xref: /aosp_15_r20/external/pigweed/pw_containers/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_containers:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker=============
4*61c4878aSAndroid Build Coastguard Workerpw_containers
5*61c4878aSAndroid Build Coastguard Worker=============
6*61c4878aSAndroid Build Coastguard WorkerThe ``pw_containers`` module provides embedded-friendly container classes.
7*61c4878aSAndroid Build Coastguard Worker
8*61c4878aSAndroid Build Coastguard Worker----------
9*61c4878aSAndroid Build Coastguard Workerpw::Vector
10*61c4878aSAndroid Build Coastguard Worker----------
11*61c4878aSAndroid Build Coastguard WorkerThe Vector class is similar to ``std::vector``, except it is backed by a
12*61c4878aSAndroid Build Coastguard Workerfixed-size buffer. Vectors must be declared with an explicit maximum size
13*61c4878aSAndroid Build Coastguard Worker(e.g. ``Vector<int, 10>``) but vectors can be used and referred to without the
14*61c4878aSAndroid Build Coastguard Workermax size template parameter (e.g. ``Vector<int>``).
15*61c4878aSAndroid Build Coastguard Worker
16*61c4878aSAndroid Build Coastguard WorkerTo allow referring to a ``pw::Vector`` without an explicit maximum size, all
17*61c4878aSAndroid Build Coastguard WorkerVector classes inherit from the generic ``Vector<T>``, which stores the maximum
18*61c4878aSAndroid Build Coastguard Workersize in a variable. This allows Vectors to be used without having to know
19*61c4878aSAndroid Build Coastguard Workertheir maximum size at compile time. It also keeps code size small since
20*61c4878aSAndroid Build Coastguard Workerfunction implementations are shared for all maximum sizes.
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard Worker---------------
23*61c4878aSAndroid Build Coastguard Workerpw::InlineDeque
24*61c4878aSAndroid Build Coastguard Worker---------------
25*61c4878aSAndroid Build Coastguard Worker.. doxygentypedef:: pw::InlineDeque
26*61c4878aSAndroid Build Coastguard Worker
27*61c4878aSAndroid Build Coastguard Worker---------------
28*61c4878aSAndroid Build Coastguard Workerpw::InlineQueue
29*61c4878aSAndroid Build Coastguard Worker---------------
30*61c4878aSAndroid Build Coastguard Worker.. doxygentypedef:: pw::InlineQueue
31*61c4878aSAndroid Build Coastguard Worker
32*61c4878aSAndroid Build Coastguard Worker--------------------------
33*61c4878aSAndroid Build Coastguard Workerpw::InlineVarLenEntryQueue
34*61c4878aSAndroid Build Coastguard Worker--------------------------
35*61c4878aSAndroid Build Coastguard Worker.. doxygenfile:: pw_containers/inline_var_len_entry_queue.h
36*61c4878aSAndroid Build Coastguard Worker   :sections: detaileddescription
37*61c4878aSAndroid Build Coastguard Worker
38*61c4878aSAndroid Build Coastguard WorkerExample
39*61c4878aSAndroid Build Coastguard Worker=======
40*61c4878aSAndroid Build Coastguard Worker.. tab-set::
41*61c4878aSAndroid Build Coastguard Worker
42*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: C++
43*61c4878aSAndroid Build Coastguard Worker      :sync: c++
44*61c4878aSAndroid Build Coastguard Worker
45*61c4878aSAndroid Build Coastguard Worker      Queues are declared with their max size
46*61c4878aSAndroid Build Coastguard Worker      (``InlineVarLenEntryQueue<kMaxSize>``) but may be used without
47*61c4878aSAndroid Build Coastguard Worker      specifying the size (``InlineVarLenEntryQueue<>&``).
48*61c4878aSAndroid Build Coastguard Worker
49*61c4878aSAndroid Build Coastguard Worker      .. code-block:: c++
50*61c4878aSAndroid Build Coastguard Worker
51*61c4878aSAndroid Build Coastguard Worker         // Declare a queue with capacity sufficient for one 10-byte entry or
52*61c4878aSAndroid Build Coastguard Worker         // multiple smaller entries.
53*61c4878aSAndroid Build Coastguard Worker         pw::InlineVarLenEntryQueue<10> queue;
54*61c4878aSAndroid Build Coastguard Worker
55*61c4878aSAndroid Build Coastguard Worker         // Push an entry, asserting if the entry does not fit.
56*61c4878aSAndroid Build Coastguard Worker         queue.push(queue, data)
57*61c4878aSAndroid Build Coastguard Worker
58*61c4878aSAndroid Build Coastguard Worker         // Use push_overwrite() to push entries, overwriting older entries
59*61c4878aSAndroid Build Coastguard Worker         // as needed.
60*61c4878aSAndroid Build Coastguard Worker         queue.push_overwrite(queue, more_data)
61*61c4878aSAndroid Build Coastguard Worker
62*61c4878aSAndroid Build Coastguard Worker         // Remove an entry.
63*61c4878aSAndroid Build Coastguard Worker         queue.pop();
64*61c4878aSAndroid Build Coastguard Worker
65*61c4878aSAndroid Build Coastguard Worker      Alternately, a ``InlineVarLenEntryQueue`` may be initialized in an
66*61c4878aSAndroid Build Coastguard Worker      existing ``uint32_t`` array.
67*61c4878aSAndroid Build Coastguard Worker
68*61c4878aSAndroid Build Coastguard Worker      .. code-block:: c++
69*61c4878aSAndroid Build Coastguard Worker
70*61c4878aSAndroid Build Coastguard Worker         // Initialize a InlineVarLenEntryQueue.
71*61c4878aSAndroid Build Coastguard Worker         uint32_t buffer[32];
72*61c4878aSAndroid Build Coastguard Worker         auto& queue = pw::InlineVarLenEntryQueue<>::Init(buffer);
73*61c4878aSAndroid Build Coastguard Worker
74*61c4878aSAndroid Build Coastguard Worker         // Largest supported entry is 114 B (13 B overhead + 1 B prefix)
75*61c4878aSAndroid Build Coastguard Worker         assert(queue.max_size_bytes() == 114u);
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Worker         // Write data
78*61c4878aSAndroid Build Coastguard Worker         queue.push_overwrite(data);
79*61c4878aSAndroid Build Coastguard Worker
80*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: C
81*61c4878aSAndroid Build Coastguard Worker      :sync: c
82*61c4878aSAndroid Build Coastguard Worker
83*61c4878aSAndroid Build Coastguard Worker      A ``InlineVarLenEntryQueue`` may be declared and initialized in C with the
84*61c4878aSAndroid Build Coastguard Worker      :c:macro:`PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE` macro.
85*61c4878aSAndroid Build Coastguard Worker
86*61c4878aSAndroid Build Coastguard Worker      .. code-block:: c
87*61c4878aSAndroid Build Coastguard Worker
88*61c4878aSAndroid Build Coastguard Worker         // Declare a queue with capacity sufficient for one 10-byte entry or
89*61c4878aSAndroid Build Coastguard Worker         // multiple smaller entries.
90*61c4878aSAndroid Build Coastguard Worker         PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(queue, 10);
91*61c4878aSAndroid Build Coastguard Worker
92*61c4878aSAndroid Build Coastguard Worker         // Push an entry, asserting if the entry does not fit.
93*61c4878aSAndroid Build Coastguard Worker         pw_InlineVarLenEntryQueue_Push(queue, "12345", 5);
94*61c4878aSAndroid Build Coastguard Worker
95*61c4878aSAndroid Build Coastguard Worker         // Use push_overwrite() to push entries, overwriting older entries
96*61c4878aSAndroid Build Coastguard Worker         // as needed.
97*61c4878aSAndroid Build Coastguard Worker         pw_InlineVarLenEntryQueue_PushOverwrite(queue, "abcdefg", 7);
98*61c4878aSAndroid Build Coastguard Worker
99*61c4878aSAndroid Build Coastguard Worker         // Remove an entry.
100*61c4878aSAndroid Build Coastguard Worker         pw_InlineVarLenEntryQueue_Pop(queue);
101*61c4878aSAndroid Build Coastguard Worker
102*61c4878aSAndroid Build Coastguard Worker      Alternately, a ``InlineVarLenEntryQueue`` may be initialized in an
103*61c4878aSAndroid Build Coastguard Worker      existing ``uint32_t`` array.
104*61c4878aSAndroid Build Coastguard Worker
105*61c4878aSAndroid Build Coastguard Worker      .. code-block:: c
106*61c4878aSAndroid Build Coastguard Worker
107*61c4878aSAndroid Build Coastguard Worker         // Initialize a InlineVarLenEntryQueue.
108*61c4878aSAndroid Build Coastguard Worker         uint32_t buffer[32];
109*61c4878aSAndroid Build Coastguard Worker         pw_InlineVarLenEntryQueue_Init(buffer, 32);
110*61c4878aSAndroid Build Coastguard Worker
111*61c4878aSAndroid Build Coastguard Worker         // Largest supported entry is 114 B (13 B overhead + 1 B prefix)
112*61c4878aSAndroid Build Coastguard Worker         assert(pw_InlineVarLenEntryQueue_MaxSizeBytes(buffer) == 114u);
113*61c4878aSAndroid Build Coastguard Worker
114*61c4878aSAndroid Build Coastguard Worker         // Write some data
115*61c4878aSAndroid Build Coastguard Worker         pw_InlineVarLenEntryQueue_PushOverwrite(buffer, "123", 3);
116*61c4878aSAndroid Build Coastguard Worker
117*61c4878aSAndroid Build Coastguard WorkerQueue vs. deque
118*61c4878aSAndroid Build Coastguard Worker===============
119*61c4878aSAndroid Build Coastguard WorkerThis module provides :cpp:type:`InlineVarLenEntryQueue`, but no corresponding
120*61c4878aSAndroid Build Coastguard Worker``InlineVarLenEntryDeque`` class. Following the C++ Standard Library style,
121*61c4878aSAndroid Build Coastguard Workerthe deque class would provide ``push_front()`` and ``pop_back()`` operations in
122*61c4878aSAndroid Build Coastguard Workeraddition to ``push_back()`` and ``pop_front()`` (equivalent to a queue's
123*61c4878aSAndroid Build Coastguard Worker``push()`` and ``pop()``).
124*61c4878aSAndroid Build Coastguard Worker
125*61c4878aSAndroid Build Coastguard WorkerThere is no ``InlineVarLenEntryDeque`` class because there is no efficient way
126*61c4878aSAndroid Build Coastguard Workerto implement ``push_front()`` and ``pop_back()``. These operations would
127*61c4878aSAndroid Build Coastguard Workernecessarily be O(n), since each entry knows the position of the next entry, but
128*61c4878aSAndroid Build Coastguard Workernot the previous, as in a single-linked list. Given that these operations would
129*61c4878aSAndroid Build Coastguard Workerbe inefficient and unlikely to be used, they are not implemented, and only a
130*61c4878aSAndroid Build Coastguard Workerqueue class is provided.
131*61c4878aSAndroid Build Coastguard Worker
132*61c4878aSAndroid Build Coastguard WorkerAPI Reference
133*61c4878aSAndroid Build Coastguard Worker=============
134*61c4878aSAndroid Build Coastguard WorkerC++
135*61c4878aSAndroid Build Coastguard Worker---
136*61c4878aSAndroid Build Coastguard Worker.. doxygengroup:: inline_var_len_entry_queue_cpp_api
137*61c4878aSAndroid Build Coastguard Worker   :content-only:
138*61c4878aSAndroid Build Coastguard Worker   :members:
139*61c4878aSAndroid Build Coastguard Worker
140*61c4878aSAndroid Build Coastguard WorkerC
141*61c4878aSAndroid Build Coastguard Worker-
142*61c4878aSAndroid Build Coastguard Worker.. doxygengroup:: inline_var_len_entry_queue_c_api
143*61c4878aSAndroid Build Coastguard Worker   :content-only:
144*61c4878aSAndroid Build Coastguard Worker
145*61c4878aSAndroid Build Coastguard WorkerPython
146*61c4878aSAndroid Build Coastguard Worker------
147*61c4878aSAndroid Build Coastguard Worker.. automodule:: pw_containers.inline_var_len_entry_queue
148*61c4878aSAndroid Build Coastguard Worker   :members:
149*61c4878aSAndroid Build Coastguard Worker
150*61c4878aSAndroid Build Coastguard Worker.. _module-pw_containers-intrusive_list:
151*61c4878aSAndroid Build Coastguard Worker
152*61c4878aSAndroid Build Coastguard Worker-----------------
153*61c4878aSAndroid Build Coastguard Workerpw::IntrusiveList
154*61c4878aSAndroid Build Coastguard Worker-----------------
155*61c4878aSAndroid Build Coastguard Worker``pw::IntrusiveList`` provides an embedded-friendly, double-linked, intrusive
156*61c4878aSAndroid Build Coastguard Workerlist implementation. An intrusive list is a type of linked list that embeds list
157*61c4878aSAndroid Build Coastguard Workermetadata, such as a "next" pointer, into the list object itself. This allows the
158*61c4878aSAndroid Build Coastguard Workerconstruction of a linked list without the need to dynamically allocate list
159*61c4878aSAndroid Build Coastguard Workerentries.
160*61c4878aSAndroid Build Coastguard Worker
161*61c4878aSAndroid Build Coastguard WorkerIn C, an intrusive list can be made by manually including the "next" pointer as
162*61c4878aSAndroid Build Coastguard Workera member of the object's struct. ``pw::IntrusiveList`` uses C++ features to
163*61c4878aSAndroid Build Coastguard Workersimplify the process of creating an intrusive list. It provides classes that
164*61c4878aSAndroid Build Coastguard Workerlist elements can inherit from, protecting the list metadata from being accessed
165*61c4878aSAndroid Build Coastguard Workerby the item class.
166*61c4878aSAndroid Build Coastguard Worker
167*61c4878aSAndroid Build Coastguard WorkerAPI Reference
168*61c4878aSAndroid Build Coastguard Worker=============
169*61c4878aSAndroid Build Coastguard WorkerThis class is similar to ``std::list<T>``, except that the type of items to be
170*61c4878aSAndroid Build Coastguard Workeradded must derive from ``pw::IntrusiveList<T>::Item``.
171*61c4878aSAndroid Build Coastguard Worker
172*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::containers::future::IntrusiveList
173*61c4878aSAndroid Build Coastguard Worker   :members:
174*61c4878aSAndroid Build Coastguard Worker
175*61c4878aSAndroid Build Coastguard Worker.. note::
176*61c4878aSAndroid Build Coastguard Worker   Originally, ``pw::IntrusiveList<T>`` was implemented as a singly-linked list.
177*61c4878aSAndroid Build Coastguard Worker   To facilitate migration to ``pw::IntrusiveForwardList<T>::Item``, this
178*61c4878aSAndroid Build Coastguard Worker   original implementation can still be temporarily used by enabling the
179*61c4878aSAndroid Build Coastguard Worker   ``PW_CONTAINERS_USE_LEGACY_INTRUSIVE_LIST`` module configuration option.
180*61c4878aSAndroid Build Coastguard Worker
181*61c4878aSAndroid Build Coastguard Worker.. _module-pw_containers-intrusive_list-example:
182*61c4878aSAndroid Build Coastguard Worker
183*61c4878aSAndroid Build Coastguard WorkerExample
184*61c4878aSAndroid Build Coastguard Worker=======
185*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/intrusive_list.cc
186*61c4878aSAndroid Build Coastguard Worker   :language: cpp
187*61c4878aSAndroid Build Coastguard Worker   :linenos:
188*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_containers-intrusive_list]
189*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_containers-intrusive_list]
190*61c4878aSAndroid Build Coastguard Worker
191*61c4878aSAndroid Build Coastguard Worker------------------------
192*61c4878aSAndroid Build Coastguard Workerpw::IntrusiveForwardList
193*61c4878aSAndroid Build Coastguard Worker------------------------
194*61c4878aSAndroid Build Coastguard Worker``pw::IntrusiveForwardList`` provides an embedded-friendly, singly-linked,
195*61c4878aSAndroid Build Coastguard Workerintrusive list implementation. It is very similar to
196*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_containers-intrusive_list`, except that is singly rather than
197*61c4878aSAndroid Build Coastguard Workerdoubly linked.
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard WorkerAPI Reference
200*61c4878aSAndroid Build Coastguard Worker=============
201*61c4878aSAndroid Build Coastguard WorkerThis class is similar to ``std::forward_list<T>``. Items to be added must derive
202*61c4878aSAndroid Build Coastguard Workerfrom ``pw::IntrusiveForwardList<T>::Item``.
203*61c4878aSAndroid Build Coastguard Worker
204*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::IntrusiveForwardList
205*61c4878aSAndroid Build Coastguard Worker   :members:
206*61c4878aSAndroid Build Coastguard Worker
207*61c4878aSAndroid Build Coastguard WorkerExample
208*61c4878aSAndroid Build Coastguard Worker=======
209*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/intrusive_forward_list.cc
210*61c4878aSAndroid Build Coastguard Worker   :language: cpp
211*61c4878aSAndroid Build Coastguard Worker   :linenos:
212*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_containers-intrusive_forward_list]
213*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_containers-intrusive_forward_list]
214*61c4878aSAndroid Build Coastguard Worker
215*61c4878aSAndroid Build Coastguard WorkerPerformance Considerations
216*61c4878aSAndroid Build Coastguard Worker==========================
217*61c4878aSAndroid Build Coastguard WorkerItems only include pointers to the next item. To reach previous items, the list
218*61c4878aSAndroid Build Coastguard Workermaintains a cycle of items so that the first item can be reached from the last.
219*61c4878aSAndroid Build Coastguard WorkerThis structure means certain operations have linear complexity in terms of the
220*61c4878aSAndroid Build Coastguard Workernumber of items in the list, i.e. they are "O(n)":
221*61c4878aSAndroid Build Coastguard Worker
222*61c4878aSAndroid Build Coastguard Worker- Removing an item from a list using
223*61c4878aSAndroid Build Coastguard Worker  ``pw::IntrusiveForwardList<T>::remove(const T&)``.
224*61c4878aSAndroid Build Coastguard Worker- Getting the list size using ``pw::IntrusiveForwardList<T>::size()``.
225*61c4878aSAndroid Build Coastguard Worker
226*61c4878aSAndroid Build Coastguard WorkerWhen using a ``pw::IntrusiveForwardList<T>`` in a performance critical section
227*61c4878aSAndroid Build Coastguard Workeror with many items, authors should prefer to avoid these methods. For example,
228*61c4878aSAndroid Build Coastguard Workerit may be preferable to create items that together with their storage outlive
229*61c4878aSAndroid Build Coastguard Workerthe list.
230*61c4878aSAndroid Build Coastguard Worker
231*61c4878aSAndroid Build Coastguard WorkerNotably, ``pw::IntrusiveForwardList<T>::end()`` is constant complexity (i.e.
232*61c4878aSAndroid Build Coastguard Worker"O(1)"). As a result iterating over a list does not incur an additional penalty.
233*61c4878aSAndroid Build Coastguard Worker
234*61c4878aSAndroid Build Coastguard Worker.. _module-pw_containers-intrusivelist-size-report:
235*61c4878aSAndroid Build Coastguard Worker
236*61c4878aSAndroid Build Coastguard WorkerSize report
237*61c4878aSAndroid Build Coastguard Worker===========
238*61c4878aSAndroid Build Coastguard Worker.. include:: intrusive_list_size_report
239*61c4878aSAndroid Build Coastguard Worker
240*61c4878aSAndroid Build Coastguard Worker.. _module-pw_containers-intrusive_set:
241*61c4878aSAndroid Build Coastguard Worker
242*61c4878aSAndroid Build Coastguard Worker----------------
243*61c4878aSAndroid Build Coastguard Workerpw::IntrusiveSet
244*61c4878aSAndroid Build Coastguard Worker----------------
245*61c4878aSAndroid Build Coastguard Worker``pw::IntrusiveSet`` provides an embedded-friendly, tree-based, intrusive
246*61c4878aSAndroid Build Coastguard Workerset implementation. The intrusive aspect of the set is very similar to that of
247*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_containers-intrusive_list`.
248*61c4878aSAndroid Build Coastguard Worker
249*61c4878aSAndroid Build Coastguard WorkerAPI Reference
250*61c4878aSAndroid Build Coastguard Worker=============
251*61c4878aSAndroid Build Coastguard WorkerThis class is similar to ``std::set<T>``. Items to be added must derive from
252*61c4878aSAndroid Build Coastguard Worker``pw::IntrusiveSet<T>::Item`` or an equivalent type.
253*61c4878aSAndroid Build Coastguard Worker
254*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::IntrusiveSet
255*61c4878aSAndroid Build Coastguard Worker   :members:
256*61c4878aSAndroid Build Coastguard Worker
257*61c4878aSAndroid Build Coastguard WorkerExample
258*61c4878aSAndroid Build Coastguard Worker=======
259*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/intrusive_set.cc
260*61c4878aSAndroid Build Coastguard Worker   :language: cpp
261*61c4878aSAndroid Build Coastguard Worker   :linenos:
262*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_containers-intrusive_set]
263*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_containers-intrusive_set]
264*61c4878aSAndroid Build Coastguard Worker
265*61c4878aSAndroid Build Coastguard Worker---------------------
266*61c4878aSAndroid Build Coastguard Workerpw::IntrusiveMultiSet
267*61c4878aSAndroid Build Coastguard Worker---------------------
268*61c4878aSAndroid Build Coastguard Worker``pw::IntrusiveMultiSet`` provides an embedded-friendly, tree-based, intrusive
269*61c4878aSAndroid Build Coastguard Workermultiset implementation. This is very similar to
270*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_containers-intrusive_set`, except that the tree may contain
271*61c4878aSAndroid Build Coastguard Workermultiple items with equivalent keys.
272*61c4878aSAndroid Build Coastguard Worker
273*61c4878aSAndroid Build Coastguard WorkerAPI Reference
274*61c4878aSAndroid Build Coastguard Worker=============
275*61c4878aSAndroid Build Coastguard WorkerThis class is similar to ``std::multiset<T>``. Items to be added must derive
276*61c4878aSAndroid Build Coastguard Workerfrom ``pw::IntrusiveMultiSet<T>::Item`` or an equivalent type.
277*61c4878aSAndroid Build Coastguard Worker
278*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::IntrusiveMultiSet
279*61c4878aSAndroid Build Coastguard Worker   :members:
280*61c4878aSAndroid Build Coastguard Worker
281*61c4878aSAndroid Build Coastguard WorkerExample
282*61c4878aSAndroid Build Coastguard Worker=======
283*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/intrusive_multiset.cc
284*61c4878aSAndroid Build Coastguard Worker   :language: cpp
285*61c4878aSAndroid Build Coastguard Worker   :linenos:
286*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_containers-intrusive_multiset]
287*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_containers-intrusive_multiset]
288*61c4878aSAndroid Build Coastguard Worker
289*61c4878aSAndroid Build Coastguard Worker.. _module-pw_containers-intrusive_map:
290*61c4878aSAndroid Build Coastguard Worker
291*61c4878aSAndroid Build Coastguard Worker----------------
292*61c4878aSAndroid Build Coastguard Workerpw::IntrusiveMap
293*61c4878aSAndroid Build Coastguard Worker----------------
294*61c4878aSAndroid Build Coastguard Worker``pw::IntrusiveMap`` provides an embedded-friendly, tree-based, intrusive
295*61c4878aSAndroid Build Coastguard Workermap implementation. The intrusive aspect of the map is very similar to that of
296*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_containers-intrusive_list`.
297*61c4878aSAndroid Build Coastguard Worker
298*61c4878aSAndroid Build Coastguard WorkerAPI Reference
299*61c4878aSAndroid Build Coastguard Worker=============
300*61c4878aSAndroid Build Coastguard WorkerThis class is similar to ``std::map<K, V>``. Items to be added must derive from
301*61c4878aSAndroid Build Coastguard Worker``pw::IntrusiveMap<K, V>::Item`` or an equivalent type.
302*61c4878aSAndroid Build Coastguard Worker
303*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::IntrusiveMap
304*61c4878aSAndroid Build Coastguard Worker   :members:
305*61c4878aSAndroid Build Coastguard Worker
306*61c4878aSAndroid Build Coastguard WorkerExample
307*61c4878aSAndroid Build Coastguard Worker=======
308*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/intrusive_map.cc
309*61c4878aSAndroid Build Coastguard Worker   :language: cpp
310*61c4878aSAndroid Build Coastguard Worker   :linenos:
311*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_containers-intrusive_map]
312*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_containers-intrusive_map]
313*61c4878aSAndroid Build Coastguard Worker
314*61c4878aSAndroid Build Coastguard Worker---------------------
315*61c4878aSAndroid Build Coastguard Workerpw::IntrusiveMultiMap
316*61c4878aSAndroid Build Coastguard Worker---------------------
317*61c4878aSAndroid Build Coastguard Worker``pw::IntrusiveMultiMap`` provides an embedded-friendly, tree-based, intrusive
318*61c4878aSAndroid Build Coastguard Workermultimap implementation. This is very similar to
319*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_containers-intrusive_map`, except that the tree may contain
320*61c4878aSAndroid Build Coastguard Workermultiple items with equivalent keys.
321*61c4878aSAndroid Build Coastguard Worker
322*61c4878aSAndroid Build Coastguard WorkerAPI Reference
323*61c4878aSAndroid Build Coastguard Worker=============
324*61c4878aSAndroid Build Coastguard WorkerThis class is similar to ``std::multimap<K, V>``. Items to be added must derive
325*61c4878aSAndroid Build Coastguard Workerfrom ``pw::IntrusiveMultiMap<K, V>::Item`` or an equivalent type.
326*61c4878aSAndroid Build Coastguard Worker
327*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::IntrusiveMultiMap
328*61c4878aSAndroid Build Coastguard Worker   :members:
329*61c4878aSAndroid Build Coastguard Worker
330*61c4878aSAndroid Build Coastguard WorkerExample
331*61c4878aSAndroid Build Coastguard Worker=======
332*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/intrusive_multimap.cc
333*61c4878aSAndroid Build Coastguard Worker   :language: cpp
334*61c4878aSAndroid Build Coastguard Worker   :linenos:
335*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_containers-intrusive_multimap]
336*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_containers-intrusive_multimap]
337*61c4878aSAndroid Build Coastguard Worker
338*61c4878aSAndroid Build Coastguard Worker------------------------------------
339*61c4878aSAndroid Build Coastguard WorkerUsing items with multiple containers
340*61c4878aSAndroid Build Coastguard Worker------------------------------------
341*61c4878aSAndroid Build Coastguard WorkerIntrusive items may be used with multiple containers, provided each of those
342*61c4878aSAndroid Build Coastguard Workercontainers is templated on a type that is not derived from any of the others.
343*61c4878aSAndroid Build Coastguard WorkerThis can be achieved by multiply inheriting from distinct type:
344*61c4878aSAndroid Build Coastguard Worker
345*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/multiple_containers.cc
346*61c4878aSAndroid Build Coastguard Worker   :language: cpp
347*61c4878aSAndroid Build Coastguard Worker   :linenos:
348*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_containers-multiple_containers]
349*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_containers-multiple_containers]
350*61c4878aSAndroid Build Coastguard Worker
351*61c4878aSAndroid Build Coastguard WorkerIf one or more types is derived from another, the compiler will fail to build
352*61c4878aSAndroid Build Coastguard Workerwith an error that ``ItemType`` is ambiguous or found in multiple base classes.
353*61c4878aSAndroid Build Coastguard Worker
354*61c4878aSAndroid Build Coastguard Worker-----------------------
355*61c4878aSAndroid Build Coastguard Workerpw::containers::FlatMap
356*61c4878aSAndroid Build Coastguard Worker-----------------------
357*61c4878aSAndroid Build Coastguard Worker``FlatMap`` provides a simple, fixed-size associative array with `O`\ (log `n`)
358*61c4878aSAndroid Build Coastguard Workerlookup by key.
359*61c4878aSAndroid Build Coastguard Worker
360*61c4878aSAndroid Build Coastguard Worker``pw::containers::FlatMap`` contains the same methods and features for looking
361*61c4878aSAndroid Build Coastguard Workerup data as ``std::map``. However, modification of the underlying data is limited
362*61c4878aSAndroid Build Coastguard Workerto the mapped values, via ``.at()`` (key must exist) and ``mapped_iterator``
363*61c4878aSAndroid Build Coastguard Workerobjects returned by ``.mapped_begin()`` and ``.mapped_end()``.
364*61c4878aSAndroid Build Coastguard Worker``mapped_iterator`` objects are bidirectional iterators that can be dereferenced
365*61c4878aSAndroid Build Coastguard Workerto access and mutate the mapped value objects.
366*61c4878aSAndroid Build Coastguard Worker
367*61c4878aSAndroid Build Coastguard WorkerThe underlying array in ``pw::containers::FlatMap`` does not need to be sorted.
368*61c4878aSAndroid Build Coastguard WorkerDuring construction, ``pw::containers::FlatMap`` will perform a constexpr
369*61c4878aSAndroid Build Coastguard Workerinsertion sort.
370*61c4878aSAndroid Build Coastguard Worker
371*61c4878aSAndroid Build Coastguard WorkerA ``FlatMap`` can be created in one of several ways. Each of the following
372*61c4878aSAndroid Build Coastguard Workerexamples defines a ``FlatMap`` with two items.
373*61c4878aSAndroid Build Coastguard Worker
374*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/flat_map.cc
375*61c4878aSAndroid Build Coastguard Worker   :language: cpp
376*61c4878aSAndroid Build Coastguard Worker   :linenos:
377*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_containers-flat_map]
378*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_containers-flat_map]
379*61c4878aSAndroid Build Coastguard Worker
380*61c4878aSAndroid Build Coastguard Worker----------------------------
381*61c4878aSAndroid Build Coastguard Workerpw::containers::FilteredView
382*61c4878aSAndroid Build Coastguard Worker----------------------------
383*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::containers::FilteredView
384*61c4878aSAndroid Build Coastguard Worker
385*61c4878aSAndroid Build Coastguard Worker-------------------------------
386*61c4878aSAndroid Build Coastguard Workerpw::containers::WrappedIterator
387*61c4878aSAndroid Build Coastguard Worker-------------------------------
388*61c4878aSAndroid Build Coastguard Worker``pw::containers::WrappedIterator`` is a class that makes it easy to wrap an
389*61c4878aSAndroid Build Coastguard Workerexisting iterator type. It reduces boilerplate by providing ``operator++``,
390*61c4878aSAndroid Build Coastguard Worker``operator--``, ``operator==``, ``operator!=``, and the standard iterator
391*61c4878aSAndroid Build Coastguard Workeraliases (``difference_type``, ``value_type``, etc.). It does not provide the
392*61c4878aSAndroid Build Coastguard Workerdereference operator; that must be supplied by a derived class.
393*61c4878aSAndroid Build Coastguard Worker
394*61c4878aSAndroid Build Coastguard WorkerTo use it, create a class that derives from ``WrappedIterator`` and define
395*61c4878aSAndroid Build Coastguard Worker``operator*()`` and ``operator->()`` as appropriate. The new iterator might
396*61c4878aSAndroid Build Coastguard Workerapply a transformation to or access a member of the values provided by the
397*61c4878aSAndroid Build Coastguard Workeroriginal iterator. The following example defines an iterator that multiplies the
398*61c4878aSAndroid Build Coastguard Workervalues in an array by 2.
399*61c4878aSAndroid Build Coastguard Worker
400*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/wrapped_iterator.cc
401*61c4878aSAndroid Build Coastguard Worker   :language: cpp
402*61c4878aSAndroid Build Coastguard Worker   :linenos:
403*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_containers-wrapped_iterator]
404*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_containers-wrapped_iterator]
405*61c4878aSAndroid Build Coastguard Worker
406*61c4878aSAndroid Build Coastguard Worker``WrappedIterator`` may be used in concert with ``FilteredView`` to create a
407*61c4878aSAndroid Build Coastguard Workerview that iterates over a matching values in a container and applies a
408*61c4878aSAndroid Build Coastguard Workertransformation to the values. For example, it could be used with
409*61c4878aSAndroid Build Coastguard Worker``FilteredView`` to filter a list of packets and yield only one field from the
410*61c4878aSAndroid Build Coastguard Workerpacket.
411*61c4878aSAndroid Build Coastguard Worker
412*61c4878aSAndroid Build Coastguard WorkerThe combination of ``FilteredView`` and ``WrappedIterator`` provides some basic
413*61c4878aSAndroid Build Coastguard Workerfunctional programming features similar to (though much more cumbersome than)
414*61c4878aSAndroid Build Coastguard Worker`generator expressions <https://www.python.org/dev/peps/pep-0289/>`_ (or `filter
415*61c4878aSAndroid Build Coastguard Worker<https://docs.python.org/3/library/functions.html#filter>`_/`map
416*61c4878aSAndroid Build Coastguard Worker<https://docs.python.org/3/library/functions.html#map>`_) in Python or streams
417*61c4878aSAndroid Build Coastguard Workerin Java 8. ``WrappedIterator`` and ``FilteredView`` require no memory
418*61c4878aSAndroid Build Coastguard Workerallocation, which is helpful when memory is too constrained to process the items
419*61c4878aSAndroid Build Coastguard Workerinto a new container.
420*61c4878aSAndroid Build Coastguard Worker
421*61c4878aSAndroid Build Coastguard Worker------------------------
422*61c4878aSAndroid Build Coastguard Workerpw::containers::to_array
423*61c4878aSAndroid Build Coastguard Worker------------------------
424*61c4878aSAndroid Build Coastguard Worker``pw::containers::to_array`` is a C++14-compatible implementation of C++20's
425*61c4878aSAndroid Build Coastguard Worker`std::to_array <https://en.cppreference.com/w/cpp/container/array/to_array>`_.
426*61c4878aSAndroid Build Coastguard WorkerIn C++20, it is an alias for ``std::to_array``. It converts a C array to a
427*61c4878aSAndroid Build Coastguard Worker``std::array``.
428*61c4878aSAndroid Build Coastguard Worker
429*61c4878aSAndroid Build Coastguard Worker-------------------------
430*61c4878aSAndroid Build Coastguard Workerpw_containers/algorithm.h
431*61c4878aSAndroid Build Coastguard Worker-------------------------
432*61c4878aSAndroid Build Coastguard WorkerPigweed provides a set of Container-based versions of algorithmic functions
433*61c4878aSAndroid Build Coastguard Workerwithin the C++ standard library, based on a subset of
434*61c4878aSAndroid Build Coastguard Worker``absl/algorithm/container.h``.
435*61c4878aSAndroid Build Coastguard Worker
436*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: bool pw::containers::AllOf()
437*61c4878aSAndroid Build Coastguard Worker
438*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::all_of()`` function to
439*61c4878aSAndroid Build Coastguard Worker   test if all elements within a container satisfy a condition.
440*61c4878aSAndroid Build Coastguard Worker
441*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: bool pw::containers::AnyOf()
442*61c4878aSAndroid Build Coastguard Worker
443*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::any_of()`` function to
444*61c4878aSAndroid Build Coastguard Worker   test if any element in a container fulfills a condition.
445*61c4878aSAndroid Build Coastguard Worker
446*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: bool pw::containers::NoneOf()
447*61c4878aSAndroid Build Coastguard Worker
448*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::none_of()`` function to
449*61c4878aSAndroid Build Coastguard Worker   test if no elements in a container fulfill a condition.
450*61c4878aSAndroid Build Coastguard Worker
451*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::ForEach()
452*61c4878aSAndroid Build Coastguard Worker
453*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::for_each()`` function to
454*61c4878aSAndroid Build Coastguard Worker   apply a function to a container's elements.
455*61c4878aSAndroid Build Coastguard Worker
456*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::Find()
457*61c4878aSAndroid Build Coastguard Worker
458*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::find()`` function to find
459*61c4878aSAndroid Build Coastguard Worker   the first element containing the passed value within a container value.
460*61c4878aSAndroid Build Coastguard Worker
461*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::FindIf()
462*61c4878aSAndroid Build Coastguard Worker
463*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::find_if()`` function to find
464*61c4878aSAndroid Build Coastguard Worker   the first element in a container matching the given condition.
465*61c4878aSAndroid Build Coastguard Worker
466*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::FindIfNot()
467*61c4878aSAndroid Build Coastguard Worker
468*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::find_if_not()`` function to
469*61c4878aSAndroid Build Coastguard Worker   find the first element in a container not matching the given condition.
470*61c4878aSAndroid Build Coastguard Worker
471*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::FindEnd()
472*61c4878aSAndroid Build Coastguard Worker
473*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::find_end()`` function to
474*61c4878aSAndroid Build Coastguard Worker   find the last subsequence within a container.
475*61c4878aSAndroid Build Coastguard Worker
476*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::FindFirstOf()
477*61c4878aSAndroid Build Coastguard Worker
478*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::find_first_of()`` function
479*61c4878aSAndroid Build Coastguard Worker   to find the first element within the container that is also within the options
480*61c4878aSAndroid Build Coastguard Worker   container.
481*61c4878aSAndroid Build Coastguard Worker
482*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::AdjacentFind()
483*61c4878aSAndroid Build Coastguard Worker
484*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::adjacent_find()`` function
485*61c4878aSAndroid Build Coastguard Worker   to find equal adjacent elements within a container.
486*61c4878aSAndroid Build Coastguard Worker
487*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::Count()
488*61c4878aSAndroid Build Coastguard Worker
489*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::count()`` function to count
490*61c4878aSAndroid Build Coastguard Worker   values that match within a container.
491*61c4878aSAndroid Build Coastguard Worker
492*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::CountIf()
493*61c4878aSAndroid Build Coastguard Worker
494*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::count_if()`` function to
495*61c4878aSAndroid Build Coastguard Worker   count values matching a condition within a container.
496*61c4878aSAndroid Build Coastguard Worker
497*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::Mismatch()
498*61c4878aSAndroid Build Coastguard Worker
499*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::mismatch()`` function to
500*61c4878aSAndroid Build Coastguard Worker   return the first element where two ordered containers differ. Applies ``==``
501*61c4878aSAndroid Build Coastguard Worker   to the first ``N`` elements of ``c1`` and ``c2``, where
502*61c4878aSAndroid Build Coastguard Worker   ``N = min(size(c1), size(c2)).`` the function's test condition. Applies
503*61c4878aSAndroid Build Coastguard Worker   ``pred`` to the first N elements of ``c1``  and ``c2``, where
504*61c4878aSAndroid Build Coastguard Worker   ``N = min(size(c1), size(c2))``.
505*61c4878aSAndroid Build Coastguard Worker
506*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: bool pw::containers::Equal()
507*61c4878aSAndroid Build Coastguard Worker
508*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::equal()`` function to
509*61c4878aSAndroid Build Coastguard Worker   test whether two containers are equal.
510*61c4878aSAndroid Build Coastguard Worker
511*61c4878aSAndroid Build Coastguard Worker   .. note::
512*61c4878aSAndroid Build Coastguard Worker
513*61c4878aSAndroid Build Coastguard Worker      The semantics of ``Equal()`` are slightly different than those of
514*61c4878aSAndroid Build Coastguard Worker      ``std::equal()``: while the latter iterates over the second container only
515*61c4878aSAndroid Build Coastguard Worker      up to the size of the first container, ``Equal()`` also checks whether the
516*61c4878aSAndroid Build Coastguard Worker      container sizes are equal.  This better matches expectations about
517*61c4878aSAndroid Build Coastguard Worker      ``Equal()`` based on its signature.
518*61c4878aSAndroid Build Coastguard Worker
519*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: bool pw::containers::IsPermutation()
520*61c4878aSAndroid Build Coastguard Worker
521*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::is_permutation()`` function
522*61c4878aSAndroid Build Coastguard Worker   to test whether a container is a permutation of another.
523*61c4878aSAndroid Build Coastguard Worker
524*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::Search()
525*61c4878aSAndroid Build Coastguard Worker
526*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::search()`` function to
527*61c4878aSAndroid Build Coastguard Worker   search a container for a subsequence.
528*61c4878aSAndroid Build Coastguard Worker
529*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: pw::containers::SearchN()
530*61c4878aSAndroid Build Coastguard Worker
531*61c4878aSAndroid Build Coastguard Worker   Container-based version of the <algorithm> ``std::search_n()`` function to
532*61c4878aSAndroid Build Coastguard Worker   search a container for the first sequence of N elements.
533*61c4878aSAndroid Build Coastguard Worker
534*61c4878aSAndroid Build Coastguard Worker-------------
535*61c4878aSAndroid Build Coastguard WorkerCompatibility
536*61c4878aSAndroid Build Coastguard Worker-------------
537*61c4878aSAndroid Build Coastguard Worker- C++17
538*61c4878aSAndroid Build Coastguard Worker
539*61c4878aSAndroid Build Coastguard Worker------
540*61c4878aSAndroid Build Coastguard WorkerZephyr
541*61c4878aSAndroid Build Coastguard Worker------
542*61c4878aSAndroid Build Coastguard WorkerTo enable ``pw_containers`` for Zephyr add ``CONFIG_PIGWEED_CONTAINERS=y`` to
543*61c4878aSAndroid Build Coastguard Workerthe project's configuration.
544