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
62template <typename T, typename SizeType = uint16_t>
64 public:
65 using value_type = T;
66 using size_type = SizeType;
67 using reference = value_type&;
68 using const_reference = const value_type&;
69 using pointer = value_type*;
70 using const_pointer = const value_type*;
73 using reverse_iterator = std::reverse_iterator<iterator>;
74 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
76
80 explicit constexpr DynamicVector(Allocator& allocator) : deque_(allocator) {}
81
82 DynamicVector(const DynamicVector&) = delete;
83 DynamicVector& operator=(const DynamicVector&) = delete;
84
85 constexpr DynamicVector(DynamicVector&&) = default;
86 constexpr DynamicVector& operator=(DynamicVector&&) = default;
87
88 // Iterators
89
90 iterator begin() { return iterator(data()); }
91 const_iterator begin() const { return cbegin(); }
92 const_iterator cbegin() const { return const_iterator(data()); }
93
94 iterator end() { return iterator(data() + size()); }
95 const_iterator end() const { return cend(); }
96 const_iterator cend() const { return const_iterator(data() + size()); }
97
98 reverse_iterator rbegin() { return reverse_iterator(end()); }
99 const_reverse_iterator rbegin() const { return crbegin(); }
100 const_reverse_iterator crbegin() const {
101 return const_reverse_iterator(end());
102 }
103
104 reverse_iterator rend() { return reverse_iterator(begin()); }
105 const_reverse_iterator rend() const { return crend(); }
106 const_reverse_iterator crend() const {
107 return const_reverse_iterator(begin());
108 }
109
110 // Capacity
111
113 constexpr allocator_type& get_allocator() const {
114 return deque_.get_allocator();
115 }
116
118 bool empty() const { return deque_.empty(); }
119
121 size_type size() const { return deque_.size(); }
122
125 size_type capacity() const { return deque_.capacity(); }
126
128 size_type max_size() const { return deque_.max_size(); }
129
135 void reserve(size_type new_capacity) { deque_.reserve(new_capacity); }
136
142 void reserve_exact(size_type new_capacity) {
143 deque_.reserve_exact(new_capacity);
144 }
145
153 [[nodiscard]] bool try_reserve(size_type new_capacity) {
154 return deque_.try_reserve(new_capacity);
155 }
156
163 [[nodiscard]] bool try_reserve_exact(size_type new_capacity) {
164 return deque_.try_reserve_exact(new_capacity);
165 }
166
168 void shrink_to_fit() { deque_.shrink_to_fit(); }
169
170 // Element access
171
178 reference operator[](size_type pos) { return data()[pos]; }
179
186 const_reference operator[](size_type pos) const { return data()[pos]; }
187
195 reference at(size_type pos) { return deque_.at(pos); }
196
204 const_reference at(size_type pos) const { return deque_.at(pos); }
205
209 reference front() { return deque_.front(); }
210
214 const_reference front() const { return deque_.front(); }
215
219 reference back() { return deque_.back(); }
220
224 const_reference back() const { return deque_.back(); }
225
232 pointer data() { return deque_.data(); }
233
239 const_pointer data() const { return deque_.data(); }
240
241 // Modifiers
242
247 void assign(size_type count, const value_type& value) {
248 deque_.assign(count, value);
249 }
250
251 [[nodiscard]] bool try_assign(size_type count, const value_type& value) {
252 return deque_.try_assign(count, value);
253 }
254
258 void assign(std::initializer_list<T> init) { deque_.assign(init); }
259
260 [[nodiscard]] bool try_assign(std::initializer_list<T> init) {
261 return deque_.try_assign(init);
262 }
263
268 void push_back(const value_type& value) { deque_.push_back(value); }
269
274 void push_back(value_type&& value) { deque_.push_back(std::move(value)); }
275
282 [[nodiscard]] bool try_push_back(const value_type& value) {
283 return deque_.try_push_back(value);
284 }
285
292 [[nodiscard]] bool try_push_back(value_type&& value) {
293 return deque_.try_push_back(std::move(value));
294 }
295
299 void pop_back() { deque_.pop_back(); }
300
305 template <typename... Args>
306 void emplace_back(Args&&... args) {
307 deque_.emplace_back(std::forward<Args>(args)...);
308 }
309
316 template <typename... Args>
317 [[nodiscard]] bool try_emplace_back(Args&&... args) {
318 return deque_.try_emplace_back(std::forward<Args>(args)...);
319 }
320
328 template <typename... Args>
329 iterator emplace(const_iterator pos, Args&&... args) {
330 auto deque_it = deque_.try_emplace_shift_right(ToDequeIterator(pos),
331 std::forward<Args>(args)...);
332 PW_ASSERT(deque_it.has_value());
333 return iterator(data() + deque_it->pos_);
334 }
335
344 template <typename... Args>
345 [[nodiscard]] std::optional<iterator> try_emplace(const_iterator pos,
346 Args&&... args) {
347 auto deque_it = deque_.try_emplace_shift_right(ToDequeIterator(pos),
348 std::forward<Args>(args)...);
349 if (!deque_it.has_value()) {
350 return std::nullopt;
351 }
352 return iterator(data() + deque_it->pos_);
353 }
354
362 iterator insert(const_iterator pos, const T& value) {
363 return emplace(pos, value);
364 }
365
374 return emplace(pos, std::move(value));
375 }
376
385 iterator insert(const_iterator pos, size_type count, const T& value) {
386 auto deque_it =
387 deque_.try_insert_shift_right(ToDequeIterator(pos), count, value);
388 PW_ASSERT(deque_it.has_value());
389 return iterator(data() + deque_it->pos_);
390 }
391
400 template <typename InputIt>
401 iterator insert(const_iterator pos, InputIt first, InputIt last) {
402 auto deque_it =
403 deque_.try_insert_shift_right(ToDequeIterator(pos), first, last);
404 PW_ASSERT(deque_it.has_value());
405 return iterator(data() + deque_it->pos_);
406 }
407
415 iterator insert(const_iterator pos, std::initializer_list<T> ilist) {
416 return insert(pos, ilist.begin(), ilist.end());
417 }
418
427 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
428 const T& value) {
429 return try_emplace(pos, value);
430 }
431
440 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
441 T&& value) {
442 return try_emplace(pos, std::move(value));
443 }
444
456 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
457 size_type count,
458 const T& value) {
459 auto deque_it =
460 deque_.try_insert_shift_right(ToDequeIterator(pos), count, value);
461 if (!deque_it.has_value()) {
462 return std::nullopt;
463 }
464 return iterator(data() + deque_it->pos_);
465 }
466
478 template <typename InputIt>
479 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
480 InputIt first,
481 InputIt last) {
482 auto deque_it =
483 deque_.try_insert_shift_right(ToDequeIterator(pos), first, last);
484 if (!deque_it.has_value()) {
485 return std::nullopt;
486 }
487 return iterator(data() + deque_it->pos_);
488 }
489
500 [[nodiscard]] std::optional<iterator> try_insert(
501 const_iterator pos, std::initializer_list<T> ilist) {
502 return try_insert(pos, ilist.begin(), ilist.end());
503 }
504
505 // TODO: b/424613355 - Implement insert, emplace
506
511 iterator erase(const_iterator pos) { return erase(pos, pos + 1); }
512
519 auto first_ptr = const_cast<pointer>(&*first);
520 if (first != last) {
521 std::move(const_cast<pointer>(&*last), data() + size(), first_ptr);
522 size_t items_to_pop = static_cast<SizeType>(last - first);
523 for (size_t i = 0; i < items_to_pop; ++i) {
524 deque_.pop_back();
525 }
526 }
527 return iterator(first_ptr);
528 }
529
537 void resize(size_type count) { deque_.resize(count); }
538
548 void resize(size_type count, const value_type& value) {
549 deque_.resize(count, value);
550 }
551
556 [[nodiscard]] bool try_resize(size_type count) {
557 return deque_.try_resize(count);
558 }
559
566 [[nodiscard]] bool try_resize(size_type count, const value_type& value) {
567 return deque_.try_resize(count, value);
568 }
569
571 void clear() { deque_.clear(); }
572
574 void reset() { deque_.reset(); }
575
579 void swap(DynamicVector& other) { deque_.swap(other.deque_); }
580
581 private:
582 typename DynamicDeque<T, size_type>::const_iterator ToDequeIterator(
583 const_iterator it) const {
584 return {deque_, static_cast<size_type>(it - cbegin())};
585 }
586
587 // The underlying DynamicDeque instance that provides the storage.
588 DynamicDeque<T, size_type> deque_;
589};
590
591} // namespace pw
Definition: allocator.h:42
bool try_assign(size_type count, const value_type &value)
Definition: generic_deque.h:691
Definition: dynamic_vector.h:63
Definition: ptr_iterator.h:164
Definition: ptr_iterator.h:142
void reserve(size_type new_capacity)
Increases capacity() to at least new_capacity. Crashes on failure.
Definition: dynamic_deque.h:162
void reserve_exact(size_type new_capacity)
Increases capacity() to exactly new_capacity. Crashes on failure.
Definition: dynamic_deque.h:178
void swap(DynamicDeque &other) noexcept
Swaps the contents of two deques. No allocations occur.
Definition: dynamic_deque.h:208
bool try_reserve(size_type new_capacity)
Definition: dynamic_deque.h:283
void shrink_to_fit()
Definition: dynamic_deque.h:304
constexpr allocator_type & get_allocator() const
Returns the deque's allocator.
Definition: dynamic_deque.h:205
void reset()
Clears the deque and deallocates its buffer.
Definition: dynamic_deque.h:195
bool try_reserve_exact(size_type new_capacity)
Definition: dynamic_deque.h:173
std::optional< iterator > try_insert(const_iterator pos, T &&value)
Definition: dynamic_vector.h:440
iterator insert(const_iterator pos, InputIt first, InputIt last)
Definition: dynamic_vector.h:401
constexpr allocator_type & get_allocator() const
Returns the vector's allocator.
Definition: dynamic_vector.h:113
void clear()
Removes all elements from the vector.
Definition: dynamic_vector.h:571
size_type capacity() const
Definition: dynamic_vector.h:125
std::optional< iterator > try_insert(const_iterator pos, std::initializer_list< T > ilist)
Definition: dynamic_vector.h:500
bool try_resize(size_type count, const value_type &value)
Definition: dynamic_vector.h:566
bool try_emplace_back(Args &&... args)
Definition: dynamic_vector.h:317
reference at(size_type pos)
Definition: dynamic_vector.h:195
reference operator[](size_type pos)
Definition: dynamic_vector.h:178
bool try_reserve(size_type new_capacity)
Definition: dynamic_vector.h:153
std::optional< iterator > try_insert(const_iterator pos, InputIt first, InputIt last)
Definition: dynamic_vector.h:479
const_reference back() const
Definition: dynamic_vector.h:224
iterator insert(const_iterator pos, T &&value)
Definition: dynamic_vector.h:373
bool try_reserve_exact(size_type new_capacity)
Definition: dynamic_vector.h:163
void resize(size_type count)
Definition: dynamic_vector.h:537
void pop_back()
Definition: dynamic_vector.h:299
void emplace_back(Args &&... args)
Definition: dynamic_vector.h:306
std::optional< iterator > try_emplace(const_iterator pos, Args &&... args)
Definition: dynamic_vector.h:345
iterator insert(const_iterator pos, std::initializer_list< T > ilist)
Definition: dynamic_vector.h:415
iterator insert(const_iterator pos, size_type count, const T &value)
Definition: dynamic_vector.h:385
reference front()
Definition: dynamic_vector.h:209
reference back()
Definition: dynamic_vector.h:219
size_type max_size() const
Maximum possible value of size(), ignoring allocator limitations.
Definition: dynamic_vector.h:128
void reserve(size_type new_capacity)
Definition: dynamic_vector.h:135
const_reference operator[](size_type pos) const
Definition: dynamic_vector.h:186
const_pointer data() const
Definition: dynamic_vector.h:239
void resize(size_type count, const value_type &value)
Definition: dynamic_vector.h:548
bool try_push_back(value_type &&value)
Definition: dynamic_vector.h:292
iterator insert(const_iterator pos, const T &value)
Definition: dynamic_vector.h:362
std::optional< iterator > try_insert(const_iterator pos, const T &value)
Definition: dynamic_vector.h:427
void shrink_to_fit()
Reduces memory usage by releasing unused capacity.
Definition: dynamic_vector.h:168
void push_back(value_type &&value)
Definition: dynamic_vector.h:274
std::optional< iterator > try_insert(const_iterator pos, size_type count, const T &value)
Definition: dynamic_vector.h:456
const_reference front() const
Definition: dynamic_vector.h:214
constexpr DynamicVector(Allocator &allocator)
Definition: dynamic_vector.h:80
void push_back(const value_type &value)
Definition: dynamic_vector.h:268
bool try_push_back(const value_type &value)
Definition: dynamic_vector.h:282
void reserve_exact(size_type new_capacity)
Definition: dynamic_vector.h:142
iterator erase(const_iterator pos)
Definition: dynamic_vector.h:511
pointer data()
Definition: dynamic_vector.h:232
void reset()
Clears the deque and deallocates its buffer.
Definition: dynamic_vector.h:574
size_type size() const
Returns the number of elements in the vector.
Definition: dynamic_vector.h:121
const_reference at(size_type pos) const
Definition: dynamic_vector.h:204
iterator erase(const_iterator first, const_iterator last)
Definition: dynamic_vector.h:518
void assign(size_type count, const value_type &value)
Definition: dynamic_vector.h:247
bool empty() const
Checks if the vector is empty.
Definition: dynamic_vector.h:118
void swap(DynamicVector &other)
Definition: dynamic_vector.h:579
iterator emplace(const_iterator pos, Args &&... args)
Definition: dynamic_vector.h:329
void assign(std::initializer_list< T > init)
Definition: dynamic_vector.h:258
bool try_resize(size_type count)
Definition: dynamic_vector.h:556
The Pigweed namespace.
Definition: alignment.h:27