19#include "pw_allocator/allocator.h"
20#include "pw_allocator/unique_ptr.h"
21#include "pw_containers/dynamic_vector.h"
38template <
typename T,
typename SizeType = u
int16_t>
42 using size_type = SizeType;
43 using difference_type = std::ptrdiff_t;
44 using reference = value_type&;
45 using const_reference =
const value_type&;
46 using pointer = value_type*;
47 using const_pointer =
const value_type*;
52 template <
bool kIsConst>
55 using iterator_category = std::random_access_iterator_tag;
57 using difference_type = std::ptrdiff_t;
58 using pointer = std::conditional_t<kIsConst, const T*, T*>;
59 using reference = std::conditional_t<kIsConst, const T&, T&>;
61 constexpr Iterator() =
default;
64 template <
bool kOtherConst,
65 typename = std::enable_if_t<kIsConst && !kOtherConst>>
66 constexpr Iterator(
const Iterator<kOtherConst>& other) : it_(other.it_) {}
68 reference operator*()
const {
return **it_; }
69 pointer operator->()
const {
return *it_; }
71 Iterator& operator++() {
75 Iterator operator++(
int) {
return Iterator(it_++); }
76 Iterator& operator--() {
80 Iterator operator--(
int) {
return Iterator(it_--); }
82 Iterator& operator+=(difference_type n) {
86 Iterator& operator-=(difference_type n) {
90 friend Iterator operator+(Iterator it, difference_type n) {
91 return Iterator(it.it_ + n);
93 friend Iterator operator+(difference_type n, Iterator it) {
94 return Iterator(it.it_ + n);
96 friend Iterator operator-(Iterator it, difference_type n) {
97 return Iterator(it.it_ - n);
99 friend difference_type operator-(Iterator lhs, Iterator rhs) {
100 return lhs.it_ - rhs.it_;
103 friend bool operator==(Iterator lhs, Iterator rhs) {
104 return lhs.it_ == rhs.it_;
106 friend bool operator!=(Iterator lhs, Iterator rhs) {
107 return lhs.it_ != rhs.it_;
109 friend bool operator<(Iterator lhs, Iterator rhs) {
110 return lhs.it_ < rhs.it_;
112 friend bool operator<=(Iterator lhs, Iterator rhs) {
113 return lhs.it_ <= rhs.it_;
115 friend bool operator>(Iterator lhs, Iterator rhs) {
116 return lhs.it_ > rhs.it_;
118 friend bool operator>=(Iterator lhs, Iterator rhs) {
119 return lhs.it_ >= rhs.it_;
122 reference operator[](difference_type n)
const {
return *(*
this + n); }
126 std::conditional_t<kIsConst,
130 explicit constexpr Iterator(BaseIterator it) : it_(it) {}
137 using iterator = Iterator<false>;
138 using const_iterator = Iterator<true>;
139 using reverse_iterator = std::reverse_iterator<iterator>;
140 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
144 : vector_(allocator) {}
148 DynamicPtrVector(
const DynamicPtrVector&) =
delete;
149 DynamicPtrVector& operator=(
const DynamicPtrVector&) =
delete;
151 DynamicPtrVector(DynamicPtrVector&& other)
noexcept =
default;
152 DynamicPtrVector& operator=(DynamicPtrVector&& other)
noexcept {
154 vector_ = std::move(other.vector_);
160 iterator begin() {
return iterator(vector_.begin()); }
161 const_iterator begin()
const {
return const_iterator(vector_.begin()); }
162 const_iterator cbegin()
const {
return begin(); }
164 iterator end() {
return iterator(vector_.end()); }
165 const_iterator end()
const {
return const_iterator(vector_.end()); }
166 const_iterator cend()
const {
return end(); }
168 reverse_iterator rbegin() {
return reverse_iterator(end()); }
169 const_reverse_iterator rbegin()
const {
170 return const_reverse_iterator(end());
172 const_reverse_iterator crbegin()
const {
return rbegin(); }
174 reverse_iterator rend() {
return reverse_iterator(begin()); }
175 const_reverse_iterator rend()
const {
176 return const_reverse_iterator(begin());
178 const_reverse_iterator crend()
const {
return rend(); }
182 allocator_type& get_allocator()
const {
return vector_.get_allocator(); }
183 [[nodiscard]]
bool empty()
const {
return vector_.empty(); }
184 size_type size()
const {
return vector_.size(); }
185 size_type ptr_capacity()
const {
return vector_.capacity(); }
186 size_type max_size()
const {
return vector_.max_size(); }
191 void reserve_ptr(size_type new_capacity) { vector_.reserve(new_capacity); }
195 vector_.reserve_exact(new_capacity);
202 return vector_.try_reserve(new_capacity);
206 return vector_.try_reserve_exact(new_capacity);
209 void shrink_to_fit() { vector_.shrink_to_fit(); }
213 reference operator[](size_type pos) {
return *vector_[pos]; }
214 const_reference operator[](size_type pos)
const {
return *vector_[pos]; }
216 reference at(size_type pos) {
return *vector_.at(pos); }
217 const_reference at(size_type pos)
const {
return *vector_.at(pos); }
219 reference front() {
return *vector_.front(); }
220 const_reference front()
const {
return *vector_.front(); }
222 reference back() {
return *vector_.back(); }
223 const_reference back()
const {
return *vector_.back(); }
227 T*
const*
data() {
return vector_.data(); }
228 const T*
const*
data()
const {
return vector_.data(); }
249 T* ptr = vector_.back();
256 T* ptr =
const_cast<T*
>(pos.operator->());
258 vector_.erase(pos.it_);
271 template <
typename U = T,
typename... Args>
273 PW_ASSERT(try_emplace_back<U>(std::forward<Args>(args)...));
282 template <
typename U = T,
typename... Args>
284 return try_emplace<U>(end(), std::forward<Args>(args)...).has_value();
296 template <
typename U = T,
typename... Args>
297 iterator
emplace(const_iterator pos, Args&&... args) {
298 std::optional<iterator> res =
299 try_emplace<U>(pos, std::forward<Args>(args)...);
300 PW_ASSERT(res.has_value());
310 template <
typename U = T,
typename... Args>
311 [[nodiscard]] std::optional<iterator>
try_emplace(const_iterator pos,
314 std::is_same_v<T, U> ||
315 (std::is_base_of_v<T, U> && (std::is_trivially_destructible_v<U> ||
316 std::has_virtual_destructor_v<T>)),
317 "Objects must inherit from T and be either virtually or trivially "
320 const auto index = std::distance(vector_.cbegin(), pos.it_);
322 if (!vector_.try_reserve(vector_.size() + 1)) {
326 if (T* ptr = vector_.get_allocator().template New<U>(
327 std::forward<Args>(args)...);
330 return iterator(*vector_.try_insert(vector_.begin() + index, ptr));
335 iterator insert(const_iterator pos,
const T& value) {
338 iterator insert(const_iterator pos, T&& value) {
339 return emplace(pos, std::move(value));
342 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
346 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
351 iterator erase(const_iterator pos) {
return erase(pos, pos + 1); }
353 iterator erase(const_iterator first, const_iterator last) {
355 for (
auto it = first; it != last; ++it) {
356 Delete(
const_cast<T*
>(it.operator->()));
358 return iterator(vector_.erase(first.it_, last.it_));
362 for (T* ptr : vector_) {
369 void Delete(T* ptr) { vector_.get_allocator().Delete(ptr); }
371 DynamicVector<T*, SizeType> vector_;
Definition: allocator.h:43
Definition: dynamic_ptr_vector.h:39
Definition: unique_ptr.h:43
Definition: ptr_iterator.h:164
Definition: ptr_iterator.h:142
void Delete(T *ptr)
Definition: deallocator.h:284
std::optional< iterator > try_emplace(const_iterator pos, Args &&... args)
Definition: dynamic_ptr_vector.h:311
bool try_push_back(T &&value)
Attempts to append a new element by moving value.
Definition: dynamic_ptr_vector.h:244
void emplace_back(Args &&... args)
Definition: dynamic_ptr_vector.h:272
void push_back(const T &value)
Appends a new element by copying value.
Definition: dynamic_ptr_vector.h:233
bool try_emplace_back(Args &&... args)
Definition: dynamic_ptr_vector.h:283
void reserve_ptr_exact(size_type new_capacity)
Definition: dynamic_ptr_vector.h:194
iterator emplace(const_iterator pos, Args &&... args)
Definition: dynamic_ptr_vector.h:297
bool try_reserve_ptr(size_type new_capacity)
Definition: dynamic_ptr_vector.h:201
constexpr DynamicPtrVector(Allocator &allocator)
Constructs an empty DynamicPtrVector using the provided allocator.
Definition: dynamic_ptr_vector.h:143
bool try_reserve_ptr_exact(size_type new_capacity)
Definition: dynamic_ptr_vector.h:205
void push_back(T &&value)
Appends a new element by moving value.
Definition: dynamic_ptr_vector.h:236
pw::UniquePtr< T > take(const_iterator pos)
Removes the element at pos and returns it as a UniquePtr.
Definition: dynamic_ptr_vector.h:255
void reserve_ptr(size_type new_capacity)
Definition: dynamic_ptr_vector.h:191
bool try_push_back(const T &value)
Attempts to append a new element by copying value.
Definition: dynamic_ptr_vector.h:239
T *const * data()
Definition: dynamic_ptr_vector.h:227
The Pigweed namespace.
Definition: alignment.h:27