Skip to content

Commit

Permalink
pw_containers: VariableLengthEntryQueue C++ API
Browse files Browse the repository at this point in the history
The C++ API is similar to pw::InlineQueue, but uses the C
implementation.

Change-Id: Ief89ee808556305e75dccd0c90723177a14744b2
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/169910
Pigweed-Auto-Submit: Wyatt Hepler <[email protected]>
Reviewed-by: Armando Montanez <[email protected]>
Commit-Queue: Auto-Submit <[email protected]>
  • Loading branch information
255 authored and CQ Bot Account committed Feb 26, 2024
1 parent 44a57f1 commit e589acd
Show file tree
Hide file tree
Showing 5 changed files with 597 additions and 59 deletions.
1 change: 1 addition & 0 deletions pw_containers/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ cc_library(
hdrs = ["public/pw_containers/variable_length_entry_queue.h"],
includes = ["public"],
deps = [
":raw_storage",
"//pw_assert",
"//pw_varint",
],
Expand Down
1 change: 1 addition & 0 deletions pw_containers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pw_add_library(pw_containers.variable_length_entry_queue STATIC
PUBLIC_INCLUDES
public
PUBLIC_DEPS
pw_containers._raw_storage
pw_varint
PRIVATE_DEPS
pw_assert
Expand Down
100 changes: 100 additions & 0 deletions pw_containers/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,108 @@ pw::VariableLengthEntryQueue
.. doxygenfile:: pw_containers/variable_length_entry_queue.h
:sections: detaileddescription

Example
=======
.. tab-set::

.. tab-item:: C++
:sync: c++

Queues are declared with their max size
(``VariableLengthEntryQueue<kMaxSize>``) but may be used without
specifying the size (``VariableLengthEntryQueue<>&``).

.. code-block:: c++

// Declare a queue with capacity sufficient for one 10-byte entry or
// multiple smaller entries.
pw::VariableLengthEntryQueue<10> queue;

// Push an entry, asserting if the entry does not fit.
queue.push(queue, data)

// Use push_overwrite() to push entries, overwriting older entries
// as needed.
queue.push_overwrite(queue, more_data)

// Remove an entry.
queue.pop();

Alternately, a ``VariableLengthEntryQueue`` may be initialized in an
existing ``uint32_t`` array.

.. code-block:: c++

// Initialize a VariableLengthEntryQueue.
uint32_t buffer[32];
auto& queue = pw::VariableLengthEntryQueue<>::Init(buffer);

// Largest supported entry is 114 B (13 B overhead + 1 B prefix)
assert(queue.max_size_bytes() == 114u);

// Write data
queue.push_overwrite(data);

.. 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.

.. code-block:: c
// Declare a queue with capacity sufficient for one 10-byte entry or
// multiple smaller entries.
PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(queue, 10);
// Push an entry, asserting if the entry does not fit.
pw_VariableLengthEntryQueue_Push(queue, "12345", 5);
// Use push_overwrite() to push entries, overwriting older entries
// as needed.
pw_VariableLengthEntryQueue_PushOverwrite(queue, "abcdefg", 7);
// Remove an entry.
pw_VariableLengthEntryQueue_Pop(queue);
Alternately, a ``VariableLengthEntryQueue`` may be initialized in an
existing ``uint32_t`` array.

.. code-block:: c
// Initialize a VariableLengthEntryQueue.
uint32_t buffer[32];
pw_VariableLengthEntryQueue_Init(buffer, 32);
// Largest supported entry is 114 B (13 B overhead + 1 B prefix)
assert(pw_VariableLengthEntryQueue_MaxSizeBytes(buffer) == 114u);
// Write some data
pw_VariableLengthEntryQueue_PushOverwrite(buffer, "123", 3);
Queue vs. deque
===============
This module provides :cpp:type:`VariableLengthEntryQueue`, but no corresponding
``VariableLengthEntryDeque`` 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
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
be inefficient and unlikely to be used, they are not implemented, and only a
queue class is provided.

API Reference
===============
C++
---
.. doxygengroup:: variable_length_entry_queue_cpp_api
:content-only:
:members:

C
-
.. doxygengroup:: variable_length_entry_queue_c_api
Expand Down
Loading

0 comments on commit e589acd

Please sign in to comment.