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>
94 containers::internal::kGenericSized> {
95 private:
96 using Base =
98
99 public:
100 using value_type = typename Base::value_type;
101 using const_value_type = typename Base::const_value_type;
102 using size_type = typename Base::size_type;
103 using pointer = typename Base::pointer;
104 using const_pointer = typename Base::const_pointer;
105 using reference = typename Base::reference;
106 using const_reference = typename Base::const_reference;
107
109 : array_{PW_VAR_QUEUE_DATA_SIZE_BYTES(kMaxSizeBytes), 0, 0} {}
110
111 // Explicit zero element constexpr constructor. Using this constructor will
112 // place the entire object in .data, which will increase ROM size. Use with
113 // caution if working with large capacity sizes.
115 : array_{PW_VAR_QUEUE_DATA_SIZE_BYTES(kMaxSizeBytes), 0, 0} {}
116
118 *this = other;
119 }
121 *this = std::move(other);
122 }
124 const BasicInlineVarLenEntryQueue<T>& other);
127
128 private:
129 template <typename, size_t>
130 friend class BasicInlineVarLenEntryQueue;
131
132 constexpr span<uint32_t> array() { return array_; }
133 constexpr span<const uint32_t> array() const { return array_; }
134
135 // This class does not derive from RawStorage in order to allow this array to
136 // be initialized as a constant expression.
137 std::array<uint32_t, _PW_VAR_QUEUE_SIZE_UINT32(kMaxSizeBytes)> array_;
138};
139
142
145
153template <typename T>
154class BasicInlineVarLenEntryQueue<T, containers::internal::kGenericSized>
155 : public containers::internal::GenericVarLenEntryQueue<
156 BasicInlineVarLenEntryQueue<T, containers::internal::kGenericSized>,
157 T> {
158 private:
159 using Base = containers::internal::GenericVarLenEntryQueue<
161 T>;
162
163 public:
164 using value_type = containers::internal::VarLenEntry<T>;
165 using const_value_type = containers::internal::VarLenEntry<const T>;
166 using size_type = std::uint32_t;
167 using pointer = const value_type*;
168 using const_pointer = pointer;
169 using reference = const value_type&;
170 using const_reference = reference;
171
175 template <size_t kArraySize>
176 static BasicInlineVarLenEntryQueue& Init(uint32_t (&array)[kArraySize]);
177 static BasicInlineVarLenEntryQueue& Init(uint32_t array[],
178 size_t array_size_uint32);
179
183
184 protected:
185 constexpr BasicInlineVarLenEntryQueue() = default;
187
188 private:
189 static constexpr size_t kNumFields = 3;
190 static constexpr size_t kBufferSize = 0;
191 static constexpr size_t kHead = 1;
192 static constexpr size_t kTail = 2;
193
194 // GenericVarLenEntryQueue uses CRTP to encapsulate
195 template <typename, typename>
196 friend class containers::internal::GenericVarLenEntryQueue;
197
198 size_t buffer_size() const { return array()[kBufferSize]; }
199
200 size_t head() const { return array()[kHead]; }
201 void set_head(size_t head) { array()[kHead] = static_cast<uint32_t>(head); }
202
203 size_t tail() const { return array()[kTail]; }
204 void set_tail(size_t tail) { array()[kTail] = static_cast<uint32_t>(tail); }
205
206 span<T> buffer() {
207 return span<T>(reinterpret_cast<T*>(array().subspan(kNumFields).data()),
208 buffer_size());
209 }
210
211 span<const T> buffer() const {
212 return span<const T>(
213 reinterpret_cast<const T*>(array().subspan(kNumFields).data()),
214 buffer_size());
215 }
216
217 // The underlying data is not part of the generic-length queue class. It is
218 // provided in the derived class from which this instance was constructed. To
219 // access the data, downcast this to a BasicInlineVarLenEntryQueue with a
220 // known max size, and return a pointer to the start of the array, which is
221 // the same for all queues with explicit max size.
222 span<uint32_t> array() {
223 return static_cast<BasicInlineVarLenEntryQueue<T, 0>*>(this)->array();
224 }
225 span<const uint32_t> array() const {
226 return static_cast<const BasicInlineVarLenEntryQueue<T, 0>*>(this)->array();
227 }
228};
229
231template <size_t kMaxSizeBytes = containers::internal::kGenericSized>
234
236// Template method implementation.
237
238// BasicInlineVarLenEntryQueue<T, kMaxSizeBytes> methods.
239
240template <typename T, size_t kMaxSizeBytes>
243 const BasicInlineVarLenEntryQueue<T>& other) {
244 PW_ASSERT(this->GetBufferSize() >= other.GetBufferSize());
245 size_t array_size =
246 (sizeof(uint32_t) *
248 other.GetBufferSize();
249 std::memcpy(this->array(), other.array(), array_size);
250 return *this;
251}
252
253template <typename T, size_t kMaxSizeBytes>
254BasicInlineVarLenEntryQueue<T, kMaxSizeBytes>&
255BasicInlineVarLenEntryQueue<T, kMaxSizeBytes>::operator=(
256 BasicInlineVarLenEntryQueue<T>&& other) {
257 *this = other;
258 other.clear();
259 return *this;
260}
261
262// BasicInlineVarLenEntryQueue<T> methods.
263
264template <typename T>
265template <size_t kArraySize>
266BasicInlineVarLenEntryQueue<T>& BasicInlineVarLenEntryQueue<T>::Init(
267 uint32_t (&array)[kArraySize]) {
268 static_assert(
270 "InlineVarLenEntryQueue must be backed by an array with more than "
271 "PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32 (3) elements");
272 return Init(array, kArraySize);
273}
274
275template <typename T>
276BasicInlineVarLenEntryQueue<T>& BasicInlineVarLenEntryQueue<T>::Init(
277 uint32_t array[], size_t array_size_uint32) {
278 auto array_size = static_cast<uint32_t>(array_size_uint32);
280 array[0] = array_size * sizeof(uint32_t);
281 array[1] = 0; // head
282 array[2] = 0; // tail
283 return *(std::launder(reinterpret_cast<BasicInlineVarLenEntryQueue*>(array)));
284}
285
286template <typename T>
287span<const T> BasicInlineVarLenEntryQueue<T>::raw_storage() const {
288 size_t raw_size = (kNumFields * sizeof(uint32_t)) + buffer_size();
289 return span<const T>(reinterpret_cast<const T*>(array().data()), raw_size);
290}
291
292} // namespace pw
293
294#define _PW_VAR_QUEUE_CHECK_SIZE(max_size_bytes) \
295 static_assert(sizeof(pw::InlineVarLenEntryQueue<max_size_bytes>) == \
296 _PW_VAR_QUEUE_SIZE_UINT32(max_size_bytes) * sizeof(uint32_t));
297
298#else // !defined(__cplusplus)
299
300#define _PW_VAR_QUEUE_CHECK_SIZE(max_size_bytes)
301
302#endif // __cplusplus
303
304PW_EXTERN_C_START
305
308
318#define PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(variable, max_size_bytes) \
319 _PW_VAR_QUEUE_CHECK_SIZE(max_size_bytes) \
320 uint32_t variable[_PW_VAR_QUEUE_SIZE_UINT32(max_size_bytes)] = { \
321 PW_VAR_QUEUE_DATA_SIZE_BYTES(max_size_bytes), /*head=*/0u, /*tail=*/0u}
322
323typedef uint32_t* pw_InlineVarLenEntryQueue_Handle;
324typedef const uint32_t* pw_InlineVarLenEntryQueue_ConstHandle;
325
327void pw_InlineVarLenEntryQueue_Init(uint32_t array[], size_t array_size_uint32);
328
330pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_Begin(
331 pw_InlineVarLenEntryQueue_Handle queue);
332
334pw_InlineVarLenEntryQueue_ConstIterator pw_InlineVarLenEntryQueue_ConstBegin(
335 pw_InlineVarLenEntryQueue_ConstHandle queue);
336
338pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_End(
339 pw_InlineVarLenEntryQueue_Handle queue);
340
342pw_InlineVarLenEntryQueue_ConstIterator pw_InlineVarLenEntryQueue_ConstEnd(
343 pw_InlineVarLenEntryQueue_ConstHandle queue);
344
347 pw_InlineVarLenEntryQueue_ConstHandle queue);
348
351 pw_InlineVarLenEntryQueue_ConstHandle queue);
352
355 pw_InlineVarLenEntryQueue_ConstHandle queue);
356
359 pw_InlineVarLenEntryQueue_ConstHandle queue);
360
363 pw_InlineVarLenEntryQueue_ConstHandle queue);
364
366void pw_InlineVarLenEntryQueue_Push(pw_InlineVarLenEntryQueue_Handle queue,
367 const void* data,
368 uint32_t data_size_bytes);
369
371bool pw_InlineVarLenEntryQueue_TryPush(pw_InlineVarLenEntryQueue_Handle queue,
372 const void* data,
373 const uint32_t data_size_bytes);
374
377 pw_InlineVarLenEntryQueue_Handle queue,
378 const void* data,
379 uint32_t data_size_bytes);
380
382void pw_InlineVarLenEntryQueue_Pop(pw_InlineVarLenEntryQueue_Handle queue);
383
385void pw_InlineVarLenEntryQueue_Clear(pw_InlineVarLenEntryQueue_Handle queue);
386
389 pw_InlineVarLenEntryQueue_ConstHandle queue);
390
393 pw_InlineVarLenEntryQueue_ConstHandle from,
394 pw_InlineVarLenEntryQueue_Handle to);
395
398 pw_InlineVarLenEntryQueue_ConstHandle from,
399 pw_InlineVarLenEntryQueue_Handle to);
400
403 pw_InlineVarLenEntryQueue_Handle from, pw_InlineVarLenEntryQueue_Handle to);
404
407 pw_InlineVarLenEntryQueue_Handle from, pw_InlineVarLenEntryQueue_Handle to);
408
410
411PW_EXTERN_C_END
412
Definition: inline_var_len_entry_queue.h:157
Definition: inline_var_len_entry_queue.h:94
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)
uint32_t pw_InlineVarLenEntryQueue_MaxSize(pw_InlineVarLenEntryQueue_ConstHandle queue)
bool pw_InlineVarLenEntryQueue_Empty(pw_InlineVarLenEntryQueue_ConstHandle queue)
pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_End(pw_InlineVarLenEntryQueue_Handle queue)
pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_Begin(pw_InlineVarLenEntryQueue_Handle 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