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
39template <typename T, size_t kCapacity = containers::internal::kGenericSized>
41
42template <typename ValueType,
43 typename SizeType,
44 size_t kCapacity = containers::internal::kGenericSized>
46 : public containers::internal::RawStorage<
47 BasicInlineAsyncDeque<ValueType,
48 SizeType,
49 containers::internal::kGenericSized>,
50 ValueType,
51 kCapacity> {
52 private:
53 using Base = BasicInlineAsyncDeque<ValueType,
54 SizeType,
55 containers::internal::kGenericSized>;
56
57 public:
58 using typename Base::const_iterator;
59 using typename Base::const_pointer;
60 using typename Base::const_reference;
61 using typename Base::difference_type;
62 using typename Base::iterator;
63 using typename Base::pointer;
64 using typename Base::reference;
65 using typename Base::size_type;
66 using typename Base::value_type;
67
69 constexpr BasicInlineAsyncDeque() noexcept = default;
70
72 BasicInlineAsyncDeque(size_type count, const_reference value) {
73 Base::assign(count, value);
74 }
75
77 explicit BasicInlineAsyncDeque(size_type count)
78 : BasicInlineAsyncDeque(count, value_type()) {}
79
81 template <
82 typename InputIterator,
83 typename = containers::internal::EnableIfInputIterator<InputIterator>>
84 BasicInlineAsyncDeque(InputIterator start, InputIterator finish) {
85 Base::assign(start, finish);
86 }
87
89 BasicInlineAsyncDeque(const BasicInlineAsyncDeque& other) { *this = other; }
90
94 template <size_t kOtherCapacity>
97 *this = other;
98 }
99
102 *this = std::move(other);
103 }
104
106 template <size_t kOtherCapacity>
109 other) noexcept {
110 *this = std::move(other);
111 }
112
114 BasicInlineAsyncDeque(const std::initializer_list<value_type>& list) {
115 *this = list;
116 }
117
119 template <typename T, typename = containers::internal::EnableIfIterable<T>>
120 BasicInlineAsyncDeque(const T& other) {
121 *this = other;
122 }
123
124 // Assignment operators
125 //
126 // These operators delegate to the base class implementations in order to
127 // maximize code reuse. The wrappers are required so that `operator=`
128 // returns the correct type of reference.
129 //
130 // The `static_cast`s below are unfortunately necessary: without them,
131 // overload resolution prefers to use the "iterable" operators rather than
132 // upcast the RHS.
133
136 const std::initializer_list<value_type>& list) {
137 Base::operator=(list);
138 return *this;
139 }
140
143 Base::operator=(static_cast<const Base&>(other));
144 return *this;
145 }
146
150 template <size_t kOtherCapacity>
153 Base::operator=(static_cast<const Base&>(other));
154 return *this;
155 }
156
159 Base::operator=(static_cast<Base&&>(std::move(other)));
160 return *this;
161 }
162
164 template <size_t kOtherCapacity>
167 other) noexcept {
168 Base::operator=(static_cast<Base&&>(std::move(other)));
169 return *this;
170 }
171
172 // Size
173
174 static constexpr size_type max_size() { return capacity(); }
175 static constexpr size_type capacity() { return kCapacity; }
176};
177
178// Defines the generic-sized BasicInlineAsyncDeque<T> specialization, which
179// serves as the base class for BasicInlineAsyncDeque<T> of any capacity.
180//
181// Except for constructors and destructors, all other methods should be
182// implemented on this generic-sized specialization.
183//
184// NOTE: this size-polymorphic base class must not be used inside of
185// ``std::unique_ptr`` or ``delete``.
186template <typename ValueType, typename SizeType>
187class BasicInlineAsyncDeque<ValueType,
188 SizeType,
189 containers::internal::kGenericSized>
191 ValueType,
192 containers::internal::AsyncCountAndCapacity<SizeType>,
193 containers::internal::kGenericSized> {
194 private:
196 ValueType,
198 containers::internal::kGenericSized>;
199
200 public:
201 using typename Base::const_iterator;
202 using typename Base::const_pointer;
203 using typename Base::const_reference;
204 using typename Base::difference_type;
205 using typename Base::iterator;
206 using typename Base::pointer;
207 using typename Base::reference;
208 using typename Base::size_type;
209 using typename Base::value_type;
210
212 Base::assign(other.begin(), other.end());
213 return *this;
214 }
215
217 Base::clear();
218 for (auto&& item : other) {
219 Base::emplace_back(std::move(item));
220 }
221 other.clear();
222 return *this;
223 }
224
225 using Base::operator=;
226
228 async2::Poll<> PendHasSpace(async2::Context& context, size_type num = 1) {
229 return Base::count_and_capacity().PendHasSpace(context, num);
230 }
231
234 return Base::count_and_capacity().PendNotEmpty(context);
235 }
236
237 protected:
238 constexpr BasicInlineAsyncDeque(size_type capacity) noexcept
239 : Base(capacity) {}
240
241 // Polymorphic-sized `InlineAsyncDeque` may not be used with `unique_ptr`
242 // or `delete`. `delete` could be supported using C++20's destroying delete.
243 ~BasicInlineAsyncDeque() = default;
244
245 private:
246 static constexpr bool kFixedCapacity = true; // uses static allocation
247};
248
249} // namespace pw
Definition: inline_async_deque.h:51
Definition: context.h:55
Definition: poll.h:60
Definition: async_count_and_capacity.h:35
BasicInlineAsyncDeque(InputIterator start, InputIterator finish)
Copy constructs from an iterator.
Definition: inline_async_deque.h:84
BasicInlineAsyncDeque(const BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_async_deque.h:95
async2::Poll PendHasSpace(async2::Context &context, size_type num=1)
Returns Pending until space for num elements is available.
Definition: inline_async_deque.h:228
BasicInlineAsyncDeque(BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &&other) noexcept
Move constructs for mismatched capacity.
Definition: inline_async_deque.h:107
BasicInlineAsyncDeque(const BasicInlineAsyncDeque &other)
Copy constructs for matching capacity.
Definition: inline_async_deque.h:89
BasicInlineAsyncDeque & operator=(BasicInlineAsyncDeque &&other) noexcept
Move assigns for matching capacity.
Definition: inline_async_deque.h:158
BasicInlineAsyncDeque & operator=(BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &&other) noexcept
Move assigns for mismatched capacity.
Definition: inline_async_deque.h:165
BasicInlineAsyncDeque & operator=(const BasicInlineAsyncDeque &other)
Copy assigns for matching capacity.
Definition: inline_async_deque.h:142
constexpr BasicInlineAsyncDeque() noexcept=default
Constructs with zero elements.
BasicInlineAsyncDeque(BasicInlineAsyncDeque &&other) noexcept
Move constructs for matching capacity.
Definition: inline_async_deque.h:101
BasicInlineAsyncDeque(const T &other)
Copy constructor for arbitrary iterables.
Definition: inline_async_deque.h:120
BasicInlineAsyncDeque(size_type count)
Constructs with count default-initialized elements.
Definition: inline_async_deque.h:77
BasicInlineAsyncDeque & operator=(const std::initializer_list< value_type > &list)
Copy assigns from list.
Definition: inline_async_deque.h:135
BasicInlineAsyncDeque & operator=(const BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_async_deque.h:151
async2::Poll PendNotEmpty(async2::Context &context)
Returns Pending until an element is available.
Definition: inline_async_deque.h:233
BasicInlineAsyncDeque(const std::initializer_list< value_type > &list)
Copy constructs from an initializer list.
Definition: inline_async_deque.h:114
The Pigweed namespace.
Definition: alignment.h:27