19#include "pw_allocator/allocator.h"
20#include "pw_allocator/unique_ptr.h"
21#include "pw_containers/dynamic_vector.h"
49template <
typename T,
typename SizeType = u
int16_t>
53 using size_type = SizeType;
54 using difference_type = std::ptrdiff_t;
55 using reference = value_type&;
56 using const_reference =
const value_type&;
57 using pointer = value_type*;
58 using const_pointer =
const value_type*;
63 template <
bool kIsConst>
66 using iterator_category = std::random_access_iterator_tag;
68 using difference_type = std::ptrdiff_t;
69 using pointer = std::conditional_t<kIsConst, const T*, T*>;
70 using reference = std::conditional_t<kIsConst, const T&, T&>;
72 constexpr Iterator() =
default;
75 template <
bool kOtherConst,
76 typename = std::enable_if_t<kIsConst && !kOtherConst>>
77 constexpr Iterator(
const Iterator<kOtherConst>& other) : it_(other.it_) {}
79 reference operator*()
const {
return **it_; }
80 pointer operator->()
const {
return *it_; }
82 Iterator& operator++() {
86 Iterator operator++(
int) {
return Iterator(it_++); }
87 Iterator& operator--() {
91 Iterator operator--(
int) {
return Iterator(it_--); }
93 Iterator& operator+=(difference_type n) {
97 Iterator& operator-=(difference_type n) {
101 friend Iterator operator+(Iterator it, difference_type n) {
102 return Iterator(it.it_ + n);
104 friend Iterator operator+(difference_type n, Iterator it) {
105 return Iterator(it.it_ + n);
107 friend Iterator operator-(Iterator it, difference_type n) {
108 return Iterator(it.it_ - n);
110 friend difference_type operator-(Iterator lhs, Iterator rhs) {
111 return lhs.it_ - rhs.it_;
114 friend bool operator==(Iterator lhs, Iterator rhs) {
115 return lhs.it_ == rhs.it_;
117 friend bool operator!=(Iterator lhs, Iterator rhs) {
118 return lhs.it_ != rhs.it_;
120 friend bool operator<(Iterator lhs, Iterator rhs) {
121 return lhs.it_ < rhs.it_;
123 friend bool operator<=(Iterator lhs, Iterator rhs) {
124 return lhs.it_ <= rhs.it_;
126 friend bool operator>(Iterator lhs, Iterator rhs) {
127 return lhs.it_ > rhs.it_;
129 friend bool operator>=(Iterator lhs, Iterator rhs) {
130 return lhs.it_ >= rhs.it_;
133 reference operator[](difference_type n)
const {
return *(*
this + n); }
137 std::conditional_t<kIsConst,
141 explicit constexpr Iterator(BaseIterator it) : it_(it) {}
148 using iterator = Iterator<false>;
149 using const_iterator = Iterator<true>;
150 using reverse_iterator = std::reverse_iterator<iterator>;
151 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
155 : vector_(allocator) {}
159 DynamicPtrVector(
const DynamicPtrVector&) =
delete;
160 DynamicPtrVector& operator=(
const DynamicPtrVector&) =
delete;
162 DynamicPtrVector(DynamicPtrVector&& other)
noexcept =
default;
163 DynamicPtrVector& operator=(DynamicPtrVector&& other)
noexcept {
165 vector_ = std::move(other.vector_);
171 iterator begin() {
return iterator(vector_.begin()); }
172 const_iterator begin()
const {
return const_iterator(vector_.begin()); }
173 const_iterator cbegin()
const {
return begin(); }
175 iterator end() {
return iterator(vector_.end()); }
176 const_iterator end()
const {
return const_iterator(vector_.end()); }
177 const_iterator cend()
const {
return end(); }
179 reverse_iterator rbegin() {
return reverse_iterator(end()); }
180 const_reverse_iterator rbegin()
const {
181 return const_reverse_iterator(end());
183 const_reverse_iterator crbegin()
const {
return rbegin(); }
185 reverse_iterator rend() {
return reverse_iterator(begin()); }
186 const_reverse_iterator rend()
const {
187 return const_reverse_iterator(begin());
189 const_reverse_iterator crend()
const {
return rend(); }
193 allocator_type& get_allocator()
const {
return vector_.get_allocator(); }
194 [[nodiscard]]
bool empty()
const {
return vector_.empty(); }
195 size_type size()
const {
return vector_.size(); }
196 size_type ptr_capacity()
const {
return vector_.capacity(); }
197 size_type max_size()
const {
return vector_.max_size(); }
202 void reserve_ptr(size_type new_capacity) { vector_.reserve(new_capacity); }
206 vector_.reserve_exact(new_capacity);
213 return vector_.try_reserve(new_capacity);
217 return vector_.try_reserve_exact(new_capacity);
220 void shrink_to_fit() { vector_.shrink_to_fit(); }
224 reference operator[](size_type pos) {
return *vector_[pos]; }
225 const_reference operator[](size_type pos)
const {
return *vector_[pos]; }
227 reference at(size_type pos) {
return *vector_.at(pos); }
228 const_reference at(size_type pos)
const {
return *vector_.at(pos); }
230 reference front() {
return *vector_.front(); }
231 const_reference front()
const {
return *vector_.front(); }
233 reference back() {
return *vector_.back(); }
234 const_reference back()
const {
return *vector_.back(); }
238 T*
const*
data() {
return vector_.data(); }
239 const T*
const*
data()
const {
return vector_.data(); }
260 PW_ASSERT(value !=
nullptr);
261 if (value.deallocator()->IsEqual(get_allocator())) {
262 vector_.push_back(value.get());
271 T* ptr = vector_.back();
278 T* ptr =
const_cast<T*
>(pos.operator->());
280 vector_.erase(pos.it_);
293 template <
typename U = T,
typename... Args>
295 PW_ASSERT(try_emplace_back<U>(std::forward<Args>(args)...));
304 template <
typename U = T,
typename... Args>
306 return try_emplace<U>(end(), std::forward<Args>(args)...).has_value();
318 template <
typename U = T,
typename... Args>
319 iterator
emplace(const_iterator pos, Args&&... args) {
320 std::optional<iterator> res =
321 try_emplace<U>(pos, std::forward<Args>(args)...);
322 PW_ASSERT(res.has_value());
332 template <
typename U = T,
typename... Args>
333 [[nodiscard]] std::optional<iterator>
try_emplace(const_iterator pos,
336 std::is_same_v<T, U> ||
337 (std::is_base_of_v<T, U> && (std::is_trivially_destructible_v<U> ||
338 std::has_virtual_destructor_v<T>)),
339 "Objects must inherit from T and be either virtually or trivially "
342 const auto index = std::distance(vector_.cbegin(), pos.it_);
344 if (!vector_.try_reserve(vector_.size() + 1)) {
348 if (T* ptr = vector_.get_allocator().template New<U>(
349 std::forward<Args>(args)...);
352 return iterator(*vector_.try_insert(vector_.begin() + index, ptr));
357 iterator insert(const_iterator pos,
const T& value) {
360 iterator insert(const_iterator pos, T&& value) {
361 return emplace(pos, std::move(value));
370 PW_ASSERT(value !=
nullptr);
371 if (value.deallocator()->IsEqual(get_allocator())) {
372 iterator it = iterator(vector_.insert(pos.it_, value.get()));
377 iterator it =
emplace(pos, std::move(*value));
382 [[nodiscard]] std::optional<iterator> try_insert(const_iterator pos,
387 iterator erase(const_iterator pos) {
return erase(pos, pos + 1); }
389 iterator erase(const_iterator first, const_iterator last) {
391 for (
auto it = first; it != last; ++it) {
392 Delete(
const_cast<T*
>(it.operator->()));
394 return iterator(vector_.erase(first.it_, last.it_));
398 for (T* ptr : vector_) {
415 void swap(size_type first, size_type second) {
416 std::swap(vector_[first], vector_[second]);
421 void swap(const_iterator first, const_iterator second) {
422 std::swap(
const_cast<pointer&
>(*first.it_),
423 const_cast<pointer&
>(*second.it_));
427 void Delete(T* ptr) { vector_.get_allocator().Delete(ptr); }
429 DynamicVector<T*, SizeType> vector_;
Definition: allocator.h:42
Definition: dynamic_ptr_vector.h:50
Definition: unique_ptr.h:44
Definition: ptr_iterator.h:164
Definition: ptr_iterator.h:142
void Delete(T *ptr)
Definition: deallocator.h:248
void swap(const_iterator first, const_iterator second)
Definition: dynamic_ptr_vector.h:421
void reset()
Clears the deque and deallocates its buffer.
Definition: dynamic_ptr_vector.h:405
std::optional< iterator > try_emplace(const_iterator pos, Args &&... args)
Definition: dynamic_ptr_vector.h:333
void swap(size_type first, size_type second)
Definition: dynamic_ptr_vector.h:415
void emplace_back(Args &&... args)
Definition: dynamic_ptr_vector.h:294
void push_back(const T &value)
Appends a new element by copying value.
Definition: dynamic_ptr_vector.h:244
void push_back(UniquePtr< T > &&value)
Definition: dynamic_ptr_vector.h:259
bool try_emplace_back(Args &&... args)
Definition: dynamic_ptr_vector.h:305
void reserve_ptr_exact(size_type new_capacity)
Definition: dynamic_ptr_vector.h:205
void swap(DynamicPtrVector &other)
Swaps the contents of this DynamicPtrVector with another one.
Definition: dynamic_ptr_vector.h:411
iterator emplace(const_iterator pos, Args &&... args)
Definition: dynamic_ptr_vector.h:319
bool try_reserve_ptr(size_type new_capacity)
Definition: dynamic_ptr_vector.h:212
constexpr DynamicPtrVector(Allocator &allocator)
Constructs an empty DynamicPtrVector using the provided allocator.
Definition: dynamic_ptr_vector.h:154
bool try_reserve_ptr_exact(size_type new_capacity)
Definition: dynamic_ptr_vector.h:216
void push_back(T &&value)
Appends a new element by moving value.
Definition: dynamic_ptr_vector.h:247
iterator insert(const_iterator pos, UniquePtr< T > &&value)
Definition: dynamic_ptr_vector.h:369
pw::UniquePtr< T > take(const_iterator pos)
Removes the element at pos and returns it as a UniquePtr.
Definition: dynamic_ptr_vector.h:277
void reserve_ptr(size_type new_capacity)
Definition: dynamic_ptr_vector.h:202
bool try_push_back(const T &value)
Attempts to append a new element by copying value.
Definition: dynamic_ptr_vector.h:250
T *const * data()
Definition: dynamic_ptr_vector.h:238
The Pigweed namespace.
Definition: alignment.h:27