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
248 void assign(size_type count, const value_type& value) {
249 deque_.assign(count, value);
250 }
251
252 [[nodiscard]] bool try_assign(size_type count, const value_type& value) {
253 return deque_.try_assign(count, value);
254 }
255
260 void assign(std::initializer_list<T> init) { deque_.assign(init); }
261
262 [[nodiscard]] bool try_assign(std::initializer_list<T> init) {
263 return deque_.try_assign(init);
264 }
265
270 void push_back(const value_type& value) { deque_.push_back(value); }
271
276 void push_back(value_type&& value) { deque_.push_back(std::move(value)); }
277
284 [[nodiscard]] bool try_push_back(const value_type& value) {
285 return deque_.try_push_back(value);
286 }
287
294 [[nodiscard]] bool try_push_back(value_type&& value) {
295 return deque_.try_push_back(std::move(value));
296 }
297
301 void pop_back() { deque_.pop_back(); }
302
307 template <typename... Args>
308 void emplace_back(Args&&... args) {
309 deque_.emplace_back(std::forward<Args>(args)...);
310 }
311
318 template <typename... Args>
319 [[nodiscard]] bool try_emplace_back(Args&&... args) {
320 return deque_.try_emplace_back(std::forward<Args>(args)...);
321 }
322
330 template <typename... Args>
331 iterator emplace(const_iterator pos, Args&&... args) {
332 auto deque_it = deque_.try_emplace_shift_right(ToDequeIterator(pos),
333 std::forward<Args>(args)...);
334 PW_ASSERT(deque_it.has_value());
335 return iterator(data() + deque_it->pos_);
336 }
337
346 template <typename... Args>
347 [[nodiscard]] std::optional<iterator> try_emplace(const_iterator pos,
348 Args&&... args) {
349 auto deque_it = deque_.try_emplace_shift_right(ToDequeIterator(pos),
350 std::forward<Args>(args)...);
351 if (!deque_it.has_value()) {
352 return std::nullopt;
353 }
354 return iterator(data() + deque_it->pos_);
355 }
356
364 iterator insert(const_iterator pos, const T& value) {
365 return emplace(pos, value);
366 }
367
376 return emplace(pos, std::move(value));
377 }
378
387 iterator insert(const_iterator pos, size_type count, const T& value) {
388 auto deque_it =
389 deque_.try_insert_shift_right(ToDequeIterator(pos), count, value);
390 PW_ASSERT(deque_it.has_value());
391 return iterator(data() + deque_it->pos_);
392 }
393
402 template <typename InputIt>
403 iterator insert(const_iterator pos, InputIt first, InputIt last) {
404 auto deque_it =
405 deque_.try_insert_shift_right(ToDequeIterator(pos), first, last);
406 PW_ASSERT(deque_it.has_value());
407 return iterator(data() + deque_it->pos_);
408 }
409
417 iterator insert(const_iterator pos, std::initializer_list<T> ilist) {
418 return insert(pos, ilist.begin(), ilist.end());
419 }
420
429 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
430 const T& value) {
431 return try_emplace(pos, value);
432 }
433
442 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
443 T&& value) {
444 return try_emplace(pos, std::move(value));
445 }
446
458 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
459 size_type count,
460 const T& value) {
461 auto deque_it =
462 deque_.try_insert_shift_right(ToDequeIterator(pos), count, value);
463 if (!deque_it.has_value()) {
464 return std::nullopt;
465 }
466 return iterator(data() + deque_it->pos_);
467 }
468
480 template <typename InputIt>
481 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
482 InputIt first,
483 InputIt last) {
484 auto deque_it =
485 deque_.try_insert_shift_right(ToDequeIterator(pos), first, last);
486 if (!deque_it.has_value()) {
487 return std::nullopt;
488 }
489 return iterator(data() + deque_it->pos_);
490 }
491
502 [[nodiscard]] std::optional<iterator> try_insert(
503 const_iterator pos, std::initializer_list<T> ilist) {
504 return try_insert(pos, ilist.begin(), ilist.end());
505 }
506
507 // TODO: b/424613355 - Implement insert, emplace
508
513 iterator erase(const_iterator pos) { return erase(pos, pos + 1); }
514
521 auto first_ptr = const_cast<pointer>(&*first);
522 if (first != last) {
523 std::move(const_cast<pointer>(&*last), data() + size(), first_ptr);
524 size_t items_to_pop = static_cast<SizeType>(last - first);
525 for (size_t i = 0; i < items_to_pop; ++i) {
526 deque_.pop_back();
527 }
528 }
529 return iterator(first_ptr);
530 }
531
539 void resize(size_type count) { deque_.resize(count); }
540
550 void resize(size_type count, const value_type& value) {
551 deque_.resize(count, value);
552 }
553
558 [[nodiscard]] bool try_resize(size_type count) {
559 return deque_.try_resize(count);
560 }
561
568 [[nodiscard]] bool try_resize(size_type count, const value_type& value) {
569 return deque_.try_resize(count, value);
570 }
571
573 void clear() { deque_.clear(); }
574
576 void reset() { deque_.reset(); }
577
581 void swap(DynamicVector& other) { deque_.swap(other.deque_); }
582
583 private:
584 typename DynamicDeque<T, size_type>::const_iterator ToDequeIterator(
585 const_iterator it) const {
586 return {deque_, static_cast<size_type>(it - cbegin())};
587 }
588
589 // The underlying DynamicDeque instance that provides the storage.
590 DynamicDeque<T, size_type> deque_;
591};
592
593} // namespace pw
Definition: allocator.h:42
bool try_assign(size_type count, const value_type &value)
Definition: generic_deque.h:618
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:157
void reserve_exact(size_type new_capacity)
Increases capacity() to exactly new_capacity. Crashes on failure.
Definition: dynamic_deque.h:173
void swap(DynamicDeque &other) noexcept
Swaps the contents of two deques. No allocations occur.
Definition: dynamic_deque.h:203
bool try_reserve(size_type new_capacity)
Definition: dynamic_deque.h:269
void shrink_to_fit()
Definition: dynamic_deque.h:290
constexpr allocator_type & get_allocator() const
Returns the deque's allocator.
Definition: dynamic_deque.h:200
void reset()
Clears the deque and deallocates its buffer.
Definition: dynamic_deque.h:190
bool try_reserve_exact(size_type new_capacity)
Definition: dynamic_deque.h:168
std::optional< iterator > try_insert(const_iterator pos, T &&value)
Definition: dynamic_vector.h:442
iterator insert(const_iterator pos, InputIt first, InputIt last)
Definition: dynamic_vector.h:403
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:573
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:502
bool try_resize(size_type count, const value_type &value)
Definition: dynamic_vector.h:568
bool try_emplace_back(Args &&... args)
Definition: dynamic_vector.h:319
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:481
const_reference back() const
Definition: dynamic_vector.h:224
iterator insert(const_iterator pos, T &&value)
Definition: dynamic_vector.h:375
bool try_reserve_exact(size_type new_capacity)
Definition: dynamic_vector.h:163
void resize(size_type count)
Definition: dynamic_vector.h:539
void pop_back()
Definition: dynamic_vector.h:301
void emplace_back(Args &&... args)
Definition: dynamic_vector.h:308
std::optional< iterator > try_emplace(const_iterator pos, Args &&... args)
Definition: dynamic_vector.h:347
iterator insert(const_iterator pos, std::initializer_list< T > ilist)
Definition: dynamic_vector.h:417
iterator insert(const_iterator pos, size_type count, const T &value)
Definition: dynamic_vector.h:387
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:550
bool try_push_back(value_type &&value)
Definition: dynamic_vector.h:294
iterator insert(const_iterator pos, const T &value)
Definition: dynamic_vector.h:364
std::optional< iterator > try_insert(const_iterator pos, const T &value)
Definition: dynamic_vector.h:429
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:276
std::optional< iterator > try_insert(const_iterator pos, size_type count, const T &value)
Definition: dynamic_vector.h:458
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:270
bool try_push_back(const value_type &value)
Definition: dynamic_vector.h:284
void reserve_exact(size_type new_capacity)
Definition: dynamic_vector.h:142
iterator erase(const_iterator pos)
Definition: dynamic_vector.h:513
pointer data()
Definition: dynamic_vector.h:232
void reset()
Clears the deque and deallocates its buffer.
Definition: dynamic_vector.h:576
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:520
void assign(size_type count, const value_type &value)
Definition: dynamic_vector.h:248
bool empty() const
Checks if the vector is empty.
Definition: dynamic_vector.h:118
void swap(DynamicVector &other)
Definition: dynamic_vector.h:581
iterator emplace(const_iterator pos, Args &&... args)
Definition: dynamic_vector.h:331
void assign(std::initializer_list< T > init)
Definition: dynamic_vector.h:260
bool try_resize(size_type count)
Definition: dynamic_vector.h:558
The Pigweed namespace.
Definition: alignment.h:27