C/C++ API Reference
Loading...
Searching...
No Matches
dynamic_vector.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 <initializer_list>
17#include <iterator>
18
19#include "pw_allocator/allocator.h"
20#include "pw_containers/dynamic_deque.h"
21#include "pw_containers/ptr_iterator.h"
22
23namespace pw {
24
26
29
52template <typename T, typename SizeType = uint16_t>
54 public:
55 using value_type = T;
56 using size_type = SizeType;
57 using reference = value_type&;
58 using const_reference = const value_type&;
59 using pointer = value_type*;
60 using const_pointer = const value_type*;
63 using reverse_iterator = std::reverse_iterator<iterator>;
64 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
66
70 explicit constexpr DynamicVector(Allocator& allocator) : deque_(allocator) {}
71
72 DynamicVector(const DynamicVector&) = delete;
73 DynamicVector& operator=(const DynamicVector&) = delete;
74
75 constexpr DynamicVector(DynamicVector&&) = default;
76 constexpr DynamicVector& operator=(DynamicVector&&) = default;
77
78 // Iterators
79
80 iterator begin() { return iterator(data()); }
81 const_iterator begin() const { return cbegin(); }
82 const_iterator cbegin() const { return const_iterator(data()); }
83
84 iterator end() { return iterator(data() + size()); }
85 const_iterator end() const { return cend(); }
86 const_iterator cend() const { return const_iterator(data() + size()); }
87
88 reverse_iterator rbegin() { return reverse_iterator(end()); }
89 const_reverse_iterator rbegin() const { return crbegin(); }
90 const_reverse_iterator crbegin() const {
91 return const_reverse_iterator(end());
92 }
93
94 reverse_iterator rend() { return reverse_iterator(begin()); }
95 const_reverse_iterator rend() const { return crend(); }
96 const_reverse_iterator crend() const {
97 return const_reverse_iterator(begin());
98 }
99
100 // Capacity
101
103 constexpr allocator_type& get_allocator() const {
104 return deque_.get_allocator();
105 }
106
108 bool empty() const { return deque_.empty(); }
109
111 size_type size() const { return deque_.size(); }
112
115 size_type capacity() const { return deque_.capacity(); }
116
118 size_type max_size() const { return deque_.max_size(); }
119
125 void reserve(size_type new_capacity) { deque_.reserve(new_capacity); }
126
132 void reserve_exact(size_type new_capacity) {
133 deque_.reserve_exact(new_capacity);
134 }
135
143 [[nodiscard]] bool try_reserve(size_type new_capacity) {
144 return deque_.try_reserve(new_capacity);
145 }
146
153 [[nodiscard]] bool try_reserve_exact(size_type new_capacity) {
154 return deque_.try_reserve_exact(new_capacity);
155 }
156
158 void shrink_to_fit() { deque_.shrink_to_fit(); }
159
160 // Element access
161
168 reference operator[](size_type pos) { return data()[pos]; }
169
176 const_reference operator[](size_type pos) const { return data()[pos]; }
177
185 reference at(size_type pos) { return deque_.at(pos); }
186
194 const_reference at(size_type pos) const { return deque_.at(pos); }
195
199 reference front() { return deque_.front(); }
200
204 const_reference front() const { return deque_.front(); }
205
209 reference back() { return deque_.back(); }
210
214 const_reference back() const { return deque_.back(); }
215
222 pointer data() { return deque_.data(); }
223
229 const_pointer data() const { return deque_.data(); }
230
231 // Modifiers
232
238 void assign(size_type count, const value_type& value) {
239 deque_.assign(count, value);
240 }
241
242 [[nodiscard]] bool try_assign(size_type count, const value_type& value) {
243 return deque_.try_assign(count, value);
244 }
245
250 void assign(std::initializer_list<T> init) { deque_.assign(init); }
251
252 [[nodiscard]] bool try_assign(std::initializer_list<T> init) {
253 return deque_.try_assign(init);
254 }
255
260 void push_back(const value_type& value) { deque_.push_back(value); }
261
266 void push_back(value_type&& value) { deque_.push_back(std::move(value)); }
267
274 [[nodiscard]] bool try_push_back(const value_type& value) {
275 return deque_.try_push_back(value);
276 }
277
284 [[nodiscard]] bool try_push_back(value_type&& value) {
285 return deque_.try_push_back(std::move(value));
286 }
287
291 void pop_back() { deque_.pop_back(); }
292
297 template <typename... Args>
298 void emplace_back(Args&&... args) {
299 deque_.emplace_back(std::forward<Args>(args)...);
300 }
301
308 template <typename... Args>
309 [[nodiscard]] bool try_emplace_back(Args&&... args) {
310 return deque_.try_emplace_back(std::forward<Args>(args)...);
311 }
312
320 template <typename... Args>
321 iterator emplace(const_iterator pos, Args&&... args) {
322 auto deque_it = deque_.try_emplace_shift_right(ToDequeIterator(pos),
323 std::forward<Args>(args)...);
324 PW_ASSERT(deque_it.has_value());
325 return iterator(data() + deque_it->pos_);
326 }
327
336 template <typename... Args>
337 [[nodiscard]] std::optional<iterator> try_emplace(const_iterator pos,
338 Args&&... args) {
339 auto deque_it = deque_.try_emplace_shift_right(ToDequeIterator(pos),
340 std::forward<Args>(args)...);
341 if (!deque_it.has_value()) {
342 return std::nullopt;
343 }
344 return iterator(data() + deque_it->pos_);
345 }
346
354 iterator insert(const_iterator pos, const T& value) {
355 return emplace(pos, value);
356 }
357
366 return emplace(pos, std::move(value));
367 }
368
377 iterator insert(const_iterator pos, size_type count, const T& value) {
378 auto deque_it =
379 deque_.try_insert_shift_right(ToDequeIterator(pos), count, value);
380 PW_ASSERT(deque_it.has_value());
381 return iterator(data() + deque_it->pos_);
382 }
383
392 template <typename InputIt>
393 iterator insert(const_iterator pos, InputIt first, InputIt last) {
394 auto deque_it =
395 deque_.try_insert_shift_right(ToDequeIterator(pos), first, last);
396 PW_ASSERT(deque_it.has_value());
397 return iterator(data() + deque_it->pos_);
398 }
399
407 iterator insert(const_iterator pos, std::initializer_list<T> ilist) {
408 return insert(pos, ilist.begin(), ilist.end());
409 }
410
419 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
420 const T& value) {
421 return try_emplace(pos, value);
422 }
423
432 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
433 T&& value) {
434 return try_emplace(pos, std::move(value));
435 }
436
448 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
449 size_type count,
450 const T& value) {
451 auto deque_it =
452 deque_.try_insert_shift_right(ToDequeIterator(pos), count, value);
453 if (!deque_it.has_value()) {
454 return std::nullopt;
455 }
456 return iterator(data() + deque_it->pos_);
457 }
458
470 template <typename InputIt>
471 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
472 InputIt first,
473 InputIt last) {
474 auto deque_it =
475 deque_.try_insert_shift_right(ToDequeIterator(pos), first, last);
476 if (!deque_it.has_value()) {
477 return std::nullopt;
478 }
479 return iterator(data() + deque_it->pos_);
480 }
481
492 [[nodiscard]] std::optional<iterator> try_insert(
493 const_iterator pos, std::initializer_list<T> ilist) {
494 return try_insert(pos, ilist.begin(), ilist.end());
495 }
496
497 // TODO: b/424613355 - Implement insert, emplace
498
504 auto deque_it = deque_.erase(ToDequeIterator(pos));
505 return iterator(data() + deque_it.pos_);
506 }
507
514 auto deque_it = deque_.erase(ToDequeIterator(first), ToDequeIterator(last));
515 return iterator(data() + deque_it.pos_);
516 }
517
525 void resize(size_type count) { deque_.resize(count); }
526
536 void resize(size_type count, const value_type& value) {
537 deque_.resize(count, value);
538 }
539
544 [[nodiscard]] bool try_resize(size_type count) {
545 return deque_.try_resize(count);
546 }
547
554 [[nodiscard]] bool try_resize(size_type count, const value_type& value) {
555 return deque_.try_resize(count, value);
556 }
557
559 void clear() { deque_.clear(); }
560
564 void swap(DynamicVector& other) { deque_.swap(other.deque_); }
565
566 private:
567 typename DynamicDeque<T, size_type>::const_iterator ToDequeIterator(
568 const_iterator it) const {
569 return {deque_, static_cast<size_type>(it - cbegin())};
570 }
571
572 // The underlying DynamicDeque instance that provides the storage.
573 DynamicDeque<T, size_type> deque_;
574};
575
576} // namespace pw
Definition: allocator.h:36
bool try_assign(size_type count, const value_type &value)
Definition: generic_deque.h:615
Definition: dynamic_vector.h:53
Definition: ptr_iterator.h:164
Definition: ptr_iterator.h:142
constexpr size_type size() const noexcept
Returns the number of elements in the deque.
Definition: generic_deque.h:64
constexpr size_type capacity() const noexcept
Returns the maximum number of elements in the deque.
Definition: generic_deque.h:69
void reserve(size_type new_capacity)
Increases capacity() to at least new_capacity. Crashes on failure.
Definition: dynamic_deque.h:151
void reserve_exact(size_type new_capacity)
Increases capacity() to exactly new_capacity. Crashes on failure.
Definition: dynamic_deque.h:167
void swap(DynamicDeque &other) noexcept
Swaps the contents of two deques. No allocations occur.
Definition: dynamic_deque.h:182
bool try_reserve(size_type new_capacity)
Definition: dynamic_deque.h:240
void shrink_to_fit()
Attempts to reduce capacity() to size(). Not guaranteed to succeed.
Definition: dynamic_deque.h:261
constexpr allocator_type & get_allocator() const
Returns the deque's allocator.
Definition: dynamic_deque.h:179
bool try_reserve_exact(size_type new_capacity)
Definition: dynamic_deque.h:162
iterator erase(const_iterator pos)
Erases the item at pos, which must be a dereferenceable iterator.
Definition: generic_deque.h:305
void assign(size_type count, const value_type &value)
Sets the contents to count copies of value. Crashes if cannot fit.
Definition: generic_deque.h:211
std::optional< iterator > try_insert(const_iterator pos, T &&value)
Definition: dynamic_vector.h:432
iterator insert(const_iterator pos, InputIt first, InputIt last)
Definition: dynamic_vector.h:393
constexpr allocator_type & get_allocator() const
Returns the vector's allocator.
Definition: dynamic_vector.h:103
void clear()
Removes all elements from the vector.
Definition: dynamic_vector.h:559
size_type capacity() const
Definition: dynamic_vector.h:115
std::optional< iterator > try_insert(const_iterator pos, std::initializer_list< T > ilist)
Definition: dynamic_vector.h:492
bool try_resize(size_type count, const value_type &value)
Definition: dynamic_vector.h:554
bool try_emplace_back(Args &&... args)
Definition: dynamic_vector.h:309
reference at(size_type pos)
Definition: dynamic_vector.h:185
reference operator[](size_type pos)
Definition: dynamic_vector.h:168
bool try_reserve(size_type new_capacity)
Definition: dynamic_vector.h:143
std::optional< iterator > try_insert(const_iterator pos, InputIt first, InputIt last)
Definition: dynamic_vector.h:471
const_reference back() const
Definition: dynamic_vector.h:214
iterator insert(const_iterator pos, T &&value)
Definition: dynamic_vector.h:365
bool try_reserve_exact(size_type new_capacity)
Definition: dynamic_vector.h:153
void resize(size_type count)
Definition: dynamic_vector.h:525
void pop_back()
Definition: dynamic_vector.h:291
void emplace_back(Args &&... args)
Definition: dynamic_vector.h:298
std::optional< iterator > try_emplace(const_iterator pos, Args &&... args)
Definition: dynamic_vector.h:337
iterator insert(const_iterator pos, std::initializer_list< T > ilist)
Definition: dynamic_vector.h:407
iterator insert(const_iterator pos, size_type count, const T &value)
Definition: dynamic_vector.h:377
reference front()
Definition: dynamic_vector.h:199
reference back()
Definition: dynamic_vector.h:209
size_type max_size() const
Maximum possible value of size(), ignoring allocator limitations.
Definition: dynamic_vector.h:118
void reserve(size_type new_capacity)
Definition: dynamic_vector.h:125
const_reference operator[](size_type pos) const
Definition: dynamic_vector.h:176
const_pointer data() const
Definition: dynamic_vector.h:229
void resize(size_type count, const value_type &value)
Definition: dynamic_vector.h:536
bool try_push_back(value_type &&value)
Definition: dynamic_vector.h:284
iterator insert(const_iterator pos, const T &value)
Definition: dynamic_vector.h:354
std::optional< iterator > try_insert(const_iterator pos, const T &value)
Definition: dynamic_vector.h:419
void shrink_to_fit()
Reduces memory usage by releasing unused capacity.
Definition: dynamic_vector.h:158
void push_back(value_type &&value)
Definition: dynamic_vector.h:266
std::optional< iterator > try_insert(const_iterator pos, size_type count, const T &value)
Definition: dynamic_vector.h:448
const_reference front() const
Definition: dynamic_vector.h:204
constexpr DynamicVector(Allocator &allocator)
Definition: dynamic_vector.h:70
void push_back(const value_type &value)
Definition: dynamic_vector.h:260
bool try_push_back(const value_type &value)
Definition: dynamic_vector.h:274
void reserve_exact(size_type new_capacity)
Definition: dynamic_vector.h:132
iterator erase(const_iterator pos)
Definition: dynamic_vector.h:503
pointer data()
Definition: dynamic_vector.h:222
size_type size() const
Returns the number of elements in the vector.
Definition: dynamic_vector.h:111
const_reference at(size_type pos) const
Definition: dynamic_vector.h:194
iterator erase(const_iterator first, const_iterator last)
Definition: dynamic_vector.h:513
void assign(size_type count, const value_type &value)
Definition: dynamic_vector.h:238
bool empty() const
Checks if the vector is empty.
Definition: dynamic_vector.h:108
void swap(DynamicVector &other)
Definition: dynamic_vector.h:564
iterator emplace(const_iterator pos, Args &&... args)
Definition: dynamic_vector.h:321
void assign(std::initializer_list< T > init)
Definition: dynamic_vector.h:250
bool try_resize(size_type count)
Definition: dynamic_vector.h:544
The Pigweed namespace.
Definition: alignment.h:27