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/var_len_entry_queue_iterator.h"
49#include "pw_preprocessor/util.h"
50
51#ifndef __cplusplus
52
53#include <stdbool.h>
54#include <stddef.h>
55#include <stdint.h>
56
57#else // __cplusplus
58
59#include <cstddef>
60#include <cstdint>
61
62#include "pw_bytes/span.h"
63#include "pw_containers/internal/generic_var_len_entry_queue.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_UINT32(max_size_bytes))
82
83#define _PW_VAR_QUEUE_DATA_SIZE_UINT32(max_size_bytes) \
84 ((_PW_VAR_QUEUE_DATA_SIZE_BYTES(max_size_bytes) + 3 /* round up */) / 4)
85
86#define _PW_VAR_QUEUE_DATA_SIZE_BYTES(max_size_bytes) \
87 (PW_VARINT_ENCODED_SIZE_BYTES(max_size_bytes) + max_size_bytes + \
88 1 /*end byte*/)
89
90#ifdef __cplusplus
91namespace pw {
92
93// A`BasicInlineVarLenEntryQueue` with a known maximum size of a single entry.
94// The member functions are immplemented in the generic-capacity base.
95// TODO: b/303056683 - Add helper for calculating kMaxSizeBytes for N entries of
96// a particular size.
97template <typename T,
98 size_t kMaxSizeBytes = containers::internal::kGenericSized>
101 containers::internal::kGenericSized> {
102 private:
103 using Base =
105
106 public:
107 using value_type = typename Base::value_type;
108 using const_value_type = typename Base::const_value_type;
109 using size_type = typename Base::size_type;
110 using pointer = typename Base::pointer;
111 using const_pointer = typename Base::const_pointer;
112 using reference = typename Base::reference;
113 using const_reference = typename Base::const_reference;
114
116 : array_{_PW_VAR_QUEUE_DATA_SIZE_BYTES(kMaxSizeBytes), 0, 0} {}
117
118 // Explicit zero element constexpr constructor. Using this constructor will
119 // place the entire object in .data, which will increase ROM size. Use with
120 // caution if working with large capacity sizes.
122 : array_{_PW_VAR_QUEUE_DATA_SIZE_BYTES(kMaxSizeBytes), 0, 0} {}
123
125 *this = other;
126 }
128 *this = std::move(other);
129 }
131 const BasicInlineVarLenEntryQueue<T>& other);
134
135 private:
136 template <typename, size_t>
137 friend class BasicInlineVarLenEntryQueue;
138
139 constexpr span<uint32_t> array() { return array_; }
140 constexpr span<const uint32_t> array() const { return array_; }
141
142 // This class does not derive from RawStorage in order to allow this array to
143 // be initialized as a constant expression.
144 std::array<uint32_t, _PW_VAR_QUEUE_SIZE_UINT32(kMaxSizeBytes)> array_;
145};
146
149
152
160template <typename T>
161class BasicInlineVarLenEntryQueue<T, containers::internal::kGenericSized>
162 : public containers::internal::GenericVarLenEntryQueue<
163 BasicInlineVarLenEntryQueue<T, containers::internal::kGenericSized>,
164 T> {
165 private:
166 using Base = containers::internal::GenericVarLenEntryQueue<
168 T>;
169
170 public:
171 using value_type = containers::internal::VarLenEntry<T>;
172 using const_value_type = containers::internal::VarLenEntry<const T>;
173 using size_type = std::uint32_t;
174 using pointer = const value_type*;
175 using const_pointer = pointer;
176 using reference = const value_type&;
177 using const_reference = reference;
178
182 template <size_t kArraySize>
183 static BasicInlineVarLenEntryQueue& Init(uint32_t (&array)[kArraySize]);
184 static BasicInlineVarLenEntryQueue& Init(uint32_t array[],
185 size_t array_size_uint32);
186
190
191 protected:
192 constexpr BasicInlineVarLenEntryQueue() = default;
194
195 uint32_t buffer_size() const { return array()[kBufferSize]; }
196
197 uint32_t head() const { return array()[kHead]; }
198 void set_head(uint32_t head) { array()[kHead] = head; }
199
200 uint32_t tail() const { return array()[kTail]; }
201 void set_tail(uint32_t tail) { array()[kTail] = tail; }
202
203 span<T> buffer() {
204 return span<T>(reinterpret_cast<T*>(array().subspan(kNumFields).data()),
205 buffer_size());
206 }
207
208 span<const T> buffer() const {
209 return span<const T>(
210 reinterpret_cast<const T*>(array().subspan(kNumFields).data()),
211 buffer_size());
212 }
213
214 private:
215 static constexpr size_t kNumFields = 3;
216 static constexpr size_t kBufferSize = 0;
217 static constexpr size_t kHead = 1;
218 static constexpr size_t kTail = 2;
219
220 template <typename, typename>
221 friend class containers::internal::GenericVarLenEntryQueue;
222
223 // The underlying data is not part of the generic-length queue class. It is
224 // provided in the derived class from which this instance was constructed. To
225 // access the data, downcast this to a BasicInlineVarLenEntryQueue with a
226 // known max size, and return a pointer to the start of the array, which is
227 // the same for all queues with explicit max size.
228 span<uint32_t> array() {
229 return static_cast<BasicInlineVarLenEntryQueue<T, 0>*>(this)->array();
230 }
231 span<const uint32_t> array() const {
232 return static_cast<const BasicInlineVarLenEntryQueue<T, 0>*>(this)->array();
233 }
234};
235
237template <size_t kMaxSizeBytes = containers::internal::kGenericSized>
240
242// Template method implementation.
243
244// BasicInlineVarLenEntryQueue<T, kMaxSizeBytes> methods.
245
246template <typename T, size_t kMaxSizeBytes>
249 const BasicInlineVarLenEntryQueue<T>& other) {
250 PW_ASSERT(this->GetBufferSize() >= other.GetBufferSize());
251 size_t array_size =
252 (sizeof(uint32_t) *
254 other.GetBufferSize();
255 std::memcpy(this->array(), other.array(), array_size);
256 return *this;
257}
258
259template <typename T, size_t kMaxSizeBytes>
260BasicInlineVarLenEntryQueue<T, kMaxSizeBytes>&
261BasicInlineVarLenEntryQueue<T, kMaxSizeBytes>::operator=(
262 BasicInlineVarLenEntryQueue<T>&& other) {
263 *this = other;
264 other.clear();
265 return *this;
266}
267
268// BasicInlineVarLenEntryQueue<T> methods.
269
270template <typename T>
271template <size_t kArraySize>
272BasicInlineVarLenEntryQueue<T>& BasicInlineVarLenEntryQueue<T>::Init(
273 uint32_t (&array)[kArraySize]) {
274 static_assert(
276 "InlineVarLenEntryQueue must be backed by an array with more than "
277 "PW_VARIABLE_LENGTH_ENTRY_QUEUE_HEADER_SIZE_UINT32 (3) elements");
278 return Init(array, kArraySize);
279}
280
281template <typename T>
282BasicInlineVarLenEntryQueue<T>& BasicInlineVarLenEntryQueue<T>::Init(
283 uint32_t array[], size_t array_size_uint32) {
284 auto array_size = static_cast<uint32_t>(array_size_uint32);
286 array[0] = array_size * sizeof(uint32_t);
287 array[1] = 0; // head
288 array[2] = 0; // tail
289 return *(std::launder(reinterpret_cast<BasicInlineVarLenEntryQueue*>(array)));
290}
291
292template <typename T>
293span<const T> BasicInlineVarLenEntryQueue<T>::raw_storage() const {
294 size_t raw_size = (kNumFields * sizeof(uint32_t)) + buffer_size();
295 return span<const T>(reinterpret_cast<const T*>(array().data()), raw_size);
296}
297
298} // namespace pw
299
300#define _PW_VAR_QUEUE_CHECK_SIZE(max_size_bytes) \
301 static_assert(sizeof(pw::InlineVarLenEntryQueue<max_size_bytes>) == \
302 _PW_VAR_QUEUE_SIZE_UINT32(max_size_bytes) * sizeof(uint32_t));
303
304#else // !defined(__cplusplus)
305
306#define _PW_VAR_QUEUE_CHECK_SIZE(max_size_bytes)
307
308#endif // __cplusplus
309
310PW_EXTERN_C_START
311
314
324#define PW_VARIABLE_LENGTH_ENTRY_QUEUE_DECLARE(variable, max_size_bytes) \
325 _PW_VAR_QUEUE_CHECK_SIZE(max_size_bytes) \
326 uint32_t variable[_PW_VAR_QUEUE_SIZE_UINT32(max_size_bytes)] = { \
327 _PW_VAR_QUEUE_DATA_SIZE_BYTES(max_size_bytes), /*head=*/0u, /*tail=*/0u}
328
329typedef uint32_t* pw_InlineVarLenEntryQueue_Handle;
330typedef const uint32_t* pw_InlineVarLenEntryQueue_ConstHandle;
331
333void pw_InlineVarLenEntryQueue_Init(uint32_t array[], size_t array_size_uint32);
334
336pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_Begin(
337 pw_InlineVarLenEntryQueue_Handle queue);
338
340pw_InlineVarLenEntryQueue_ConstIterator pw_InlineVarLenEntryQueue_ConstBegin(
341 pw_InlineVarLenEntryQueue_ConstHandle queue);
342
344pw_InlineVarLenEntryQueue_Iterator pw_InlineVarLenEntryQueue_End(
345 pw_InlineVarLenEntryQueue_Handle queue);
346
348pw_InlineVarLenEntryQueue_ConstIterator pw_InlineVarLenEntryQueue_ConstEnd(
349 pw_InlineVarLenEntryQueue_ConstHandle queue);
350
353 pw_InlineVarLenEntryQueue_ConstHandle queue);
354
357 pw_InlineVarLenEntryQueue_ConstHandle queue);
358
361 pw_InlineVarLenEntryQueue_ConstHandle queue);
362
365 pw_InlineVarLenEntryQueue_ConstHandle queue);
366
369 pw_InlineVarLenEntryQueue_ConstHandle queue);
370
372void pw_InlineVarLenEntryQueue_Push(pw_InlineVarLenEntryQueue_Handle queue,
373 const void* data,
374 uint32_t data_size_bytes);
375
377bool pw_InlineVarLenEntryQueue_TryPush(pw_InlineVarLenEntryQueue_Handle queue,
378 const void* data,
379 const uint32_t data_size_bytes);
380
383 pw_InlineVarLenEntryQueue_Handle queue,
384 const void* data,
385 uint32_t data_size_bytes);
386
388void pw_InlineVarLenEntryQueue_Pop(pw_InlineVarLenEntryQueue_Handle queue);
389
391void pw_InlineVarLenEntryQueue_Clear(pw_InlineVarLenEntryQueue_Handle queue);
392
395 pw_InlineVarLenEntryQueue_ConstHandle queue);
396
399 pw_InlineVarLenEntryQueue_ConstHandle from,
400 pw_InlineVarLenEntryQueue_Handle to);
401
404 pw_InlineVarLenEntryQueue_ConstHandle from,
405 pw_InlineVarLenEntryQueue_Handle to);
406
409 pw_InlineVarLenEntryQueue_Handle from, pw_InlineVarLenEntryQueue_Handle to);
410
413 pw_InlineVarLenEntryQueue_Handle from, pw_InlineVarLenEntryQueue_Handle to);
414
416
417PW_EXTERN_C_END
418
Definition: inline_var_len_entry_queue.h:164
Definition: inline_var_len_entry_queue.h:101
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