mirror of
https://fuchsia.googlesource.com/third_party/pigweed.googlesource.com/pigweed/pigweed
synced 2024-08-02 06:46:04 +00:00
pw_containers: Rename VariableLengthEntryQueue
Rename VariableLengthEntryQueue to InlineVarLenEntryQueue. "Inline" is important for describing the data structure and is necessary for consistency with other Pigweed containers. Change-Id: I171885a4944bade1468e72093c99cf4aef7cb651 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/187311 Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com> Reviewed-by: Armando Montanez <amontanez@google.com> Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
17c586758a
commit
55dcce2af4
|
@ -35,9 +35,9 @@ pw::InlineQueue
|
|||
---------------
|
||||
.. doxygentypedef:: pw::InlineQueue
|
||||
|
||||
----------------------------
|
||||
pw::VariableLengthEntryQueue
|
||||
----------------------------
|
||||
--------------------------
|
||||
pw::InlineVarLenEntryQueue
|
||||
--------------------------
|
||||
.. doxygenfile:: pw_containers/inline_var_len_entry_queue.h
|
||||
:sections: detaileddescription
|
||||
|
||||
|
@ -49,14 +49,14 @@ Example
|
|||
:sync: c++
|
||||
|
||||
Queues are declared with their max size
|
||||
(``VariableLengthEntryQueue<kMaxSize>``) but may be used without
|
||||
specifying the size (``VariableLengthEntryQueue<>&``).
|
||||
(``InlineVarLenEntryQueue<kMaxSize>``) but may be used without
|
||||
specifying the size (``InlineVarLenEntryQueue<>&``).
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// Declare a queue with capacity sufficient for one 10-byte entry or
|
||||
// multiple smaller entries.
|
||||
pw::VariableLengthEntryQueue<10> queue;
|
||||
pw::InlineVarLenEntryQueue<10> queue;
|
||||
|
||||
// Push an entry, asserting if the entry does not fit.
|
||||
queue.push(queue, data)
|
||||
|
@ -68,14 +68,14 @@ Example
|
|||
// Remove an entry.
|
||||
queue.pop();
|
||||
|
||||
Alternately, a ``VariableLengthEntryQueue`` may be initialized in an
|
||||
Alternately, a ``InlineVarLenEntryQueue`` may be initialized in an
|
||||
existing ``uint32_t`` array.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// Initialize a VariableLengthEntryQueue.
|
||||
// Initialize a InlineVarLenEntryQueue.
|
||||
uint32_t buffer[32];
|
||||
auto& queue = pw::VariableLengthEntryQueue<>::Init(buffer);
|
||||
auto& queue = pw::InlineVarLenEntryQueue<>::Init(buffer);
|
||||
|
||||
// Largest supported entry is 114 B (13 B overhead + 1 B prefix)
|
||||
assert(queue.max_size_bytes() == 114u);
|
||||
|
@ -86,8 +86,8 @@ Example
|
|||
.. tab-item:: C
|
||||
:sync: c
|
||||
|
||||
A ``VariableLengthEntryQueue`` may be declared and initialized in C with
|
||||
the :c:macro:`PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE` macro.
|
||||
A ``InlineVarLenEntryQueue`` may be declared and initialized in C with the
|
||||
:c:macro:`PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE` macro.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
@ -96,39 +96,39 @@ Example
|
|||
PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(queue, 10);
|
||||
|
||||
// Push an entry, asserting if the entry does not fit.
|
||||
pw_VariableLengthEntryQueue_Push(queue, "12345", 5);
|
||||
pw_InlineVarLenEntryQueue_Push(queue, "12345", 5);
|
||||
|
||||
// Use push_overwrite() to push entries, overwriting older entries
|
||||
// as needed.
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(queue, "abcdefg", 7);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(queue, "abcdefg", 7);
|
||||
|
||||
// Remove an entry.
|
||||
pw_VariableLengthEntryQueue_Pop(queue);
|
||||
pw_InlineVarLenEntryQueue_Pop(queue);
|
||||
|
||||
Alternately, a ``VariableLengthEntryQueue`` may be initialized in an
|
||||
Alternately, a ``InlineVarLenEntryQueue`` may be initialized in an
|
||||
existing ``uint32_t`` array.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// Initialize a VariableLengthEntryQueue.
|
||||
// Initialize a InlineVarLenEntryQueue.
|
||||
uint32_t buffer[32];
|
||||
pw_VariableLengthEntryQueue_Init(buffer, 32);
|
||||
pw_InlineVarLenEntryQueue_Init(buffer, 32);
|
||||
|
||||
// Largest supported entry is 114 B (13 B overhead + 1 B prefix)
|
||||
assert(pw_VariableLengthEntryQueue_MaxSizeBytes(buffer) == 114u);
|
||||
assert(pw_InlineVarLenEntryQueue_MaxSizeBytes(buffer) == 114u);
|
||||
|
||||
// Write some data
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(buffer, "123", 3);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(buffer, "123", 3);
|
||||
|
||||
Queue vs. deque
|
||||
===============
|
||||
This module provides :cpp:type:`VariableLengthEntryQueue`, but no corresponding
|
||||
``VariableLengthEntryDeque`` class. Following the C++ Standard Library style,
|
||||
This module provides :cpp:type:`InlineVarLenEntryQueue`, but no corresponding
|
||||
``InlineVarLenEntryDeque`` class. Following the C++ Standard Library style,
|
||||
the deque class would provide ``push_front()`` and ``pop_back()`` operations in
|
||||
addition to ``push_back()`` and ``pop_front()`` (equivalent to a queue's
|
||||
``push()`` and ``pop()``).
|
||||
|
||||
There is no ``VariableLengthEntryDeque`` class because there is no efficient way
|
||||
There is no ``InlineVarLenEntryDeque`` class because there is no efficient way
|
||||
to implement ``push_front()`` and ``pop_back()``. These operations would
|
||||
necessarily be O(n), since each entry knows the position of the next entry, but
|
||||
not the previous, as in a single-linked list. Given that these operations would
|
||||
|
|
|
@ -35,7 +35,7 @@ static const uint8_t* Data(const uint32_t* queue) {
|
|||
return (const uint8_t*)&queue[3];
|
||||
}
|
||||
|
||||
static uint32_t WrapIndex(pw_VariableLengthEntryQueue_ConstHandle queue,
|
||||
static uint32_t WrapIndex(pw_InlineVarLenEntryQueue_ConstHandle queue,
|
||||
uint32_t offset) {
|
||||
if (offset >= BufferSize(queue)) {
|
||||
offset -= BufferSize(queue);
|
||||
|
@ -49,7 +49,7 @@ typedef struct {
|
|||
} EntrySize;
|
||||
|
||||
// Returns the size of an entry, including both the prefix length and data size.
|
||||
static EntrySize ReadEntrySize(pw_VariableLengthEntryQueue_ConstHandle queue,
|
||||
static EntrySize ReadEntrySize(pw_InlineVarLenEntryQueue_ConstHandle queue,
|
||||
uint32_t offset) {
|
||||
EntrySize size = {0, 0};
|
||||
|
||||
|
@ -65,7 +65,7 @@ static EntrySize ReadEntrySize(pw_VariableLengthEntryQueue_ConstHandle queue,
|
|||
return size;
|
||||
}
|
||||
|
||||
static uint32_t EncodePrefix(pw_VariableLengthEntryQueue_ConstHandle queue,
|
||||
static uint32_t EncodePrefix(pw_InlineVarLenEntryQueue_ConstHandle queue,
|
||||
uint8_t prefix[PW_VARINT_MAX_INT32_SIZE_BYTES],
|
||||
uint32_t data_size_bytes) {
|
||||
const uint32_t prefix_size = (uint32_t)pw_varint_Encode32(
|
||||
|
@ -74,25 +74,25 @@ static uint32_t EncodePrefix(pw_VariableLengthEntryQueue_ConstHandle queue,
|
|||
// Check that the ring buffer is capable of holding entries of this size.
|
||||
PW_CHECK_UINT_LE(prefix_size + data_size_bytes,
|
||||
Capacity(queue),
|
||||
"Entry is too large for this VariableLengthEntryQueue");
|
||||
"Entry is too large for this InlineVarLenEntryQueue");
|
||||
return prefix_size;
|
||||
}
|
||||
|
||||
// Returns the total encoded size of an entry.
|
||||
static uint32_t ReadEncodedEntrySize(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue, uint32_t offset) {
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue, uint32_t offset) {
|
||||
const EntrySize entry_size = ReadEntrySize(queue, offset);
|
||||
return entry_size.prefix + entry_size.data;
|
||||
}
|
||||
|
||||
static uint32_t PopNonEmpty(pw_VariableLengthEntryQueue_Handle queue) {
|
||||
static uint32_t PopNonEmpty(pw_InlineVarLenEntryQueue_Handle queue) {
|
||||
const uint32_t entry_size = ReadEncodedEntrySize(queue, HEAD(queue));
|
||||
HEAD(queue) = WrapIndex(queue, HEAD(queue) + entry_size);
|
||||
return entry_size;
|
||||
}
|
||||
|
||||
// Copies data to the buffer, wrapping around the end if needed.
|
||||
static uint32_t CopyAndWrap(pw_VariableLengthEntryQueue_Handle queue,
|
||||
static uint32_t CopyAndWrap(pw_InlineVarLenEntryQueue_Handle queue,
|
||||
uint32_t tail,
|
||||
const uint8_t* data,
|
||||
uint32_t size) {
|
||||
|
@ -111,7 +111,7 @@ static uint32_t CopyAndWrap(pw_VariableLengthEntryQueue_Handle queue,
|
|||
return WrapIndex(queue, tail + size);
|
||||
}
|
||||
|
||||
static void AppendEntryKnownToFit(pw_VariableLengthEntryQueue_Handle queue,
|
||||
static void AppendEntryKnownToFit(pw_InlineVarLenEntryQueue_Handle queue,
|
||||
const uint8_t* prefix,
|
||||
uint32_t prefix_size,
|
||||
const void* data,
|
||||
|
@ -123,7 +123,7 @@ static void AppendEntryKnownToFit(pw_VariableLengthEntryQueue_Handle queue,
|
|||
}
|
||||
|
||||
static inline uint32_t AvailableBytes(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue) {
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue) {
|
||||
uint32_t tail = TAIL(queue);
|
||||
if (tail < HEAD(queue)) {
|
||||
tail += BufferSize(queue);
|
||||
|
@ -131,9 +131,9 @@ static inline uint32_t AvailableBytes(
|
|||
return Capacity(queue) - (tail - HEAD(queue));
|
||||
}
|
||||
|
||||
void pw_VariableLengthEntryQueue_Push(pw_VariableLengthEntryQueue_Handle queue,
|
||||
const void* data,
|
||||
const uint32_t data_size_bytes) {
|
||||
void pw_InlineVarLenEntryQueue_Push(pw_InlineVarLenEntryQueue_Handle queue,
|
||||
const void* data,
|
||||
const uint32_t data_size_bytes) {
|
||||
uint8_t prefix[PW_VARINT_MAX_INT32_SIZE_BYTES];
|
||||
uint32_t prefix_size = EncodePrefix(queue, prefix, data_size_bytes);
|
||||
|
||||
|
@ -143,8 +143,8 @@ void pw_VariableLengthEntryQueue_Push(pw_VariableLengthEntryQueue_Handle queue,
|
|||
AppendEntryKnownToFit(queue, prefix, prefix_size, data, data_size_bytes);
|
||||
}
|
||||
|
||||
void pw_VariableLengthEntryQueue_PushOverwrite(
|
||||
pw_VariableLengthEntryQueue_Handle queue,
|
||||
void pw_InlineVarLenEntryQueue_PushOverwrite(
|
||||
pw_InlineVarLenEntryQueue_Handle queue,
|
||||
const void* data,
|
||||
const uint32_t data_size_bytes) {
|
||||
uint8_t prefix[PW_VARINT_MAX_INT32_SIZE_BYTES];
|
||||
|
@ -158,24 +158,24 @@ void pw_VariableLengthEntryQueue_PushOverwrite(
|
|||
AppendEntryKnownToFit(queue, prefix, prefix_size, data, data_size_bytes);
|
||||
}
|
||||
|
||||
void pw_VariableLengthEntryQueue_Pop(pw_VariableLengthEntryQueue_Handle queue) {
|
||||
PW_CHECK(!pw_VariableLengthEntryQueue_Empty(queue));
|
||||
void pw_InlineVarLenEntryQueue_Pop(pw_InlineVarLenEntryQueue_Handle queue) {
|
||||
PW_CHECK(!pw_InlineVarLenEntryQueue_Empty(queue));
|
||||
PopNonEmpty(queue);
|
||||
}
|
||||
|
||||
void pw_VariableLengthEntryQueue_Iterator_Advance(
|
||||
pw_VariableLengthEntryQueue_Iterator* iterator) {
|
||||
void pw_InlineVarLenEntryQueue_Iterator_Advance(
|
||||
pw_InlineVarLenEntryQueue_Iterator* iterator) {
|
||||
iterator->_pw_offset = WrapIndex(
|
||||
iterator->_pw_queue,
|
||||
iterator->_pw_offset +
|
||||
ReadEncodedEntrySize(iterator->_pw_queue, iterator->_pw_offset));
|
||||
}
|
||||
|
||||
pw_VariableLengthEntryQueue_Entry pw_VariableLengthEntryQueue_GetEntry(
|
||||
const pw_VariableLengthEntryQueue_Iterator* iterator) {
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue = iterator->_pw_queue;
|
||||
pw_InlineVarLenEntryQueue_Entry pw_InlineVarLenEntryQueue_GetEntry(
|
||||
const pw_InlineVarLenEntryQueue_Iterator* iterator) {
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue = iterator->_pw_queue;
|
||||
|
||||
pw_VariableLengthEntryQueue_Entry entry;
|
||||
pw_InlineVarLenEntryQueue_Entry entry;
|
||||
EntrySize size = ReadEntrySize(queue, iterator->_pw_offset);
|
||||
uint32_t offset_1 = WrapIndex(queue, iterator->_pw_offset + size.prefix);
|
||||
|
||||
|
@ -194,10 +194,8 @@ pw_VariableLengthEntryQueue_Entry pw_VariableLengthEntryQueue_GetEntry(
|
|||
return entry;
|
||||
}
|
||||
|
||||
uint32_t pw_VariableLengthEntryQueue_Entry_Copy(
|
||||
const pw_VariableLengthEntryQueue_Entry* entry,
|
||||
void* dest,
|
||||
uint32_t count) {
|
||||
uint32_t pw_InlineVarLenEntryQueue_Entry_Copy(
|
||||
const pw_InlineVarLenEntryQueue_Entry* entry, void* dest, uint32_t count) {
|
||||
PW_DCHECK(dest != NULL || count == 0u);
|
||||
|
||||
const uint32_t entry_size = entry->size_1 + entry->size_2;
|
||||
|
@ -217,14 +215,14 @@ uint32_t pw_VariableLengthEntryQueue_Entry_Copy(
|
|||
return to_copy;
|
||||
}
|
||||
|
||||
const uint8_t* _pw_VariableLengthEntryQueue_Entry_GetPointerChecked(
|
||||
const pw_VariableLengthEntryQueue_Entry* entry, size_t index) {
|
||||
const uint8_t* _pw_InlineVarLenEntryQueue_Entry_GetPointerChecked(
|
||||
const pw_InlineVarLenEntryQueue_Entry* entry, size_t index) {
|
||||
PW_CHECK_UINT_LT(index, entry->size_1 + entry->size_2);
|
||||
return _pw_VariableLengthEntryQueue_Entry_GetPointer(entry, index);
|
||||
return _pw_InlineVarLenEntryQueue_Entry_GetPointer(entry, index);
|
||||
}
|
||||
|
||||
uint32_t pw_VariableLengthEntryQueue_Size(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue) {
|
||||
uint32_t pw_InlineVarLenEntryQueue_Size(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue) {
|
||||
uint32_t entry_count = 0;
|
||||
uint32_t offset = HEAD(queue);
|
||||
|
||||
|
@ -235,8 +233,8 @@ uint32_t pw_VariableLengthEntryQueue_Size(
|
|||
return entry_count;
|
||||
}
|
||||
|
||||
uint32_t pw_VariableLengthEntryQueue_SizeBytes(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue) {
|
||||
uint32_t pw_InlineVarLenEntryQueue_SizeBytes(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue) {
|
||||
uint32_t total_entry_size_bytes = 0;
|
||||
uint32_t offset = HEAD(queue);
|
||||
|
||||
|
|
|
@ -38,60 +38,59 @@ struct SizeEquals {
|
|||
using TestStep = std::variant<PushOverwrite, Push, Pop, Clear, SizeEquals>;
|
||||
|
||||
// Copies an entry, which might be wrapped, to a single std::vector.
|
||||
std::vector<std::byte> ReadEntry(
|
||||
const pw_VariableLengthEntryQueue_Iterator& it) {
|
||||
auto entry = pw_VariableLengthEntryQueue_GetEntry(&it);
|
||||
std::vector<std::byte> ReadEntry(const pw_InlineVarLenEntryQueue_Iterator& it) {
|
||||
auto entry = pw_InlineVarLenEntryQueue_GetEntry(&it);
|
||||
std::vector<std::byte> value(entry.size_1 + entry.size_2);
|
||||
EXPECT_EQ(value.size(),
|
||||
pw_VariableLengthEntryQueue_Entry_Copy(
|
||||
pw_InlineVarLenEntryQueue_Entry_Copy(
|
||||
&entry, value.data(), entry.size_1 + entry.size_2));
|
||||
return value;
|
||||
}
|
||||
|
||||
// Declares a test that performs a series of operations on the C and C++
|
||||
// versions of VariableLengthEntryQueue and the "oracle" class, and checks that
|
||||
// versions of InlineVarLenEntryQueue and the "oracle" class, and checks that
|
||||
// they match after every step.
|
||||
#define DATA_DRIVEN_TEST(program, max_entry_size) \
|
||||
TEST(VariableLengthEntryQueue, \
|
||||
TEST(InlineVarLenEntryQueue, \
|
||||
DataDrivenTest_##program##_MaxSizeBytes##max_entry_size) { \
|
||||
pw::VariableLengthEntryQueue<max_entry_size> cpp_queue; \
|
||||
pw::InlineVarLenEntryQueue<max_entry_size> cpp_queue; \
|
||||
PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(c_queue, max_entry_size); \
|
||||
pw::containers::VariableLengthEntryQueueTestOracle oracle(max_entry_size); \
|
||||
pw::containers::InlineVarLenEntryQueueTestOracle oracle(max_entry_size); \
|
||||
\
|
||||
/* Check the queue sizes */ \
|
||||
static_assert(sizeof(cpp_queue) == sizeof(c_queue)); \
|
||||
ASSERT_EQ(cpp_queue.raw_storage().data(), \
|
||||
reinterpret_cast<const std::byte*>(&cpp_queue)); \
|
||||
ASSERT_EQ(cpp_queue.raw_storage().size_bytes(), \
|
||||
pw_VariableLengthEntryQueue_RawStorageSizeBytes(c_queue)); \
|
||||
pw_InlineVarLenEntryQueue_RawStorageSizeBytes(c_queue)); \
|
||||
\
|
||||
for (const TestStep& step : program) { \
|
||||
/* Take the action */ \
|
||||
if (auto ow = std::get_if<PushOverwrite>(&step); ow != nullptr) { \
|
||||
cpp_queue.push_overwrite(pw::as_bytes(pw::span(ow->data))); \
|
||||
pw_VariableLengthEntryQueue_PushOverwrite( \
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite( \
|
||||
c_queue, ow->data.data(), static_cast<uint32_t>(ow->data.size())); \
|
||||
oracle.push_overwrite(pw::as_bytes(pw::span(ow->data))); \
|
||||
} else if (auto push = std::get_if<Push>(&step); push != nullptr) { \
|
||||
cpp_queue.push(pw::as_bytes(pw::span(push->data))); \
|
||||
pw_VariableLengthEntryQueue_Push( \
|
||||
pw_InlineVarLenEntryQueue_Push( \
|
||||
c_queue, \
|
||||
push->data.data(), \
|
||||
static_cast<uint32_t>(push->data.size())); \
|
||||
oracle.push(pw::as_bytes(pw::span(push->data))); \
|
||||
} else if (std::holds_alternative<Pop>(step)) { \
|
||||
cpp_queue.pop(); \
|
||||
pw_VariableLengthEntryQueue_Pop(c_queue); \
|
||||
pw_InlineVarLenEntryQueue_Pop(c_queue); \
|
||||
oracle.pop(); \
|
||||
} else if (auto size = std::get_if<SizeEquals>(&step); \
|
||||
size != nullptr) { \
|
||||
const size_t actual = cpp_queue.size(); \
|
||||
ASSERT_EQ(actual, pw_VariableLengthEntryQueue_Size(c_queue)); \
|
||||
ASSERT_EQ(actual, pw_InlineVarLenEntryQueue_Size(c_queue)); \
|
||||
ASSERT_EQ(oracle.size(), actual); \
|
||||
ASSERT_EQ(size->expected, actual); \
|
||||
} else if (std::holds_alternative<Clear>(step)) { \
|
||||
cpp_queue.clear(); \
|
||||
pw_VariableLengthEntryQueue_Clear(c_queue); \
|
||||
pw_InlineVarLenEntryQueue_Clear(c_queue); \
|
||||
oracle.clear(); \
|
||||
} else { \
|
||||
FAIL() << "Unhandled case"; \
|
||||
|
@ -101,16 +100,16 @@ std::vector<std::byte> ReadEntry(
|
|||
ASSERT_EQ(cpp_queue.size_bytes(), oracle.size_bytes()); \
|
||||
ASSERT_EQ(cpp_queue.max_size_bytes(), oracle.max_size_bytes()); \
|
||||
\
|
||||
ASSERT_EQ(pw_VariableLengthEntryQueue_Size(c_queue), oracle.size()); \
|
||||
ASSERT_EQ(pw_VariableLengthEntryQueue_SizeBytes(c_queue), \
|
||||
ASSERT_EQ(pw_InlineVarLenEntryQueue_Size(c_queue), oracle.size()); \
|
||||
ASSERT_EQ(pw_InlineVarLenEntryQueue_SizeBytes(c_queue), \
|
||||
oracle.size_bytes()); \
|
||||
ASSERT_EQ(pw_VariableLengthEntryQueue_MaxSizeBytes(c_queue), \
|
||||
ASSERT_EQ(pw_InlineVarLenEntryQueue_MaxSizeBytes(c_queue), \
|
||||
oracle.max_size_bytes()); \
|
||||
\
|
||||
/* Compare the contents */ \
|
||||
auto oracle_it = oracle.begin(); \
|
||||
auto c_queue_it = pw_VariableLengthEntryQueue_Begin(c_queue); \
|
||||
const auto c_queue_end = pw_VariableLengthEntryQueue_End(c_queue); \
|
||||
auto c_queue_it = pw_InlineVarLenEntryQueue_Begin(c_queue); \
|
||||
const auto c_queue_end = pw_InlineVarLenEntryQueue_End(c_queue); \
|
||||
uint32_t entries_compared = 0; \
|
||||
\
|
||||
for (auto entry : cpp_queue) { \
|
||||
|
@ -121,15 +120,15 @@ std::vector<std::byte> ReadEntry(
|
|||
std::vector<std::byte>(entry.begin(), entry.end())); \
|
||||
\
|
||||
ASSERT_NE(oracle_it, oracle.end()); \
|
||||
ASSERT_FALSE(pw_VariableLengthEntryQueue_Iterator_Equal( \
|
||||
&c_queue_it, &c_queue_end)); \
|
||||
ASSERT_FALSE(pw_InlineVarLenEntryQueue_Iterator_Equal(&c_queue_it, \
|
||||
&c_queue_end)); \
|
||||
\
|
||||
++oracle_it; \
|
||||
pw_VariableLengthEntryQueue_Iterator_Advance(&c_queue_it); \
|
||||
pw_InlineVarLenEntryQueue_Iterator_Advance(&c_queue_it); \
|
||||
} \
|
||||
ASSERT_EQ(entries_compared, oracle.size()); \
|
||||
ASSERT_TRUE(pw_VariableLengthEntryQueue_Iterator_Equal(&c_queue_it, \
|
||||
&c_queue_end)); \
|
||||
ASSERT_TRUE(pw_InlineVarLenEntryQueue_Iterator_Equal(&c_queue_it, \
|
||||
&c_queue_end)); \
|
||||
ASSERT_EQ(oracle_it, oracle.end()); \
|
||||
} \
|
||||
} \
|
||||
|
@ -232,37 +231,37 @@ constexpr TestStep kClear[] = {
|
|||
DATA_DRIVEN_TEST(kClear, 7);
|
||||
DATA_DRIVEN_TEST(kClear, 100);
|
||||
|
||||
TEST(VariableLengthEntryQueue, DeclareMacro) {
|
||||
TEST(InlineVarLenEntryQueue, DeclareMacro) {
|
||||
PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(queue, 123);
|
||||
|
||||
constexpr size_t kArraySizeBytes =
|
||||
123 + 1 /*prefix*/ + 1 /* end */ + 3 /* round up */ +
|
||||
PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32 * 4;
|
||||
static_assert(sizeof(queue) == kArraySizeBytes);
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_RawStorageSizeBytes(queue),
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_RawStorageSizeBytes(queue),
|
||||
kArraySizeBytes - 3 /* padding isn't included */);
|
||||
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_MaxSizeBytes(queue), 123u);
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_SizeBytes(queue), 0u);
|
||||
EXPECT_TRUE(pw_VariableLengthEntryQueue_Empty(queue));
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_MaxSizeBytes(queue), 123u);
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_SizeBytes(queue), 0u);
|
||||
EXPECT_TRUE(pw_InlineVarLenEntryQueue_Empty(queue));
|
||||
}
|
||||
|
||||
TEST(VariableLengthEntryQueue, InitializeExistingBuffer) {
|
||||
TEST(InlineVarLenEntryQueue, InitializeExistingBuffer) {
|
||||
constexpr size_t kArraySize =
|
||||
10 + PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32;
|
||||
uint32_t queue[kArraySize];
|
||||
pw_VariableLengthEntryQueue_Init(queue, kArraySize);
|
||||
pw_InlineVarLenEntryQueue_Init(queue, kArraySize);
|
||||
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_RawStorageSizeBytes(queue),
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_RawStorageSizeBytes(queue),
|
||||
sizeof(queue));
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_MaxSizeBytes(queue),
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_MaxSizeBytes(queue),
|
||||
sizeof(uint32_t) * 10u - 1 /*prefix*/ - 1 /*end*/);
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_SizeBytes(queue), 0u);
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_Size(queue), 0u);
|
||||
EXPECT_TRUE(pw_VariableLengthEntryQueue_Empty(queue));
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_SizeBytes(queue), 0u);
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_Size(queue), 0u);
|
||||
EXPECT_TRUE(pw_InlineVarLenEntryQueue_Empty(queue));
|
||||
}
|
||||
|
||||
TEST(VariableLengthEntryQueue, MaxSizeElement) {
|
||||
TEST(InlineVarLenEntryQueue, MaxSizeElement) {
|
||||
// Test max size elements for a few sizes. Commented out statements fail an
|
||||
// assert because the elements are too large.
|
||||
PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(q16, 126);
|
||||
|
@ -270,36 +269,36 @@ TEST(VariableLengthEntryQueue, MaxSizeElement) {
|
|||
PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(q18, 128);
|
||||
PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(q19, 129);
|
||||
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q16, kBigEntryBytes, 126);
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q17, kBigEntryBytes, 126);
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q18, kBigEntryBytes, 126);
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q19, kBigEntryBytes, 126);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q16, kBigEntryBytes, 126);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q17, kBigEntryBytes, 126);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q18, kBigEntryBytes, 126);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q19, kBigEntryBytes, 126);
|
||||
|
||||
// pw_VariableLengthEntryQueue_PushOverwrite(q16, kBigEntryBytes, 127);
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q17, kBigEntryBytes, 127);
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q18, kBigEntryBytes, 127);
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q19, kBigEntryBytes, 127);
|
||||
// pw_InlineVarLenEntryQueue_PushOverwrite(q16, kBigEntryBytes, 127);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q17, kBigEntryBytes, 127);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q18, kBigEntryBytes, 127);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q19, kBigEntryBytes, 127);
|
||||
|
||||
// pw_VariableLengthEntryQueue_PushOverwrite(q16, kBigEntryBytes, 128);
|
||||
// pw_VariableLengthEntryQueue_PushOverwrite(q17, kBigEntryBytes, 128);
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q18, kBigEntryBytes, 128);
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q19, kBigEntryBytes, 128);
|
||||
// pw_InlineVarLenEntryQueue_PushOverwrite(q16, kBigEntryBytes, 128);
|
||||
// pw_InlineVarLenEntryQueue_PushOverwrite(q17, kBigEntryBytes, 128);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q18, kBigEntryBytes, 128);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q19, kBigEntryBytes, 128);
|
||||
|
||||
// pw_VariableLengthEntryQueue_PushOverwrite(q16, kBigEntryBytes, 129);
|
||||
// pw_VariableLengthEntryQueue_PushOverwrite(q17, kBigEntryBytes, 129);
|
||||
// pw_VariableLengthEntryQueue_PushOverwrite(q18, kBigEntryBytes, 129);
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(q19, kBigEntryBytes, 129);
|
||||
// pw_InlineVarLenEntryQueue_PushOverwrite(q16, kBigEntryBytes, 129);
|
||||
// pw_InlineVarLenEntryQueue_PushOverwrite(q17, kBigEntryBytes, 129);
|
||||
// pw_InlineVarLenEntryQueue_PushOverwrite(q18, kBigEntryBytes, 129);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(q19, kBigEntryBytes, 129);
|
||||
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_Size(q16), 1u);
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_Size(q17), 1u);
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_Size(q18), 1u);
|
||||
EXPECT_EQ(pw_VariableLengthEntryQueue_Size(q19), 1u);
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_Size(q16), 1u);
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_Size(q17), 1u);
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_Size(q18), 1u);
|
||||
EXPECT_EQ(pw_InlineVarLenEntryQueue_Size(q19), 1u);
|
||||
}
|
||||
|
||||
constexpr const char* kStrings[] = {"Haart", "Sandro", "", "Gelu", "Solmyr"};
|
||||
|
||||
TEST(VariableLengthEntryQueueClass, Iterate) {
|
||||
pw::BasicVariableLengthEntryQueue<char, 32> queue;
|
||||
TEST(InlineVarLenEntryQueueClass, Iterate) {
|
||||
pw::BasicInlineVarLenEntryQueue<char, 32> queue;
|
||||
|
||||
for (const char* string : kStrings) {
|
||||
queue.push(std::string_view(string));
|
||||
|
@ -314,8 +313,8 @@ TEST(VariableLengthEntryQueueClass, Iterate) {
|
|||
ASSERT_EQ(i, 5u);
|
||||
}
|
||||
|
||||
TEST(VariableLengthEntryQueueClass, IterateOverwrittenElements) {
|
||||
pw::BasicVariableLengthEntryQueue<char, 6> queue;
|
||||
TEST(InlineVarLenEntryQueueClass, IterateOverwrittenElements) {
|
||||
pw::BasicInlineVarLenEntryQueue<char, 6> queue;
|
||||
|
||||
for (const char* string : kStrings) {
|
||||
queue.push_overwrite(std::string_view(string));
|
||||
|
@ -330,12 +329,12 @@ TEST(VariableLengthEntryQueueClass, IterateOverwrittenElements) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(VariableLengthEntryQueueClass, InitializeExistingBuffer) {
|
||||
TEST(InlineVarLenEntryQueueClass, InitializeExistingBuffer) {
|
||||
constexpr size_t kArraySize =
|
||||
10 + PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32;
|
||||
uint32_t queue_array[kArraySize]{50, 50, 99};
|
||||
pw::VariableLengthEntryQueue<>& queue =
|
||||
pw::VariableLengthEntryQueue<>::Init(queue_array, kArraySize);
|
||||
pw::InlineVarLenEntryQueue<>& queue =
|
||||
pw::InlineVarLenEntryQueue<>::Init(queue_array, kArraySize);
|
||||
|
||||
EXPECT_EQ(queue.raw_storage().data(),
|
||||
reinterpret_cast<const std::byte*>(queue_array));
|
||||
|
@ -347,8 +346,8 @@ TEST(VariableLengthEntryQueueClass, InitializeExistingBuffer) {
|
|||
EXPECT_TRUE(queue.empty());
|
||||
}
|
||||
|
||||
TEST(VariableLengthEntryQueueClass, Entry) {
|
||||
pw::BasicVariableLengthEntryQueue<char, 5> queue;
|
||||
TEST(InlineVarLenEntryQueueClass, Entry) {
|
||||
pw::BasicInlineVarLenEntryQueue<char, 5> queue;
|
||||
queue.push("12"); // Split the next entry across the end.
|
||||
queue.push_overwrite(std::string_view("ABCDE"));
|
||||
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
|
||||
/// @file pw_containers/inline_var_len_entry_queue.h
|
||||
///
|
||||
/// A `VariableLengthEntryQueue` is a queue of inline variable-length binary
|
||||
/// A `InlineVarLenEntryQueue` is a queue of inline variable-length binary
|
||||
/// entries. It is implemented as a ring (circular) buffer and supports
|
||||
/// operations to append entries and overwrite if necessary. Entries may be zero
|
||||
/// bytes up to the maximum size supported by the queue.
|
||||
///
|
||||
/// The `VariableLengthEntryQueue` has a few interesting properties.
|
||||
/// The `InlineVarLenEntryQueue` has a few interesting properties.
|
||||
///
|
||||
/// - Data and metadata are stored inline in a contiguous block of
|
||||
/// `uint32_t`-aligned memory.
|
||||
|
@ -45,23 +45,23 @@
|
|||
/// decode the buffer from a block of memory).
|
||||
/// - C support is required.
|
||||
///
|
||||
/// `VariableLengthEntryQueue` is implemented in C and provides complete C and
|
||||
/// C++ APIs. The `VariableLengthEntryQueue` C++ class is structured similarly
|
||||
/// to `pw::InlineQueue` and `pw::Vector`.
|
||||
/// `InlineVarLenEntryQueue` is implemented in C and provides complete C and C++
|
||||
/// APIs. The `InlineVarLenEntryQueue` C++ class is structured similarly to
|
||||
/// `pw::InlineQueue` and `pw::Vector`.
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/// @defgroup inline_var_len_entry_queue_c_api VariableLengthEntryQueue C API
|
||||
/// @defgroup inline_var_len_entry_queue_c_api InlineVarLenEntryQueue C API
|
||||
/// @{
|
||||
|
||||
/// Handle that refers to a `VariableLengthEntryQueue`. In memory, the queue
|
||||
/// is a `uint32_t` array.
|
||||
typedef uint32_t* pw_VariableLengthEntryQueue_Handle;
|
||||
typedef const uint32_t* pw_VariableLengthEntryQueue_ConstHandle;
|
||||
/// Handle that refers to a `InlineVarLenEntryQueue`. In memory, the queue is a
|
||||
/// `uint32_t` array.
|
||||
typedef uint32_t* pw_InlineVarLenEntryQueue_Handle;
|
||||
typedef const uint32_t* pw_InlineVarLenEntryQueue_ConstHandle;
|
||||
|
||||
/// Declares and initializes a `VariableLengthEntryQueue` that can hold up to
|
||||
/// Declares and initializes a `InlineVarLenEntryQueue` that can hold up to
|
||||
/// `max_size_bytes` bytes. `max_size_bytes` is the largest supported size for a
|
||||
/// single entry; attempting to store larger entries is invalid and will fail an
|
||||
/// assertion.
|
||||
|
@ -73,55 +73,54 @@ typedef const uint32_t* pw_VariableLengthEntryQueue_ConstHandle;
|
|||
_PW_VAR_QUEUE_DATA_SIZE_UINT32(max_size_bytes)] = { \
|
||||
_PW_VAR_QUEUE_DATA_SIZE_BYTES(max_size_bytes), /*head=*/0u, /*tail=*/0u}
|
||||
|
||||
/// The size of the `VariableLengthEntryQueue` header, in `uint32_t` elements.
|
||||
/// The size of the `InlineVarLenEntryQueue` header, in `uint32_t` elements.
|
||||
/// This header stores the buffer length and head and tail offsets.
|
||||
///
|
||||
/// The underlying `uint32_t` array of a `VariableLengthEntryQueue` must be
|
||||
/// larger than this size.
|
||||
/// The underlying `uint32_t` array of a `InlineVarLenEntryQueue` must be larger
|
||||
/// than this size.
|
||||
#define PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32 (3)
|
||||
|
||||
/// Initializes a `VariableLengthEntryQueue` in place in a `uint32_t` array. The
|
||||
/// Initializes a `InlineVarLenEntryQueue` in place in a `uint32_t` array. The
|
||||
/// array MUST be larger than
|
||||
/// @c_macro{PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32} (3) elements.
|
||||
static inline void pw_VariableLengthEntryQueue_Init(uint32_t array[],
|
||||
size_t array_size_uint32);
|
||||
static inline void pw_InlineVarLenEntryQueue_Init(uint32_t array[],
|
||||
size_t array_size_uint32);
|
||||
|
||||
/// Empties the queue.
|
||||
static inline void pw_VariableLengthEntryQueue_Clear(
|
||||
pw_VariableLengthEntryQueue_Handle queue);
|
||||
static inline void pw_InlineVarLenEntryQueue_Clear(
|
||||
pw_InlineVarLenEntryQueue_Handle queue);
|
||||
|
||||
/// Appends an entry to the end of the queue.
|
||||
///
|
||||
/// @pre The entry MUST NOT be larger than `max_size_bytes()`.
|
||||
void pw_VariableLengthEntryQueue_Push(pw_VariableLengthEntryQueue_Handle queue,
|
||||
const void* data,
|
||||
uint32_t data_size_bytes);
|
||||
void pw_InlineVarLenEntryQueue_Push(pw_InlineVarLenEntryQueue_Handle queue,
|
||||
const void* data,
|
||||
uint32_t data_size_bytes);
|
||||
|
||||
/// Appends an entry to the end of the queue, removing entries with `Pop`
|
||||
/// as necessary to make room.
|
||||
///
|
||||
/// @pre The entry MUST NOT be larger than `max_size_bytes()`.
|
||||
void pw_VariableLengthEntryQueue_PushOverwrite(
|
||||
pw_VariableLengthEntryQueue_Handle queue,
|
||||
void pw_InlineVarLenEntryQueue_PushOverwrite(
|
||||
pw_InlineVarLenEntryQueue_Handle queue,
|
||||
const void* data,
|
||||
uint32_t data_size_bytes);
|
||||
|
||||
/// Removes the first entry from queue.
|
||||
///
|
||||
/// @pre The queue MUST have at least one entry.
|
||||
void pw_VariableLengthEntryQueue_Pop(pw_VariableLengthEntryQueue_Handle queue);
|
||||
void pw_InlineVarLenEntryQueue_Pop(pw_InlineVarLenEntryQueue_Handle queue);
|
||||
|
||||
/// Iterator object for a `VariableLengthEntryQueue`. Iterators are checked for
|
||||
/// equality with
|
||||
/// @cpp_func{pw_VariableLengthEntryQueue_Iterator_Equal}.
|
||||
/// Iterator object for a `InlineVarLenEntryQueue`. Iterators are checked for
|
||||
/// equality with @cpp_func{pw_InlineVarLenEntryQueue_Iterator_Equal}.
|
||||
///
|
||||
/// Iterators are invalidated by any operations that change the container or
|
||||
/// its underlying data (push/pop/init).
|
||||
typedef struct {
|
||||
// Private: do not access these fields directly!
|
||||
pw_VariableLengthEntryQueue_ConstHandle _pw_queue;
|
||||
pw_InlineVarLenEntryQueue_ConstHandle _pw_queue;
|
||||
uint32_t _pw_offset;
|
||||
} pw_VariableLengthEntryQueue_Iterator;
|
||||
} pw_InlineVarLenEntryQueue_Iterator;
|
||||
|
||||
/// An entry in the queue. Entries may be stored in up to two segments, so this
|
||||
/// struct includes pointers to both portions of the entry.
|
||||
|
@ -130,30 +129,29 @@ typedef struct {
|
|||
uint32_t size_1;
|
||||
const uint8_t* data_2;
|
||||
uint32_t size_2;
|
||||
} pw_VariableLengthEntryQueue_Entry;
|
||||
} pw_InlineVarLenEntryQueue_Entry;
|
||||
|
||||
/// Returns an iterator to the start of the `VariableLengthEntryQueue`.
|
||||
static inline pw_VariableLengthEntryQueue_Iterator
|
||||
pw_VariableLengthEntryQueue_Begin(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue);
|
||||
/// Returns an iterator to the start of the `InlineVarLenEntryQueue`.
|
||||
static inline pw_InlineVarLenEntryQueue_Iterator
|
||||
pw_InlineVarLenEntryQueue_Begin(pw_InlineVarLenEntryQueue_ConstHandle queue);
|
||||
|
||||
/// Returns an iterator that points past the end of the queue.
|
||||
static inline pw_VariableLengthEntryQueue_Iterator
|
||||
pw_VariableLengthEntryQueue_End(pw_VariableLengthEntryQueue_ConstHandle queue);
|
||||
static inline pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_End(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue);
|
||||
|
||||
/// Advances an iterator to point to the next entry in the queue. It is
|
||||
/// invalid to call `Advance` on an iterator equal to the `End` iterator.
|
||||
void pw_VariableLengthEntryQueue_Iterator_Advance(
|
||||
pw_VariableLengthEntryQueue_Iterator* iterator);
|
||||
void pw_InlineVarLenEntryQueue_Iterator_Advance(
|
||||
pw_InlineVarLenEntryQueue_Iterator* iterator);
|
||||
|
||||
/// Compares two iterators for equality.
|
||||
static inline bool pw_VariableLengthEntryQueue_Iterator_Equal(
|
||||
const pw_VariableLengthEntryQueue_Iterator* lhs,
|
||||
const pw_VariableLengthEntryQueue_Iterator* rhs);
|
||||
static inline bool pw_InlineVarLenEntryQueue_Iterator_Equal(
|
||||
const pw_InlineVarLenEntryQueue_Iterator* lhs,
|
||||
const pw_InlineVarLenEntryQueue_Iterator* rhs);
|
||||
|
||||
/// Dereferences an iterator, loading the entry it points to.
|
||||
pw_VariableLengthEntryQueue_Entry pw_VariableLengthEntryQueue_GetEntry(
|
||||
const pw_VariableLengthEntryQueue_Iterator* iterator);
|
||||
pw_InlineVarLenEntryQueue_Entry pw_InlineVarLenEntryQueue_GetEntry(
|
||||
const pw_InlineVarLenEntryQueue_Iterator* iterator);
|
||||
|
||||
/// Copies the contents of the entry to the provided buffer. The entry may be
|
||||
/// split into two regions; this serializes it into one buffer.
|
||||
|
@ -162,41 +160,41 @@ pw_VariableLengthEntryQueue_Entry pw_VariableLengthEntryQueue_GetEntry(
|
|||
/// @param dest The buffer into which to copy the serialized entry
|
||||
/// @param count Copy up to this many bytes; must not be larger than the `dest`
|
||||
/// buffer, but may be larger than the entry
|
||||
uint32_t pw_VariableLengthEntryQueue_Entry_Copy(
|
||||
const pw_VariableLengthEntryQueue_Entry* entry, void* dest, uint32_t count);
|
||||
uint32_t pw_InlineVarLenEntryQueue_Entry_Copy(
|
||||
const pw_InlineVarLenEntryQueue_Entry* entry, void* dest, uint32_t count);
|
||||
|
||||
/// Returns the byte at the specified index in the entry. Asserts if index is
|
||||
/// out-of-bounds.
|
||||
static inline uint8_t pw_VariableLengthEntryQueue_Entry_At(
|
||||
const pw_VariableLengthEntryQueue_Entry* entry, size_t index);
|
||||
static inline uint8_t pw_InlineVarLenEntryQueue_Entry_At(
|
||||
const pw_InlineVarLenEntryQueue_Entry* entry, size_t index);
|
||||
|
||||
/// Returns the number of variable-length entries in the queue. This is O(n) in
|
||||
/// the number of entries in the queue.
|
||||
uint32_t pw_VariableLengthEntryQueue_Size(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue);
|
||||
uint32_t pw_InlineVarLenEntryQueue_Size(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue);
|
||||
|
||||
/// Returns the combined size in bytes of all entries in the queue, excluding
|
||||
/// metadata. This is O(n) in the number of entries in the queue.
|
||||
uint32_t pw_VariableLengthEntryQueue_SizeBytes(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue);
|
||||
uint32_t pw_InlineVarLenEntryQueue_SizeBytes(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue);
|
||||
|
||||
/// Returns the the maximum number of bytes that can be stored in the queue.
|
||||
/// This is largest possible value of `size_bytes()`, and the size of the
|
||||
/// largest single entry that can be stored in this queue. Attempting to store a
|
||||
/// larger entry is invalid and results in a crash.
|
||||
static inline uint32_t pw_VariableLengthEntryQueue_MaxSizeBytes(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue);
|
||||
static inline uint32_t pw_InlineVarLenEntryQueue_MaxSizeBytes(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue);
|
||||
|
||||
/// Returns the size of the raw underlying `VariableLengthEntryQueue` storage.
|
||||
/// This size may be used to copy a `VariableLengthEntryQueue` into another
|
||||
/// Returns the size of the raw underlying `InlineVarLenEntryQueue` storage.
|
||||
/// This size may be used to copy a `InlineVarLenEntryQueue` into another
|
||||
/// 32-bit aligned memory location.
|
||||
static inline uint32_t pw_VariableLengthEntryQueue_RawStorageSizeBytes(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue);
|
||||
static inline uint32_t pw_InlineVarLenEntryQueue_RawStorageSizeBytes(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue);
|
||||
|
||||
/// Returns true if the `VariableLengthEntryQueue` is empty, false if it has at
|
||||
/// Returns true if the `InlineVarLenEntryQueue` is empty, false if it has at
|
||||
/// least one entry.
|
||||
static inline bool pw_VariableLengthEntryQueue_Empty(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue);
|
||||
static inline bool pw_InlineVarLenEntryQueue_Empty(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue);
|
||||
|
||||
/// @}
|
||||
|
||||
|
@ -219,70 +217,69 @@ static inline bool pw_VariableLengthEntryQueue_Empty(
|
|||
PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32) * \
|
||||
sizeof(uint32_t)
|
||||
|
||||
static inline void pw_VariableLengthEntryQueue_Init(uint32_t array[],
|
||||
size_t array_size_uint32) {
|
||||
static inline void pw_InlineVarLenEntryQueue_Init(uint32_t array[],
|
||||
size_t array_size_uint32) {
|
||||
array[0] = _PW_VAR_QUEUE_GET_ARRAY_SIZE_BYTES(array_size_uint32);
|
||||
array[1] = 0; // head
|
||||
array[2] = 0; // tail
|
||||
}
|
||||
|
||||
static inline void pw_VariableLengthEntryQueue_Clear(
|
||||
pw_VariableLengthEntryQueue_Handle queue) {
|
||||
static inline void pw_InlineVarLenEntryQueue_Clear(
|
||||
pw_InlineVarLenEntryQueue_Handle queue) {
|
||||
_PW_VAR_QUEUE_HEAD = 0; // head
|
||||
_PW_VAR_QUEUE_TAIL = 0; // tail
|
||||
}
|
||||
|
||||
static inline pw_VariableLengthEntryQueue_Iterator
|
||||
pw_VariableLengthEntryQueue_Begin(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue) {
|
||||
pw_VariableLengthEntryQueue_Iterator begin = {queue, _PW_VAR_QUEUE_HEAD};
|
||||
static inline pw_InlineVarLenEntryQueue_Iterator
|
||||
pw_InlineVarLenEntryQueue_Begin(pw_InlineVarLenEntryQueue_ConstHandle queue) {
|
||||
pw_InlineVarLenEntryQueue_Iterator begin = {queue, _PW_VAR_QUEUE_HEAD};
|
||||
return begin;
|
||||
}
|
||||
|
||||
static inline pw_VariableLengthEntryQueue_Iterator
|
||||
pw_VariableLengthEntryQueue_End(pw_VariableLengthEntryQueue_ConstHandle queue) {
|
||||
pw_VariableLengthEntryQueue_Iterator end = {queue, _PW_VAR_QUEUE_TAIL};
|
||||
static inline pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_End(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue) {
|
||||
pw_InlineVarLenEntryQueue_Iterator end = {queue, _PW_VAR_QUEUE_TAIL};
|
||||
return end;
|
||||
}
|
||||
|
||||
static inline bool pw_VariableLengthEntryQueue_Iterator_Equal(
|
||||
const pw_VariableLengthEntryQueue_Iterator* lhs,
|
||||
const pw_VariableLengthEntryQueue_Iterator* rhs) {
|
||||
static inline bool pw_InlineVarLenEntryQueue_Iterator_Equal(
|
||||
const pw_InlineVarLenEntryQueue_Iterator* lhs,
|
||||
const pw_InlineVarLenEntryQueue_Iterator* rhs) {
|
||||
return lhs->_pw_offset == rhs->_pw_offset && lhs->_pw_queue == rhs->_pw_queue;
|
||||
}
|
||||
|
||||
// Private function that returns a pointer to the specified index in the Entry.
|
||||
static inline const uint8_t* _pw_VariableLengthEntryQueue_Entry_GetPointer(
|
||||
const pw_VariableLengthEntryQueue_Entry* entry, size_t index) {
|
||||
static inline const uint8_t* _pw_InlineVarLenEntryQueue_Entry_GetPointer(
|
||||
const pw_InlineVarLenEntryQueue_Entry* entry, size_t index) {
|
||||
if (index < entry->size_1) {
|
||||
return &entry->data_1[index];
|
||||
}
|
||||
return &entry->data_2[index - entry->size_1];
|
||||
}
|
||||
|
||||
const uint8_t* _pw_VariableLengthEntryQueue_Entry_GetPointerChecked(
|
||||
const pw_VariableLengthEntryQueue_Entry* entry, size_t index);
|
||||
const uint8_t* _pw_InlineVarLenEntryQueue_Entry_GetPointerChecked(
|
||||
const pw_InlineVarLenEntryQueue_Entry* entry, size_t index);
|
||||
|
||||
static inline uint8_t pw_VariableLengthEntryQueue_Entry_At(
|
||||
const pw_VariableLengthEntryQueue_Entry* entry, size_t index) {
|
||||
return *_pw_VariableLengthEntryQueue_Entry_GetPointerChecked(entry, index);
|
||||
static inline uint8_t pw_InlineVarLenEntryQueue_Entry_At(
|
||||
const pw_InlineVarLenEntryQueue_Entry* entry, size_t index) {
|
||||
return *_pw_InlineVarLenEntryQueue_Entry_GetPointerChecked(entry, index);
|
||||
}
|
||||
|
||||
static inline uint32_t pw_VariableLengthEntryQueue_RawStorageSizeBytes(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue) {
|
||||
static inline uint32_t pw_InlineVarLenEntryQueue_RawStorageSizeBytes(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue) {
|
||||
return PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32 * sizeof(uint32_t) +
|
||||
_PW_VAR_QUEUE_ARRAY_SIZE_BYTES;
|
||||
}
|
||||
|
||||
static inline uint32_t pw_VariableLengthEntryQueue_MaxSizeBytes(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue) {
|
||||
static inline uint32_t pw_InlineVarLenEntryQueue_MaxSizeBytes(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue) {
|
||||
return _PW_VAR_QUEUE_ARRAY_SIZE_BYTES - 1 -
|
||||
(uint32_t)pw_varint_EncodedSizeBytes(_PW_VAR_QUEUE_ARRAY_SIZE_BYTES -
|
||||
1);
|
||||
}
|
||||
|
||||
static inline bool pw_VariableLengthEntryQueue_Empty(
|
||||
pw_VariableLengthEntryQueue_ConstHandle queue) {
|
||||
static inline bool pw_InlineVarLenEntryQueue_Empty(
|
||||
pw_InlineVarLenEntryQueue_ConstHandle queue) {
|
||||
return _PW_VAR_QUEUE_HEAD == _PW_VAR_QUEUE_TAIL;
|
||||
}
|
||||
|
||||
|
@ -305,26 +302,26 @@ static inline bool pw_VariableLengthEntryQueue_Empty(
|
|||
|
||||
namespace pw {
|
||||
|
||||
// A`BasicVariableLengthEntryQueue` with a known maximum size of a single entry.
|
||||
// A`BasicInlineVarLenEntryQueue` with a known maximum size of a single entry.
|
||||
// The member functions are immplemented in the generic-capacity base.
|
||||
// TODO: b/303056683 - Add helper for calculating kMaxSizeBytes for N entries of
|
||||
// a particular size.
|
||||
template <typename T,
|
||||
size_t kMaxSizeBytes = containers::internal::kGenericSized>
|
||||
class BasicVariableLengthEntryQueue : public BasicVariableLengthEntryQueue<
|
||||
T,
|
||||
containers::internal::kGenericSized> {
|
||||
class BasicInlineVarLenEntryQueue
|
||||
: public BasicInlineVarLenEntryQueue<T,
|
||||
containers::internal::kGenericSized> {
|
||||
private:
|
||||
using Base =
|
||||
BasicVariableLengthEntryQueue<T, containers::internal::kGenericSized>;
|
||||
BasicInlineVarLenEntryQueue<T, containers::internal::kGenericSized>;
|
||||
|
||||
public:
|
||||
constexpr BasicVariableLengthEntryQueue() : Base(kMaxSizeBytes) {}
|
||||
constexpr BasicInlineVarLenEntryQueue() : Base(kMaxSizeBytes) {}
|
||||
|
||||
// `BasicVariableLengthEntryQueue` is trivially copyable.
|
||||
BasicVariableLengthEntryQueue(const BasicVariableLengthEntryQueue&) = default;
|
||||
BasicVariableLengthEntryQueue& operator=(
|
||||
const BasicVariableLengthEntryQueue&) = default;
|
||||
// `BasicInlineVarLenEntryQueue` is trivially copyable.
|
||||
BasicInlineVarLenEntryQueue(const BasicInlineVarLenEntryQueue&) = default;
|
||||
BasicInlineVarLenEntryQueue& operator=(const BasicInlineVarLenEntryQueue&) =
|
||||
default;
|
||||
|
||||
private:
|
||||
static_assert(kMaxSizeBytes <=
|
||||
|
@ -341,12 +338,12 @@ class BasicVariableLengthEntryQueue : public BasicVariableLengthEntryQueue<
|
|||
/// Variable-length entry queue class template for any byte type (e.g.
|
||||
/// ``std::byte`` or ``uint8_t``).
|
||||
///
|
||||
/// ``BasicVariableLengthEntryQueue`` instances are declared with their capacity
|
||||
/// / max single entry size (``BasicVariableLengthEntryQueue<char, 64>``), but
|
||||
/// ``BasicInlineVarLenEntryQueue`` instances are declared with their capacity
|
||||
/// / max single entry size (``BasicInlineVarLenEntryQueue<char, 64>``), but
|
||||
/// may be referred to without the size
|
||||
/// (``BasicVariableLengthEntryQueue<char>&``).
|
||||
/// (``BasicInlineVarLenEntryQueue<char>&``).
|
||||
template <typename T>
|
||||
class BasicVariableLengthEntryQueue<T, containers::internal::kGenericSized> {
|
||||
class BasicInlineVarLenEntryQueue<T, containers::internal::kGenericSized> {
|
||||
public:
|
||||
class Entry;
|
||||
|
||||
|
@ -364,90 +361,88 @@ class BasicVariableLengthEntryQueue<T, containers::internal::kGenericSized> {
|
|||
// TODO: b/303046109 - Provide a non-const iterator.
|
||||
using const_iterator = iterator;
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_Init
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_Init
|
||||
template <size_t kArraySize>
|
||||
static BasicVariableLengthEntryQueue& Init(uint32_t (&array)[kArraySize]) {
|
||||
static BasicInlineVarLenEntryQueue& Init(uint32_t (&array)[kArraySize]) {
|
||||
static_assert(
|
||||
kArraySize > PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32,
|
||||
"VariableLengthEntryQueue must be backed by an array with more than "
|
||||
"InlineVarLenEntryQueue must be backed by an array with more than "
|
||||
"PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32 (3) elements");
|
||||
return Init(array, kArraySize);
|
||||
}
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_Init
|
||||
static BasicVariableLengthEntryQueue& Init(uint32_t array[],
|
||||
size_t array_size_uint32) {
|
||||
pw_VariableLengthEntryQueue_Init(array, array_size_uint32);
|
||||
return *std::launder(
|
||||
reinterpret_cast<BasicVariableLengthEntryQueue*>(array));
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_Init
|
||||
static BasicInlineVarLenEntryQueue& Init(uint32_t array[],
|
||||
size_t array_size_uint32) {
|
||||
pw_InlineVarLenEntryQueue_Init(array, array_size_uint32);
|
||||
return *std::launder(reinterpret_cast<BasicInlineVarLenEntryQueue*>(array));
|
||||
}
|
||||
|
||||
/// Returns the first entry in the queue.
|
||||
Entry front() const { return *begin(); }
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_Begin
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_Begin
|
||||
const_iterator begin() const {
|
||||
return const_iterator(pw_VariableLengthEntryQueue_Begin(array_));
|
||||
return const_iterator(pw_InlineVarLenEntryQueue_Begin(array_));
|
||||
}
|
||||
const_iterator cbegin() const { return begin(); }
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_End
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_End
|
||||
const_iterator end() const {
|
||||
return const_iterator(pw_VariableLengthEntryQueue_End(array_));
|
||||
return const_iterator(pw_InlineVarLenEntryQueue_End(array_));
|
||||
}
|
||||
const_iterator cend() const { return end(); }
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_Empty
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_Empty
|
||||
[[nodiscard]] bool empty() const {
|
||||
return pw_VariableLengthEntryQueue_Empty(array_);
|
||||
return pw_InlineVarLenEntryQueue_Empty(array_);
|
||||
}
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_Size
|
||||
size_type size() const { return pw_VariableLengthEntryQueue_Size(array_); }
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_Size
|
||||
size_type size() const { return pw_InlineVarLenEntryQueue_Size(array_); }
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_SizeBytes
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_SizeBytes
|
||||
size_type size_bytes() const {
|
||||
return pw_VariableLengthEntryQueue_SizeBytes(array_);
|
||||
return pw_InlineVarLenEntryQueue_SizeBytes(array_);
|
||||
}
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_MaxSizeBytes
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_MaxSizeBytes
|
||||
size_type max_size_bytes() const {
|
||||
return pw_VariableLengthEntryQueue_MaxSizeBytes(array_);
|
||||
return pw_InlineVarLenEntryQueue_MaxSizeBytes(array_);
|
||||
}
|
||||
|
||||
/// Underlying storage of the variable-length entry queue. May be used to
|
||||
/// memcpy the queue.
|
||||
span<const T> raw_storage() const {
|
||||
return span<const T>(
|
||||
reinterpret_cast<const T*>(array_),
|
||||
pw_VariableLengthEntryQueue_RawStorageSizeBytes(array_));
|
||||
return span<const T>(reinterpret_cast<const T*>(array_),
|
||||
pw_InlineVarLenEntryQueue_RawStorageSizeBytes(array_));
|
||||
}
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_Clear
|
||||
void clear() { pw_VariableLengthEntryQueue_Clear(array_); }
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_Clear
|
||||
void clear() { pw_InlineVarLenEntryQueue_Clear(array_); }
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_Push
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_Push
|
||||
void push(span<const T> value) {
|
||||
pw_VariableLengthEntryQueue_Push(
|
||||
pw_InlineVarLenEntryQueue_Push(
|
||||
array_, value.data(), static_cast<size_type>(value.size()));
|
||||
}
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_PushOverwrite
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_PushOverwrite
|
||||
void push_overwrite(span<const T> value) {
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(
|
||||
array_, value.data(), static_cast<size_type>(value.size()));
|
||||
}
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_Pop
|
||||
void pop() { pw_VariableLengthEntryQueue_Pop(array_); }
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_Pop
|
||||
void pop() { pw_InlineVarLenEntryQueue_Pop(array_); }
|
||||
|
||||
protected:
|
||||
constexpr BasicVariableLengthEntryQueue(uint32_t max_size_bytes)
|
||||
constexpr BasicInlineVarLenEntryQueue(uint32_t max_size_bytes)
|
||||
: array_{_PW_VAR_QUEUE_DATA_SIZE_BYTES(max_size_bytes), 0, 0} {}
|
||||
|
||||
BasicVariableLengthEntryQueue(const BasicVariableLengthEntryQueue&) = default;
|
||||
BasicVariableLengthEntryQueue& operator=(
|
||||
const BasicVariableLengthEntryQueue&) = default;
|
||||
BasicInlineVarLenEntryQueue(const BasicInlineVarLenEntryQueue&) = default;
|
||||
BasicInlineVarLenEntryQueue& operator=(const BasicInlineVarLenEntryQueue&) =
|
||||
default;
|
||||
|
||||
private:
|
||||
static_assert(std::is_integral_v<T> || std::is_same_v<T, std::byte>);
|
||||
|
@ -458,7 +453,7 @@ class BasicVariableLengthEntryQueue<T, containers::internal::kGenericSized> {
|
|||
|
||||
/// Refers to an entry in-place in the queue. Entries may be discontiguous.
|
||||
template <typename T>
|
||||
class BasicVariableLengthEntryQueue<T>::Entry {
|
||||
class BasicInlineVarLenEntryQueue<T>::Entry {
|
||||
public:
|
||||
using value_type = T;
|
||||
using size_type = std::uint32_t;
|
||||
|
@ -503,11 +498,11 @@ class BasicVariableLengthEntryQueue<T>::Entry {
|
|||
private:
|
||||
friend class Entry;
|
||||
|
||||
constexpr iterator(const pw_VariableLengthEntryQueue_Entry& entry,
|
||||
constexpr iterator(const pw_InlineVarLenEntryQueue_Entry& entry,
|
||||
size_t index)
|
||||
: entry_(&entry), index_(index) {}
|
||||
|
||||
const pw_VariableLengthEntryQueue_Entry* entry_;
|
||||
const pw_InlineVarLenEntryQueue_Entry* entry_;
|
||||
size_t index_;
|
||||
};
|
||||
|
||||
|
@ -519,7 +514,7 @@ class BasicVariableLengthEntryQueue<T>::Entry {
|
|||
|
||||
const_reference at(size_t index) const {
|
||||
return *reinterpret_cast<const T*>(
|
||||
_pw_VariableLengthEntryQueue_Entry_GetPointerChecked(&entry_, index));
|
||||
_pw_InlineVarLenEntryQueue_Entry_GetPointerChecked(&entry_, index));
|
||||
}
|
||||
|
||||
const_reference operator[](size_t index) const {
|
||||
|
@ -539,13 +534,13 @@ class BasicVariableLengthEntryQueue<T>::Entry {
|
|||
span(reinterpret_cast<const_pointer>(entry_.data_2), entry_.size_2));
|
||||
}
|
||||
|
||||
/// @copydoc pw_VariableLengthEntryQueue_Entry_Copy
|
||||
/// @copydoc pw_InlineVarLenEntryQueue_Entry_Copy
|
||||
///
|
||||
/// Copying with `copy()` is likely more efficient than an iterator-based copy
|
||||
/// with `std::copy()`, since `copy()` uses one or two `memcpy` calls instead
|
||||
/// of copying byte-by-byte.
|
||||
size_type copy(T* dest, size_type count) const {
|
||||
return pw_VariableLengthEntryQueue_Entry_Copy(&entry_, dest, count);
|
||||
return pw_InlineVarLenEntryQueue_Entry_Copy(&entry_, dest, count);
|
||||
}
|
||||
|
||||
const_iterator begin() const { return const_iterator(entry_, 0); }
|
||||
|
@ -559,28 +554,28 @@ class BasicVariableLengthEntryQueue<T>::Entry {
|
|||
size_type size() const { return entry_.size_1 + entry_.size_2; }
|
||||
|
||||
private:
|
||||
friend class BasicVariableLengthEntryQueue;
|
||||
friend class BasicInlineVarLenEntryQueue;
|
||||
|
||||
static const T* GetIndex(const pw_VariableLengthEntryQueue_Entry& entry,
|
||||
static const T* GetIndex(const pw_InlineVarLenEntryQueue_Entry& entry,
|
||||
size_t index) {
|
||||
return reinterpret_cast<const T*>(
|
||||
_pw_VariableLengthEntryQueue_Entry_GetPointer(&entry, index));
|
||||
_pw_InlineVarLenEntryQueue_Entry_GetPointer(&entry, index));
|
||||
}
|
||||
|
||||
explicit constexpr Entry(const pw_VariableLengthEntryQueue_Entry& entry)
|
||||
explicit constexpr Entry(const pw_InlineVarLenEntryQueue_Entry& entry)
|
||||
: entry_(entry) {}
|
||||
|
||||
constexpr Entry() : entry_{} {}
|
||||
|
||||
pw_VariableLengthEntryQueue_Entry entry_;
|
||||
pw_InlineVarLenEntryQueue_Entry entry_;
|
||||
};
|
||||
|
||||
/// Iterator object for a `VariableLengthEntryQueue`.
|
||||
/// Iterator object for a `InlineVarLenEntryQueue`.
|
||||
///
|
||||
/// Iterators are invalidated by any operations that change the container or
|
||||
/// its underlying data (push/pop/init).
|
||||
template <typename T>
|
||||
class BasicVariableLengthEntryQueue<T>::iterator {
|
||||
class BasicInlineVarLenEntryQueue<T>::iterator {
|
||||
public:
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = Entry;
|
||||
|
@ -594,7 +589,7 @@ class BasicVariableLengthEntryQueue<T>::iterator {
|
|||
constexpr iterator& operator=(const iterator&) = default;
|
||||
|
||||
iterator& operator++() {
|
||||
pw_VariableLengthEntryQueue_Iterator_Advance(&iterator_);
|
||||
pw_InlineVarLenEntryQueue_Iterator_Advance(&iterator_);
|
||||
entry_.entry_.data_1 = nullptr; // mark the entry as unloaded
|
||||
return *this;
|
||||
}
|
||||
|
@ -614,31 +609,30 @@ class BasicVariableLengthEntryQueue<T>::iterator {
|
|||
}
|
||||
|
||||
bool operator==(const iterator& rhs) const {
|
||||
return pw_VariableLengthEntryQueue_Iterator_Equal(&iterator_,
|
||||
&rhs.iterator_);
|
||||
return pw_InlineVarLenEntryQueue_Iterator_Equal(&iterator_, &rhs.iterator_);
|
||||
}
|
||||
bool operator!=(const iterator& rhs) const { return !(*this == rhs); }
|
||||
|
||||
private:
|
||||
friend class BasicVariableLengthEntryQueue;
|
||||
friend class BasicInlineVarLenEntryQueue;
|
||||
|
||||
explicit constexpr iterator(const pw_VariableLengthEntryQueue_Iterator& it)
|
||||
explicit constexpr iterator(const pw_InlineVarLenEntryQueue_Iterator& it)
|
||||
: iterator_(it) {}
|
||||
|
||||
void LoadEntry() const {
|
||||
if (entry_.entry_.data_1 == nullptr) {
|
||||
entry_.entry_ = pw_VariableLengthEntryQueue_GetEntry(&iterator_);
|
||||
entry_.entry_ = pw_InlineVarLenEntryQueue_GetEntry(&iterator_);
|
||||
}
|
||||
}
|
||||
|
||||
pw_VariableLengthEntryQueue_Iterator iterator_;
|
||||
pw_InlineVarLenEntryQueue_Iterator iterator_;
|
||||
mutable Entry entry_;
|
||||
};
|
||||
|
||||
/// Variable-length entry queue that uses ``std::byte`` for the byte type.
|
||||
template <size_t kMaxSizeBytes = containers::internal::kGenericSized>
|
||||
using VariableLengthEntryQueue =
|
||||
BasicVariableLengthEntryQueue<std::byte, kMaxSizeBytes>;
|
||||
using InlineVarLenEntryQueue =
|
||||
BasicInlineVarLenEntryQueue<std::byte, kMaxSizeBytes>;
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
|
||||
namespace pw::containers {
|
||||
|
||||
// Behaves like a VariableLengthEntryQueue should, but with a std::deque-based
|
||||
// Behaves like a InlineVarLenEntryQueue should, but with a std::deque-based
|
||||
// implementation.
|
||||
class VariableLengthEntryQueueTestOracle {
|
||||
class InlineVarLenEntryQueueTestOracle {
|
||||
public:
|
||||
VariableLengthEntryQueueTestOracle(uint32_t max_size_bytes)
|
||||
InlineVarLenEntryQueueTestOracle(uint32_t max_size_bytes)
|
||||
: max_size_bytes_(max_size_bytes),
|
||||
raw_size_bytes_(0),
|
||||
raw_capacity_bytes_(
|
||||
|
|
|
@ -65,7 +65,7 @@ static void TokenizeIntegersOnly(uint32_t token, int arg_count, ...) {
|
|||
}
|
||||
|
||||
// Write the encoded log to the ring buffer
|
||||
pw_VariableLengthEntryQueue_PushOverwrite(buffer, encoded, index);
|
||||
pw_InlineVarLenEntryQueue_PushOverwrite(buffer, encoded, index);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
@ -99,35 +99,35 @@ const char* RunTestAndReturnPassed(void) {
|
|||
TOKENIZE_INTS("One arg, 5 bytes: %ld", (long)INT32_MAX);
|
||||
TOKENIZE_INTS("Three args, 4 bytes: %d %d %d", 1, 63, 128);
|
||||
|
||||
ASSERT_EQ(pw_VariableLengthEntryQueue_Size(buffer), 4u);
|
||||
ASSERT_EQ(pw_InlineVarLenEntryQueue_Size(buffer), 4u);
|
||||
|
||||
pw_VariableLengthEntryQueue_Iterator it =
|
||||
pw_VariableLengthEntryQueue_Begin(buffer);
|
||||
pw_VariableLengthEntryQueue_Entry entry =
|
||||
pw_VariableLengthEntryQueue_GetEntry(&it);
|
||||
pw_InlineVarLenEntryQueue_Iterator it =
|
||||
pw_InlineVarLenEntryQueue_Begin(buffer);
|
||||
pw_InlineVarLenEntryQueue_Entry entry =
|
||||
pw_InlineVarLenEntryQueue_GetEntry(&it);
|
||||
|
||||
ASSERT_EQ(entry.size_1, sizeof(uint32_t) + 0);
|
||||
ASSERT_EQ(entry.size_2, 0u);
|
||||
|
||||
pw_VariableLengthEntryQueue_Iterator_Advance(&it);
|
||||
entry = pw_VariableLengthEntryQueue_GetEntry(&it);
|
||||
pw_InlineVarLenEntryQueue_Iterator_Advance(&it);
|
||||
entry = pw_InlineVarLenEntryQueue_GetEntry(&it);
|
||||
ASSERT_EQ(entry.size_1, sizeof(uint32_t) + 1);
|
||||
ASSERT_EQ(entry.size_2, 0u);
|
||||
|
||||
pw_VariableLengthEntryQueue_Iterator_Advance(&it);
|
||||
entry = pw_VariableLengthEntryQueue_GetEntry(&it);
|
||||
pw_InlineVarLenEntryQueue_Iterator_Advance(&it);
|
||||
entry = pw_InlineVarLenEntryQueue_GetEntry(&it);
|
||||
ASSERT_EQ(entry.size_1, sizeof(uint32_t) + 5);
|
||||
ASSERT_EQ(entry.size_2, 0u);
|
||||
|
||||
pw_VariableLengthEntryQueue_Iterator_Advance(&it);
|
||||
entry = pw_VariableLengthEntryQueue_GetEntry(&it);
|
||||
pw_InlineVarLenEntryQueue_Iterator_Advance(&it);
|
||||
entry = pw_InlineVarLenEntryQueue_GetEntry(&it);
|
||||
ASSERT_EQ(entry.size_1, sizeof(uint32_t) + 4);
|
||||
ASSERT_EQ(entry.size_2, 0u);
|
||||
|
||||
pw_VariableLengthEntryQueue_Iterator_Advance(&it);
|
||||
pw_VariableLengthEntryQueue_Iterator end =
|
||||
pw_VariableLengthEntryQueue_End(buffer);
|
||||
ASSERT_EQ(pw_VariableLengthEntryQueue_Iterator_Equal(&it, &end), true);
|
||||
pw_InlineVarLenEntryQueue_Iterator_Advance(&it);
|
||||
pw_InlineVarLenEntryQueue_Iterator end =
|
||||
pw_InlineVarLenEntryQueue_End(buffer);
|
||||
ASSERT_EQ(pw_InlineVarLenEntryQueue_Iterator_Equal(&it, &end), true);
|
||||
|
||||
return "passed";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user