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_preprocessor/compiler.h"
26#include "pw_toolchain/constexpr_tag.h"
27
29PW_MODIFY_DIAGNOSTIC(ignored, "-Wdeprecated-declarations");
30
31namespace pw {
32
34
35// Forward declaration.
36template <typename T, typename SizeType, size_t kCapacity>
37class BasicInlineAsyncDeque;
38
49template <typename T, size_t kCapacity = containers::internal::kGenericSized>
51
68template <typename ValueType,
69 typename SizeType,
70 size_t kCapacity = containers::internal::kGenericSized>
71class [[deprecated(
72 "Use pw_async2 Channels instead "
73 "(pw_async2/channel.h)")]] BasicInlineAsyncDeque
74 : public containers::internal::RawStorage<
75 BasicInlineAsyncDeque<ValueType,
76 SizeType,
77 containers::internal::kGenericSized>,
78 ValueType,
79 kCapacity> {
80 private:
81 using Base = BasicInlineAsyncDeque<ValueType,
82 SizeType,
83 containers::internal::kGenericSized>;
84
85 public:
86 using typename Base::const_iterator;
87 using typename Base::const_pointer;
88 using typename Base::const_reference;
89 using typename Base::difference_type;
90 using typename Base::iterator;
91 using typename Base::pointer;
92 using typename Base::reference;
93 using typename Base::size_type;
94 using typename Base::value_type;
95
97 constexpr BasicInlineAsyncDeque() noexcept = default;
98
100 BasicInlineAsyncDeque(size_type count, const_reference value) {
101 Base::assign(count, value);
102 }
103
105 explicit BasicInlineAsyncDeque(size_type count)
106 : BasicInlineAsyncDeque(count, value_type()) {}
107
109 template <
110 typename InputIterator,
111 typename = containers::internal::EnableIfInputIterator<InputIterator>>
112 BasicInlineAsyncDeque(InputIterator start, InputIterator finish) {
113 Base::assign(start, finish);
114 }
115
117 BasicInlineAsyncDeque(const BasicInlineAsyncDeque& other) { *this = other; }
118
122 template <size_t kOtherCapacity>
125 *this = other;
126 }
127
130 *this = std::move(other);
131 }
132
134 template <size_t kOtherCapacity>
137 other) noexcept {
138 *this = std::move(other);
139 }
140
142 BasicInlineAsyncDeque(const std::initializer_list<value_type>& list) {
143 *this = list;
144 }
145
147 template <typename T, typename = containers::internal::EnableIfIterable<T>>
148 BasicInlineAsyncDeque(const T& other) {
149 *this = other;
150 }
151
152 // Assignment operators
153 //
154 // These operators delegate to the base class implementations in order to
155 // maximize code reuse. The wrappers are required so that `operator=`
156 // returns the correct type of reference.
157 //
158 // The `static_cast`s below are unfortunately necessary: without them,
159 // overload resolution prefers to use the "iterable" operators rather than
160 // upcast the RHS.
161
164 const std::initializer_list<value_type>& list) {
165 Base::operator=(list);
166 return *this;
167 }
168
171 Base::operator=(static_cast<const Base&>(other));
172 return *this;
173 }
174
178 template <size_t kOtherCapacity>
181 Base::operator=(static_cast<const Base&>(other));
182 return *this;
183 }
184
187 Base::operator=(static_cast<Base&&>(std::move(other)));
188 return *this;
189 }
190
192 template <size_t kOtherCapacity>
195 other) noexcept {
196 Base::operator=(static_cast<Base&&>(std::move(other)));
197 return *this;
198 }
199
200 // Size
201
202 static constexpr size_type max_size() { return capacity(); }
203 static constexpr size_type capacity() { return kCapacity; }
204
205 // Async
206 // Document these functions here since the template specialization base isn't
207 // included in Doxygen.
208
210 using Base::PendHasSpace;
211
213 using Base::PendNotEmpty;
214};
215
217
218// Defines the generic-sized BasicInlineAsyncDeque<T> specialization, which
219// serves as the base class for BasicInlineAsyncDeque<T> of any capacity.
220//
221// Except for constructors and destructors, all other methods should be
222// implemented on this generic-sized specialization.
223//
224// NOTE: this size-polymorphic base class must not be used inside of
225// ``std::unique_ptr`` or ``delete``.
226template <typename ValueType, typename SizeType>
227class BasicInlineAsyncDeque<ValueType,
228 SizeType,
229 containers::internal::kGenericSized>
231 ValueType,
232 containers::internal::AsyncCountAndCapacity<SizeType>,
233 containers::internal::kGenericSized> {
234 private:
236 ValueType,
238 containers::internal::kGenericSized>;
239
240 public:
241 using typename Base::const_iterator;
242 using typename Base::const_pointer;
243 using typename Base::const_reference;
244 using typename Base::difference_type;
245 using typename Base::iterator;
246 using typename Base::pointer;
247 using typename Base::reference;
248 using typename Base::size_type;
249 using typename Base::value_type;
250
252 Base::assign(other.begin(), other.end());
253 return *this;
254 }
255
257 Base::clear();
258 for (auto&& item : other) {
259 Base::emplace_back(std::move(item));
260 }
261 other.clear();
262 return *this;
263 }
264
265 using Base::operator=;
266
267 async2::Poll<> PendHasSpace(async2::Context& context, size_type num = 1) {
268 return Base::count_and_capacity().PendHasSpace(context, num);
269 }
270
272 return Base::count_and_capacity().PendNotEmpty(context);
273 }
274
275 protected:
276 constexpr BasicInlineAsyncDeque(size_type capacity) noexcept
277 : Base(capacity) {}
278
279 // Polymorphic-sized `InlineAsyncDeque` may not be used with `unique_ptr`
280 // or `delete`. `delete` could be supported using C++20's destroying delete.
281 ~BasicInlineAsyncDeque() = default;
282
283 private:
284 static constexpr bool kFixedCapacity = true; // uses static allocation
285};
286
287} // namespace pw
288
Definition: inline_async_deque.h:79
BasicInlineAsyncDeque(InputIterator start, InputIterator finish)
Copy constructs from an iterator.
Definition: inline_async_deque.h:112
BasicInlineAsyncDeque(const BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_async_deque.h:123
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:267
BasicInlineAsyncDeque(BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &&other) noexcept
Move constructs for mismatched capacity.
Definition: inline_async_deque.h:135
BasicInlineAsyncDeque(const BasicInlineAsyncDeque &other)
Copy constructs for matching capacity.
Definition: inline_async_deque.h:117
BasicInlineAsyncDeque & operator=(BasicInlineAsyncDeque &&other) noexcept
Move assigns for matching capacity.
Definition: inline_async_deque.h:186
BasicInlineAsyncDeque & operator=(BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &&other) noexcept
Move assigns for mismatched capacity.
Definition: inline_async_deque.h:193
BasicInlineAsyncDeque & operator=(const BasicInlineAsyncDeque &other)
Copy assigns for matching capacity.
Definition: inline_async_deque.h:170
constexpr BasicInlineAsyncDeque() noexcept=default
Constructs with zero elements.
BasicInlineAsyncDeque(BasicInlineAsyncDeque &&other) noexcept
Move constructs for matching capacity.
Definition: inline_async_deque.h:129
BasicInlineAsyncDeque(const T &other)
Copy constructor for arbitrary iterables.
Definition: inline_async_deque.h:148
BasicInlineAsyncDeque(size_type count)
Constructs with count default-initialized elements.
Definition: inline_async_deque.h:105
BasicInlineAsyncDeque & operator=(const std::initializer_list< value_type > &list)
Copy assigns from list.
Definition: inline_async_deque.h:163
BasicInlineAsyncDeque & operator=(const BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_async_deque.h:179
async2::Poll PendNotEmpty(async2::Context &context)
Returns pw::async2::Pending until an element is available.
Definition: inline_async_deque.h:271
BasicInlineAsyncDeque(const std::initializer_list< value_type > &list)
Copy constructs from an initializer list.
Definition: inline_async_deque.h:142
Definition: context.h:54
Definition: poll.h:60
Definition: async_count_and_capacity.h:35
#define PW_MODIFY_DIAGNOSTICS_POP()
Definition: compiler.h:194
#define PW_MODIFY_DIAGNOSTIC(kind, option)
Definition: compiler.h:203
#define PW_MODIFY_DIAGNOSTICS_PUSH()
Definition: compiler.h:189
The Pigweed namespace.
Definition: alignment.h:27