C/C++ API Reference
Loading...
Searching...
No Matches
inline_queue.h
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#include <initializer_list>
17#include <utility>
18
19#include "pw_containers/inline_deque.h"
20#include "pw_containers/internal/generic_queue.h"
21
22namespace pw {
23namespace containers::internal {
24
25template <typename Derived, typename Deque>
26class BasicInlineQueueImpl;
27
28} // namespace containers::internal
29
31
34
35template <typename T, typename SizeType, size_t kCapacity>
36class BasicInlineQueue;
37
46template <typename T, size_t kCapacity = containers::internal::kGenericSized>
48
49template <typename ValueType,
50 typename SizeType,
51 size_t kCapacity = containers::internal::kGenericSized>
53 // TODO: b/513051956 - Fix `recursive class relation` error
55 : public BasicInlineQueue<ValueType,
56 SizeType,
57 containers::internal::kGenericSized>
59{
60 private:
61 using Base = BasicInlineQueue<ValueType,
62 SizeType,
63 containers::internal::kGenericSized>;
64
65 public:
66 using typename Base::const_iterator;
67 using typename Base::const_pointer;
68 using typename Base::const_reference;
69 using typename Base::difference_type;
70 using typename Base::iterator;
71 using typename Base::pointer;
72 using typename Base::reference;
73 using typename Base::size_type;
74 using typename Base::value_type;
75
76 // Constructors
77
78 BasicInlineQueue() noexcept = default;
79
80 // Explicit zero element constexpr constructor. Using this constructor will
81 // place the entire object in .data, which will increase ROM size. Use with
82 // caution if working with large capacity sizes.
83 constexpr BasicInlineQueue(ConstexprTag constexpr_tag) noexcept
84 : deque_(constexpr_tag) {}
85
86 BasicInlineQueue(size_type count, const_reference value)
87 : deque_(count, value) {}
88
89 explicit BasicInlineQueue(size_type count) : deque_(count) {}
90
91 template <
92 typename InputIterator,
93 typename = containers::internal::EnableIfInputIterator<InputIterator>>
94 BasicInlineQueue(InputIterator start, InputIterator finish)
95 : deque_(start, finish) {}
96
97 BasicInlineQueue(const std::initializer_list<value_type>& list)
98 : deque_(list) {}
99
101 BasicInlineQueue(const BasicInlineQueue& other) : deque_(other) {}
102
106 template <size_t kOtherCapacity>
109 *this = other;
110 }
111
114 : deque_(std::move(other.deque_)) {}
115
119 template <size_t kOtherCapacity>
122 *this = std::move(other);
123 }
124
125 template <typename T, typename = containers::internal::EnableIfIterable<T>>
126 BasicInlineQueue(const T& other) : deque_(other.begin(), other.end()) {}
127
128 BasicInlineQueue& operator=(const std::initializer_list<value_type>& list) {
129 deque_ = std::move(list);
130 return *this;
131 }
132
135 deque_ = other.deque_;
136 return *this;
137 }
138
142 template <size_t kOtherCapacity>
145 deque_ = other.deque_;
146 return *this;
147 }
148
151 deque_ = std::move(other.deque_);
152 return *this;
153 }
154
158 template <size_t kOtherCapacity>
161 deque_ = std::move(other.deque_);
162 return *this;
163 }
164
165 template <typename T, typename = containers::internal::EnableIfIterable<T>>
166 BasicInlineQueue& operator=(const T& other) {
168 other.end());
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 private:
178 template <typename OtherValueType, typename OtherSizeType, size_t kOtherSized>
179 friend class BasicInlineQueue;
180
181 template <typename, typename>
182 friend class containers::internal::BasicInlineQueueImpl;
183
184 // The deque() function is defined differently for the generic-sized and
185 // known-sized specializations. This deque() implementation simply returns the
186 // generic-sized deque_. The generic-sized deque() function casts *this to a
187 // known zero-sized specialzation to access this exact function.
188 BasicInlineDeque<ValueType, SizeType>& deque() { return deque_; }
189 const BasicInlineDeque<ValueType, SizeType>& deque() const { return deque_; }
190
191 BasicInlineDeque<ValueType, SizeType, kCapacity> deque_;
192};
193
194// Defines the generic-sized BasicInlineDeque<T> specialization, which
195// serves as the base class for BasicInlineDeque<T> of any capacity.
196//
197// Except for constructors, all other methods should be implemented on this
198// generic-sized specialization.
199template <typename ValueType, typename SizeType>
200class BasicInlineQueue<ValueType, SizeType, containers::internal::kGenericSized>
202 BasicInlineQueue<ValueType,
203 SizeType,
204 containers::internal::kGenericSized>,
205 BasicInlineDeque<ValueType, SizeType>> {
206 private:
209 BasicInlineQueue<ValueType,
210 SizeType,
211 containers::internal::kGenericSized>,
212 Deque>;
213
214 public:
215 using typename Base::const_iterator;
216 using typename Base::const_pointer;
217 using typename Base::const_reference;
218 using typename Base::difference_type;
219 using typename Base::iterator;
220 using typename Base::pointer;
221 using typename Base::reference;
222 using typename Base::size_type;
223 using typename Base::value_type;
224
225 protected:
226 constexpr BasicInlineQueue() noexcept = default;
227
228 // Polymorphic-sized `pw::InlineQueue<T>` may not be used with `unique_ptr`
229 // or `delete`. `delete` could be supported using C++20's destroying delete.
230 ~BasicInlineQueue() = default;
231
232 protected:
233 template <typename, typename>
235
236 template <size_t kCapacity>
238
239 // The underlying BasicInlineDeque is not part of the generic-sized class. It
240 // is provided in the derived class from which this instance was constructed.
241 // To access the data, down-cast this to a known max size specialization, and
242 // return a reference to a generic-sized BasicInlineDeque, which is the same
243 // reference for all sizes.
244 Deque& deque() { return static_cast<Derived<0>*>(this)->deque(); }
245 const Deque& deque() const {
246 return static_cast<const Derived<0>*>(this)->deque();
247 }
248};
249
251
252namespace containers::internal {
253
254template <typename Derived, typename Deque>
255class BasicInlineQueueImpl : public GenericQueue<Derived, Deque> {
256 private:
258
259 public:
260 using typename Base::const_iterator;
261 using typename Base::const_pointer;
262 using typename Base::const_reference;
263 using typename Base::difference_type;
264 using typename Base::iterator;
265 using typename Base::pointer;
266 using typename Base::reference;
267 using typename Base::size_type;
268 using typename Base::value_type;
269
270 // Access
271
272 reference at(size_type index) { return deque().at(index); }
273 const_reference at(size_type index) const { return deque().at(index); }
274
275 reference operator[](size_type index) { return deque()[index]; }
276 const_reference operator[](size_type index) const { return deque()[index]; }
277
278 std::pair<span<const value_type>, span<const value_type>> contiguous_data()
279 const {
280 return deque().contiguous_data();
281 }
282 std::pair<span<value_type>, span<value_type>> contiguous_data() {
283 return deque().contiguous_data();
284 }
285
286 // Iterate
287
288 iterator begin() noexcept { return deque().begin(); }
289 const_iterator begin() const noexcept { return cbegin(); }
290 const_iterator cbegin() const noexcept { return deque().cbegin(); }
291
292 iterator end() noexcept { return deque().end(); }
293 const_iterator end() const noexcept { return cend(); }
294 const_iterator cend() const noexcept { return deque().cend(); }
295
296 private:
297 using Base::deque;
298};
299
300} // namespace containers::internal
301} // namespace pw
Definition: inline_queue.h:59
Definition: generic_queue.h:25
Definition: span_impl.h:235
BasicInlineQueue & operator=(BasicInlineQueue< ValueType, SizeType, kOtherCapacity > &&other)
Definition: inline_queue.h:159
BasicInlineQueue & operator=(const BasicInlineQueue< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_queue.h:143
BasicInlineQueue & operator=(BasicInlineQueue &&other)
Move assigns from matching capacity.
Definition: inline_queue.h:150
BasicInlineQueue & operator=(const BasicInlineQueue &other)
Copy assigns from matching capacity.
Definition: inline_queue.h:134
BasicInlineQueue(BasicInlineQueue &&other)
Move constructs for matching capacity.
Definition: inline_queue.h:113
BasicInlineQueue(BasicInlineQueue< ValueType, SizeType, kOtherCapacity > &&other)
Definition: inline_queue.h:120
BasicInlineQueue(const BasicInlineQueue< ValueType, SizeType, kOtherCapacity > &other)
Definition: inline_queue.h:107
BasicInlineQueue(const BasicInlineQueue &other)
Copy constructs for matching capacity.
Definition: inline_queue.h:101
The Pigweed namespace.
Definition: alignment.h:27
Definition: constexpr_tag.h:48