Pigweed
C/C++ API Reference
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
29// Forward declaration.
30template <typename T, typename SizeType, size_t kCapacity>
31class BasicInlineAsyncDeque;
32
37template <typename T, size_t kCapacity = containers::internal::kGenericSized>
39
40template <typename ValueType,
41 typename SizeType,
42 size_t kCapacity = containers::internal::kGenericSized>
44 : public containers::internal::RawStorage<
45 BasicInlineAsyncDeque<ValueType,
46 SizeType,
47 containers::internal::kGenericSized>,
48 ValueType,
49 kCapacity> {
50 private:
51 using Base = BasicInlineAsyncDeque<ValueType,
52 SizeType,
53 containers::internal::kGenericSized>;
54
55 public:
56 using typename Base::const_iterator;
57 using typename Base::const_pointer;
58 using typename Base::const_reference;
59 using typename Base::difference_type;
60 using typename Base::iterator;
61 using typename Base::pointer;
62 using typename Base::reference;
63 using typename Base::size_type;
64 using typename Base::value_type;
65
67 constexpr BasicInlineAsyncDeque() noexcept = default;
68
70 BasicInlineAsyncDeque(size_type count, const_reference value) {
71 Base::assign(count, value);
72 }
73
75 explicit BasicInlineAsyncDeque(size_type count)
76 : BasicInlineAsyncDeque(count, value_type()) {}
77
79 template <
80 typename InputIterator,
81 typename = containers::internal::EnableIfInputIterator<InputIterator>>
82 BasicInlineAsyncDeque(InputIterator start, InputIterator finish) {
83 Base::assign(start, finish);
84 }
85
87 BasicInlineAsyncDeque(const BasicInlineAsyncDeque& other) { *this = other; }
88
92 template <size_t kOtherCapacity>
95 *this = other;
96 }
97
100 *this = std::move(other);
101 }
102
104 template <size_t kOtherCapacity>
107 other) noexcept {
108 *this = std::move(other);
109 }
110
112 BasicInlineAsyncDeque(const std::initializer_list<value_type>& list) {
113 *this = list;
114 }
115
117 template <typename T, typename = containers::internal::EnableIfIterable<T>>
118 BasicInlineAsyncDeque(const T& other) {
119 *this = other;
120 }
121
122 // Assignment operators
123 //
124 // These operators delegate to the base class implementations in order to
125 // maximize code reuse. The wrappers are required so that `operator=`
126 // returns the correct type of reference.
127 //
128 // The `static_cast`s below are unfortunately necessary: without them,
129 // overload resolution prefers to use the "iterable" operators rather than
130 // upcast the RHS.
131
134 const std::initializer_list<value_type>& list) {
135 Base::operator=(list);
136 return *this;
137 }
138
141 Base::operator=(static_cast<const Base&>(other));
142 return *this;
143 }
144
148 template <size_t kOtherCapacity>
151 Base::operator=(static_cast<const Base&>(other));
152 return *this;
153 }
154
157 Base::operator=(static_cast<Base&&>(std::move(other)));
158 return *this;
159 }
160
162 template <size_t kOtherCapacity>
165 other) noexcept {
166 Base::operator=(static_cast<Base&&>(std::move(other)));
167 return *this;
168 }
169
170 // Size
171
172 static constexpr size_type max_size() { return capacity(); }
173 static constexpr size_type capacity() { return kCapacity; }
174};
175
176// Defines the generic-sized BasicInlineAsyncDeque<T> specialization, which
177// serves as the base class for BasicInlineAsyncDeque<T> of any capacity.
178//
179// Except for constructors and destructors, all other methods should be
180// implemented on this generic-sized specialization.
181//
182// NOTE: this size-polymorphic base class must not be used inside of
183// ``std::unique_ptr`` or ``delete``.
184template <typename ValueType, typename SizeType>
185class BasicInlineAsyncDeque<ValueType,
186 SizeType,
187 containers::internal::kGenericSized>
189 ValueType,
190 containers::internal::AsyncCountAndCapacity<SizeType>,
191 containers::internal::kGenericSized> {
192 private:
194 ValueType,
195 containers::internal::AsyncCountAndCapacity<SizeType>,
196 containers::internal::kGenericSized>;
197
198 public:
199 using typename Base::const_iterator;
200 using typename Base::const_pointer;
201 using typename Base::const_reference;
202 using typename Base::difference_type;
203 using typename Base::iterator;
204 using typename Base::pointer;
205 using typename Base::reference;
206 using typename Base::size_type;
207 using typename Base::value_type;
208
210 Base::assign(other.begin(), other.end());
211 return *this;
212 }
213
215 Base::clear();
216 for (auto&& item : other) {
217 Base::emplace_back(std::move(item));
218 }
219 other.clear();
220 return *this;
221 }
222
223 using Base::operator=;
224
226 async2::Poll<> PendHasSpace(async2::Context& context, size_type num = 1) {
227 return Base::count_and_capacity().PendHasSpace(context, num);
228 }
229
232 return Base::count_and_capacity().PendNotEmpty(context);
233 }
234
235 protected:
236 constexpr BasicInlineAsyncDeque(size_type capacity) noexcept
237 : Base(capacity) {}
238
239 // Polymorphic-sized `InlineAsyncDeque` may not be used with `unique_ptr`
240 // or `delete`. `delete` could be supported using C++20's destroying delete.
241 ~BasicInlineAsyncDeque() = default;
242
243 private:
244 static constexpr bool kFixedCapacity = true; // uses static allocation
245};
246
247} // namespace pw
async2::Poll PendHasSpace(async2::Context &context, size_type num=1)
Returns Pending until space for num elements is available.
Definition: inline_async_deque.h:226
async2::Poll PendNotEmpty(async2::Context &context)
Returns Pending until an element is available.
Definition: inline_async_deque.h:231
Definition: inline_async_deque.h:49
BasicInlineAsyncDeque(InputIterator start, InputIterator finish)
Copy constructs from an iterator.
Definition: inline_async_deque.h:82
BasicInlineAsyncDeque(const BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_async_deque.h:93
BasicInlineAsyncDeque(BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &&other) noexcept
Move constructs for mismatched capacity.
Definition: inline_async_deque.h:105
BasicInlineAsyncDeque(const BasicInlineAsyncDeque &other)
Copy constructs for matching capacity.
Definition: inline_async_deque.h:87
BasicInlineAsyncDeque & operator=(BasicInlineAsyncDeque &&other) noexcept
Move assigns for matching capacity.
Definition: inline_async_deque.h:156
BasicInlineAsyncDeque & operator=(BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &&other) noexcept
Move assigns for mismatched capacity.
Definition: inline_async_deque.h:163
BasicInlineAsyncDeque & operator=(const BasicInlineAsyncDeque &other)
Copy assigns for matching capacity.
Definition: inline_async_deque.h:140
constexpr BasicInlineAsyncDeque() noexcept=default
Constructs with zero elements.
BasicInlineAsyncDeque(BasicInlineAsyncDeque &&other) noexcept
Move constructs for matching capacity.
Definition: inline_async_deque.h:99
BasicInlineAsyncDeque(const T &other)
Copy constructor for arbitrary iterables.
Definition: inline_async_deque.h:118
BasicInlineAsyncDeque(size_type count)
Constructs with count default-initialized elements.
Definition: inline_async_deque.h:75
BasicInlineAsyncDeque & operator=(const std::initializer_list< value_type > &list)
Copy assigns from list.
Definition: inline_async_deque.h:133
BasicInlineAsyncDeque & operator=(const BasicInlineAsyncDeque< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_async_deque.h:149
BasicInlineAsyncDeque(const std::initializer_list< value_type > &list)
Copy constructs from an initializer list.
Definition: inline_async_deque.h:112
Definition: context.h:49
Definition: poll.h:54
Provides basic helpers for reading and writing UTF-8 encoded strings.
Definition: alignment.h:27