C/C++ API Reference
Loading...
Searching...
No Matches
inline_async_deque.h
1// Copyright 2025 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#include <cstddef>
17#include <cstdint>
18
19#include "pw_async2/context.h"
20#include "pw_async2/poll.h"
21#include "pw_async2/try.h"
22#include "pw_containers/inline_deque.h"
23#include "pw_containers/internal/async_count_and_capacity.h"
24#include "pw_containers/internal/raw_storage.h"
25#include "pw_toolchain/constexpr_tag.h"
26
27namespace pw {
28
30
31// Forward declaration.
32template <typename T, typename SizeType, size_t kCapacity>
33class BasicInlineAsyncDeque;
34
42template <typename T, size_t kCapacity = containers::internal::kGenericSized>
44
56template <typename ValueType,
57 typename SizeType,
58 size_t kCapacity = containers::internal::kGenericSized>
60 : public containers::internal::RawStorage<
61 BasicInlineAsyncDeque<ValueType,
62 SizeType,
63 containers::internal::kGenericSized>,
64 ValueType,
65 kCapacity> {
66 private:
67 using Base = BasicInlineAsyncDeque<ValueType,
68 SizeType,
69 containers::internal::kGenericSized>;
70
71 public:
72 using typename Base::const_iterator;
73 using typename Base::const_pointer;
74 using typename Base::const_reference;
75 using typename Base::difference_type;
76 using typename Base::iterator;
77 using typename Base::pointer;
78 using typename Base::reference;
79 using typename Base::size_type;
80 using typename Base::value_type;
81
83 constexpr BasicInlineAsyncDeque() noexcept = default;
84
86 BasicInlineAsyncDeque(size_type count, const_reference value) {
87 Base::assign(count, value);
88 }
89
91 explicit BasicInlineAsyncDeque(size_type count)
92 : BasicInlineAsyncDeque(count, value_type()) {}
93
95 template <
96 typename InputIterator,
97 typename = containers::internal::EnableIfInputIterator<InputIterator>>
98 BasicInlineAsyncDeque(InputIterator start, InputIterator finish) {
99 Base::assign(start, finish);
100 }
101
103 BasicInlineAsyncDeque(const BasicInlineAsyncDeque& other) { *this = other; }
104
108 template <size_t kOtherCapacity>
111 *this = other;
112 }
113
116 *this = std::move(other);
117 }
118
120 template <size_t kOtherCapacity>
123 other) noexcept {
124 *this = std::move(other);
125 }
126
128 BasicInlineAsyncDeque(const std::initializer_list<value_type>& list) {
129 *this = list;
130 }
131
133 template <typename T, typename = containers::internal::EnableIfIterable<T>>
134 BasicInlineAsyncDeque(const T& other) {
135 *this = other;
136 }
137
138 // Assignment operators
139 //
140 // These operators delegate to the base class implementations in order to
141 // maximize code reuse. The wrappers are required so that `operator=`
142 // returns the correct type of reference.
143 //
144 // The `static_cast`s below are unfortunately necessary: without them,
145 // overload resolution prefers to use the "iterable" operators rather than
146 // upcast the RHS.
147
150 const std::initializer_list<value_type>& list) {
151 Base::operator=(list);
152 return *this;
153 }
154
157 Base::operator=(static_cast<const Base&>(other));
158 return *this;
159 }
160
164 template <size_t kOtherCapacity>
167 Base::operator=(static_cast<const Base&>(other));
168 return *this;
169 }
170
173 Base::operator=(static_cast<Base&&>(std::move(other)));
174 return *this;
175 }
176
178 template <size_t kOtherCapacity>
181 other) noexcept {
182 Base::operator=(static_cast<Base&&>(std::move(other)));
183 return *this;
184 }
185
186 // Size
187
188 static constexpr size_type max_size() { return capacity(); }
189 static constexpr size_type capacity() { return kCapacity; }
190
191 // Async
192 // Document these functions here since the template specialization base isn't
193 // included in Doxygen.
194
196 using Base::PendHasSpace;
197
199 using Base::PendNotEmpty;
200};
201
203
204// Defines the generic-sized BasicInlineAsyncDeque<T> specialization, which
205// serves as the base class for BasicInlineAsyncDeque<T> of any capacity.
206//
207// Except for constructors and destructors, all other methods should be
208// implemented on this generic-sized specialization.
209//
210// NOTE: this size-polymorphic base class must not be used inside of
211// ``std::unique_ptr`` or ``delete``.
212template <typename ValueType, typename SizeType>
213class BasicInlineAsyncDeque<ValueType,
214 SizeType,
215 containers::internal::kGenericSized>
217 ValueType,
218 containers::internal::AsyncCountAndCapacity<SizeType>,
219 containers::internal::kGenericSized> {
220 private:
222 ValueType,
224 containers::internal::kGenericSized>;
225
226 public:
227 using typename Base::const_iterator;
228 using typename Base::const_pointer;
229 using typename Base::const_reference;
230 using typename Base::difference_type;
231 using typename Base::iterator;
232 using typename Base::pointer;
233 using typename Base::reference;
234 using typename Base::size_type;
235 using typename Base::value_type;
236
238 Base::assign(other.begin(), other.end());
239 return *this;
240 }
241
243 Base::clear();
244 for (auto&& item : other) {
245 Base::emplace_back(std::move(item));
246 }
247 other.clear();
248 return *this;
249 }
250
251 using Base::operator=;
252
253 async2::Poll<> PendHasSpace(async2::Context& context, size_type num = 1) {
254 return Base::count_and_capacity().PendHasSpace(context, num);
255 }
256
258 return Base::count_and_capacity().PendNotEmpty(context);
259 }
260
261 protected:
262 constexpr BasicInlineAsyncDeque(size_type capacity) noexcept
263 : Base(capacity) {}
264
265 // Polymorphic-sized `InlineAsyncDeque` may not be used with `unique_ptr`
266 // or `delete`. `delete` could be supported using C++20's destroying delete.
267 ~BasicInlineAsyncDeque() = default;
268
269 private:
270 static constexpr bool kFixedCapacity = true; // uses static allocation
271};
272
273} // namespace pw
Definition: inline_async_deque.h:65
BasicInlineAsyncDeque(InputIterator start, InputIterator finish)
Copy constructs from an iterator.
Definition: inline_async_deque.h:98
BasicInlineAsyncDeque(const BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_async_deque.h:109
async2::Poll PendHasSpace(async2::Context &context, size_type num=1)
Returns pw::async2::Pending until space for num elements is available.
Definition: inline_async_deque.h:253
BasicInlineAsyncDeque(BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &&other) noexcept
Move constructs for mismatched capacity.
Definition: inline_async_deque.h:121
BasicInlineAsyncDeque(const BasicInlineAsyncDeque &other)
Copy constructs for matching capacity.
Definition: inline_async_deque.h:103
BasicInlineAsyncDeque & operator=(BasicInlineAsyncDeque &&other) noexcept
Move assigns for matching capacity.
Definition: inline_async_deque.h:172
BasicInlineAsyncDeque & operator=(BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &&other) noexcept
Move assigns for mismatched capacity.
Definition: inline_async_deque.h:179
BasicInlineAsyncDeque & operator=(const BasicInlineAsyncDeque &other)
Copy assigns for matching capacity.
Definition: inline_async_deque.h:156
constexpr BasicInlineAsyncDeque() noexcept=default
Constructs with zero elements.
BasicInlineAsyncDeque(BasicInlineAsyncDeque &&other) noexcept
Move constructs for matching capacity.
Definition: inline_async_deque.h:115
BasicInlineAsyncDeque(const T &other)
Copy constructor for arbitrary iterables.
Definition: inline_async_deque.h:134
BasicInlineAsyncDeque(size_type count)
Constructs with count default-initialized elements.
Definition: inline_async_deque.h:91
BasicInlineAsyncDeque & operator=(const std::initializer_list< value_type > &list)
Copy assigns from list.
Definition: inline_async_deque.h:149
BasicInlineAsyncDeque & operator=(const BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_async_deque.h:165
async2::Poll PendNotEmpty(async2::Context &context)
Returns pw::async2::Pending until an element is available.
Definition: inline_async_deque.h:257
BasicInlineAsyncDeque(const std::initializer_list< value_type > &list)
Copy constructs from an initializer list.
Definition: inline_async_deque.h:128
Definition: context.h:55
Definition: poll.h:60
Definition: async_count_and_capacity.h:35
The Pigweed namespace.
Definition: alignment.h:27