C/C++ API Reference
Loading...
Searching...
No Matches
inline_var_len_entry_queue.h
Go to the documentation of this file.
1// Copyright 2023 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16// TODO: https://pwbug.dev/426012010 - Find a way to single-source this
17// content on the Sphinx site without Breathe.
18
47
48#include "pw_containers/internal/generic_var_len_entry_queue.h"
49#include "pw_containers/internal/var_len_entry_queue_iterator.h"
50#include "pw_preprocessor/util.h"
51
52#ifndef __cplusplus
53
54#include <stdbool.h>
55#include <stddef.h>
56#include <stdint.h>
57
58#else // __cplusplus
59
60#include <cstddef>
61#include <cstdint>
62
63#include "pw_bytes/span.h"
64#include "pw_containers/internal/raw_storage.h"
65#include "pw_span/span.h"
66#include "pw_toolchain/constexpr_tag.h"
67
68#endif // __cplusplus
69
71
77#define PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32 (3)
78
79#define _PW_VAR_QUEUE_SIZE_UINT32(max_size_bytes) \
80 (PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32 + \
81 ((PW_VAR_QUEUE_DATA_SIZE_BYTES(max_size_bytes) + 3 /* round up */) / 4))
82
83#ifdef __cplusplus
84namespace pw {
85
86// A`BasicInlineVarLenEntryQueue` with a known maximum size of a single entry.
87// The member functions are immplemented in the generic-capacity base.
88// TODO: b/303056683 - Add helper for calculating kMaxSizeBytes for N entries of
89// a particular size.
90template <typename T,
91 size_t kMaxSizeBytes = containers::internal::kGenericSized>
93 // TODO: b/513051956 - Fix `recursive class relation` error
95 : public BasicInlineVarLenEntryQueue<T, containers::internal::kGenericSized>
97{
98 private:
99 using Base =
101
102 public:
103 using value_type = typename Base::value_type;
104 using const_value_type = typename Base::const_value_type;
105 using size_type = typename Base::size_type;
106 using pointer = typename Base::pointer;
107 using const_pointer = typename Base::const_pointer;
108 using reference = typename Base::reference;
109 using const_reference = typename Base::const_reference;
110
112 : array_{PW_VAR_QUEUE_DATA_SIZE_BYTES(kMaxSizeBytes), 0, 0} {}
113
114 // Explicit zero element constexpr constructor. Using this constructor will
115 // place the entire object in .data, which will increase ROM size. Use with
116 // caution if working with large capacity sizes.
118 : array_{PW_VAR_QUEUE_DATA_SIZE_BYTES(kMaxSizeBytes), 0, 0} {}
119
121 *this = other;
122 }
124 *this = std::move(other);
125 }
127 const BasicInlineVarLenEntryQueue<T>& other);
130
131 private:
132 template <typename, size_t>
133 friend class BasicInlineVarLenEntryQueue;
134
135 constexpr span<uint32_t> array() { return array_; }
136 constexpr span<const uint32_t> array() const { return array_; }
137
138 // This class does not derive from RawStorage in order to allow this array to
139 // be initialized as a constant expression.
140 std::array<uint32_t, _PW_VAR_QUEUE_SIZE_UINT32(kMaxSizeBytes)> array_;
141};
142
145
148
156template <typename T>
157class BasicInlineVarLenEntryQueue<T, containers::internal::kGenericSized>
159 BasicInlineVarLenEntryQueue<T, containers::internal::kGenericSized>,
160 T> {
161 private:
164 T>;
165
166 public:
169 using size_type = std::uint32_t;
170 using pointer = const value_type*;
171 using const_pointer = pointer;
172 using reference = const value_type&;
174
178 template <size_t kArraySize>
179 static BasicInlineVarLenEntryQueue& Init(uint32_t (&array)[kArraySize]);
180 static BasicInlineVarLenEntryQueue& Init(uint32_t array[],
181 size_t array_size_uint32);
182
186
187 protected:
188 constexpr BasicInlineVarLenEntryQueue() = default;
190
191 private:
192 static constexpr size_t kNumFields = 3;
193 static constexpr size_t kBufferSize = 0;
194 static constexpr size_t kHead = 1;
195 static constexpr size_t kTail = 2;
196
197 // GenericVarLenEntryQueue uses CRTP to encapsulate
198 template <typename, typename>
200
201 size_t buffer_size() const { return array()[kBufferSize]; }
202
203 size_t head() const { return array()[kHead]; }
204 void set_head(size_t head) { array()[kHead] = static_cast<uint32_t>(head); }
205
206 size_t tail() const { return array()[kTail]; }
207 void set_tail(size_t tail) { array()[kTail] = static_cast<uint32_t>(tail); }
208
209 span<T> buffer() {
210 return span<T>(reinterpret_cast<T*>(array().subspan(kNumFields).data()),
211 buffer_size());
212 }
213
214 span<const T> buffer() const {
215 return span<const T>(
216 reinterpret_cast<const T*>(array().subspan(kNumFields).data()),
217 buffer_size());
218 }
219
220 // The underlying data is not part of the generic-length queue class. It is
221 // provided in the derived class from which this instance was constructed. To
222 // access the data, downcast this to a BasicInlineVarLenEntryQueue with a
223 // known max size, and return a pointer to the start of the array, which is
224 // the same for all queues with explicit max size.
225 span<uint32_t> array() {
226 return static_cast<BasicInlineVarLenEntryQueue<T, 0>*>(this)->array();
227 }
228 span<const uint32_t> array() const {
229 return static_cast<const BasicInlineVarLenEntryQueue<T, 0>*>(this)->array();
230 }
231};
232
234template <size_t kMaxSizeBytes = containers::internal::kGenericSized>
237
239// Template method implementation.
240
241// BasicInlineVarLenEntryQueue<T, kMaxSizeBytes> methods.
242
243template <typename T, size_t kMaxSizeBytes>
246 const BasicInlineVarLenEntryQueue<T>& other) {
247 PW_ASSERT(this->GetBufferSize() >= other.GetBufferSize());
248 size_t array_size =
249 (sizeof(uint32_t) *
251 other.GetBufferSize();
252 std::memcpy(this->array(), other.array(), array_size);
253 return *this;
254}
255
256template <typename T, size_t kMaxSizeBytes>
257BasicInlineVarLenEntryQueue<T, kMaxSizeBytes>&
258BasicInlineVarLenEntryQueue<T, kMaxSizeBytes>::operator=(
259 BasicInlineVarLenEntryQueue<T>&& other) {
260 *this = other;
261 other.clear();
262 return *this;
263}
264
265// BasicInlineVarLenEntryQueue<T> methods.
266
268template <typename T>
269template <size_t kArraySize>
270BasicInlineVarLenEntryQueue<T>& BasicInlineVarLenEntryQueue<T>::Init(
271 uint32_t (&array)[kArraySize]) {
272 static_assert(
274 "InlineVarLenEntryQueue must be backed by an array with more than "
275 "PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32 (3) elements");
276 return Init(array, kArraySize);
277}
278
279template <typename T>
280BasicInlineVarLenEntryQueue<T>& BasicInlineVarLenEntryQueue<T>::Init(
281 uint32_t array[], size_t array_size_uint32) {
282 auto array_size = static_cast<uint32_t>(array_size_uint32);
284 array[0] = array_size * sizeof(uint32_t);
285 array[1] = 0; // head
286 array[2] = 0; // tail
287 return *(std::launder(reinterpret_cast<BasicInlineVarLenEntryQueue*>(array)));
288}
289
290template <typename T>
291span<const T> BasicInlineVarLenEntryQueue<T>::raw_storage() const {
292 size_t raw_size = (kNumFields * sizeof(uint32_t)) + buffer_size();
293 return span<const T>(reinterpret_cast<const T*>(array().data()), raw_size);
294}
296
297} // namespace pw
298
299#define _PW_VAR_QUEUE_CHECK_SIZE(max_size_bytes) \
300 static_assert(sizeof(pw::InlineVarLenEntryQueue<max_size_bytes>) == \
301 _PW_VAR_QUEUE_SIZE_UINT32(max_size_bytes) * sizeof(uint32_t));
302
303#else // !defined(__cplusplus)
304
305#define _PW_VAR_QUEUE_CHECK_SIZE(max_size_bytes)
306
307#endif // __cplusplus
308
309PW_EXTERN_C_START
310
313
323#define PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(variable, max_size_bytes) \
324 _PW_VAR_QUEUE_CHECK_SIZE(max_size_bytes) \
325 uint32_t variable[_PW_VAR_QUEUE_SIZE_UINT32(max_size_bytes)] = { \
326 PW_VAR_QUEUE_DATA_SIZE_BYTES(max_size_bytes), /*head=*/0u, /*tail=*/0u}
327
328typedef uint32_t* pw_InlineVarLenEntryQueue_Handle;
329typedef const uint32_t* pw_InlineVarLenEntryQueue_ConstHandle;
330
334void pw_InlineVarLenEntryQueue_Init(uint32_t array[], size_t array_size_uint32);
335
338 pw_InlineVarLenEntryQueue_Handle queue);
339
342 pw_InlineVarLenEntryQueue_ConstHandle queue);
343
346 pw_InlineVarLenEntryQueue_Handle queue);
347
350 pw_InlineVarLenEntryQueue_ConstHandle queue);
351
354 pw_InlineVarLenEntryQueue_ConstHandle queue);
355
358 pw_InlineVarLenEntryQueue_ConstHandle queue);
359
362 pw_InlineVarLenEntryQueue_ConstHandle queue);
363
366 pw_InlineVarLenEntryQueue_ConstHandle queue);
367
370 pw_InlineVarLenEntryQueue_ConstHandle queue);
371
373void pw_InlineVarLenEntryQueue_Push(pw_InlineVarLenEntryQueue_Handle queue,
374 const void* data,
375 uint32_t data_size_bytes);
376
378bool pw_InlineVarLenEntryQueue_TryPush(pw_InlineVarLenEntryQueue_Handle queue,
379 const void* data,
380 const uint32_t data_size_bytes);
381
384 pw_InlineVarLenEntryQueue_Handle queue,
385 const void* data,
386 uint32_t data_size_bytes);
387
389void pw_InlineVarLenEntryQueue_Pop(pw_InlineVarLenEntryQueue_Handle queue);
390
392void pw_InlineVarLenEntryQueue_Clear(pw_InlineVarLenEntryQueue_Handle queue);
393
397 pw_InlineVarLenEntryQueue_ConstHandle queue);
398
401 pw_InlineVarLenEntryQueue_ConstHandle from,
402 pw_InlineVarLenEntryQueue_Handle to);
403
406 pw_InlineVarLenEntryQueue_ConstHandle from,
407 pw_InlineVarLenEntryQueue_Handle to);
408
411 pw_InlineVarLenEntryQueue_Handle from, pw_InlineVarLenEntryQueue_Handle to);
412
415 pw_InlineVarLenEntryQueue_Handle from, pw_InlineVarLenEntryQueue_Handle to);
416
418
419PW_EXTERN_C_END
420
Definition: inline_var_len_entry_queue.h:160
Definition: inline_var_len_entry_queue.h:97
Definition: generic_var_len_entry_queue.h:139
Refers to an entry in-place in the queue. Entries may be discontiguous.
Definition: var_len_entry.h:65
Definition: span_impl.h:235
void pw_InlineVarLenEntryQueue_Push(pw_InlineVarLenEntryQueue_Handle queue, const void *data, uint32_t data_size_bytes)
bool pw_InlineVarLenEntryQueue_TryPush(pw_InlineVarLenEntryQueue_Handle queue, const void *data, const uint32_t data_size_bytes)
void pw_InlineVarLenEntryQueue_CopyEntriesOverwrite(pw_InlineVarLenEntryQueue_ConstHandle from, pw_InlineVarLenEntryQueue_Handle to)
void pw_InlineVarLenEntryQueue_MoveEntries(pw_InlineVarLenEntryQueue_Handle from, pw_InlineVarLenEntryQueue_Handle to)
uint32_t pw_InlineVarLenEntryQueue_Size(pw_InlineVarLenEntryQueue_ConstHandle queue)
void pw_InlineVarLenEntryQueue_CopyEntries(pw_InlineVarLenEntryQueue_ConstHandle from, pw_InlineVarLenEntryQueue_Handle to)
void pw_InlineVarLenEntryQueue_Init(uint32_t array[], size_t array_size_uint32)
uint32_t pw_InlineVarLenEntryQueue_RawStorageSizeBytes(pw_InlineVarLenEntryQueue_ConstHandle queue)
void pw_InlineVarLenEntryQueue_PushOverwrite(pw_InlineVarLenEntryQueue_Handle queue, const void *data, uint32_t data_size_bytes)
void pw_InlineVarLenEntryQueue_Pop(pw_InlineVarLenEntryQueue_Handle queue)
void pw_InlineVarLenEntryQueue_MoveEntriesOverwrite(pw_InlineVarLenEntryQueue_Handle from, pw_InlineVarLenEntryQueue_Handle to)
void pw_InlineVarLenEntryQueue_Clear(pw_InlineVarLenEntryQueue_Handle queue)
Empties the queue.
uint32_t pw_InlineVarLenEntryQueue_MaxSize(pw_InlineVarLenEntryQueue_ConstHandle queue)
bool pw_InlineVarLenEntryQueue_Empty(pw_InlineVarLenEntryQueue_ConstHandle queue)
Returns true if the queue is empty, false if it has at least one entry.
pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_End(pw_InlineVarLenEntryQueue_Handle queue)
Returns an iterator to the end of the queue.
pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_Begin(pw_InlineVarLenEntryQueue_Handle queue)
Returns an iterator to the start of the queue.
pw_InlineVarLenEntryQueue_ConstIterator pw_InlineVarLenEntryQueue_ConstBegin(pw_InlineVarLenEntryQueue_ConstHandle queue)
uint32_t pw_InlineVarLenEntryQueue_SizeBytes(pw_InlineVarLenEntryQueue_ConstHandle queue)
pw_InlineVarLenEntryQueue_ConstIterator pw_InlineVarLenEntryQueue_ConstEnd(pw_InlineVarLenEntryQueue_ConstHandle queue)
uint32_t pw_InlineVarLenEntryQueue_MaxSizeBytes(pw_InlineVarLenEntryQueue_ConstHandle queue)
span< const T > raw_storage() const
static BasicInlineVarLenEntryQueue & Init(uint32_t(&array)[kArraySize])
void Init()
#define PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32
Definition: inline_var_len_entry_queue.h:77
The Pigweed namespace.
Definition: alignment.h:27
Definition: constexpr_tag.h:48
Definition: var_len_entry_queue_iterator.h:172
Definition: var_len_entry_queue_iterator.h:166