39 using value_type = type_t;
40 using storage_value_type = std::conditional_t<std::is_same_v<value_type, bool>, std::uint8_t, value_type >;
41 using storage_allocator_type =
typename std::allocator_traits<allocator_t>::template rebind_alloc<storage_value_type>;
42 using base_type = std::vector<storage_value_type, storage_allocator_type>;
43 using const_base_type =
const base_type;
44 using allocator_type =
typename base_type::allocator_type;
45 using size_type = size_t;
46 using difference_type = std::ptrdiff_t;
47 using reference = value_type&;
48 using const_reference =
const value_type&;
49 using pointer = value_type*;
50 using const_pointer =
const value_type*;
59 using iterator_base_type =
typename base_type::iterator;
60 using iterator_category = std::random_access_iterator_tag;
61 using value_type = type_t;
62 using difference_type = std::ptrdiff_t;
63 using pointer = type_t*;
64 using reference = type_t&;
67 explicit iterator(iterator_base_type it) : it_(it) {}
69 reference operator *()
const {
return reinterpret_cast<reference
>(*it_);}
70 pointer operator ->()
const {
return reinterpret_cast<pointer
>(std::addressof(*it_));}
72 iterator& operator ++() {++it_;
return *
this;}
73 iterator operator ++(
int) {iterator tmp(*
this); ++(*this);
return tmp;}
74 iterator& operator --() {--it_;
return *
this;}
75 iterator operator --(
int) {iterator tmp(*
this); --(*this);
return tmp;}
77 iterator& operator +=(difference_type
n) {it_ +=
n;
return *
this;}
78 iterator operator +(difference_type
n)
const {
return iterator(it_ +
n);}
79 iterator& operator -=(difference_type
n) {it_ -=
n;
return *
this;}
80 iterator operator -(difference_type
n)
const {
return iterator(it_ -
n);}
81 difference_type operator -(
const iterator &
other)
const {
return it_ -
other.it_;}
83 reference operator [](difference_type
n)
const {
return reinterpret_cast<reference
>(it_[
n]);}
85 bool operator ==(
const iterator &
other)
const {
return it_ ==
other.it_;}
86 bool operator !=(
const iterator &
other)
const {
return it_ !=
other.it_;}
87 bool operator <(
const iterator &
other)
const {
return it_ <
other.it_;}
88 bool operator <=(
const iterator &
other)
const {
return it_ <=
other.it_;}
89 bool operator >(
const iterator &
other)
const {
return it_ >
other.it_;}
90 bool operator >=(
const iterator &
other)
const {
return it_ >=
other.it_;}
92 iterator_base_type to_base_type()
const {
return it_;}
95 friend class raw_array;
96 iterator_base_type it_;
99 class const_iterator {
101 using iterator_base_type =
typename base_type::const_iterator;
102 using iterator_category = std::random_access_iterator_tag;
103 using value_type =
const type_t;
104 using difference_type = std::ptrdiff_t;
105 using pointer =
const type_t*;
106 using reference =
const type_t&;
108 const_iterator() =
default;
109 explicit const_iterator(iterator_base_type it) : it_(it) {}
110 const_iterator(
const iterator & it) : it_(it.it_) {}
112 reference operator*()
const {
return reinterpret_cast<reference
>(*it_);}
113 pointer operator->()
const {
return reinterpret_cast<pointer
>(std::addressof(*it_));}
115 const_iterator& operator ++() {++it_;
return *
this;}
116 const_iterator operator ++(
int) {const_iterator tmp(*
this); ++(*this);
return tmp;}
117 const_iterator& operator --() {--it_;
return *
this;}
118 const_iterator operator --(
int) {const_iterator tmp(*
this); --(*this);
return tmp;}
120 const_iterator& operator +=(difference_type
n) {it_ +=
n;
return *
this;}
121 const_iterator operator +(difference_type
n)
const {
return const_iterator(it_ +
n);}
122 const_iterator& operator -=(difference_type
n) {it_ -=
n;
return *
this;}
123 const_iterator operator -(difference_type
n)
const {
return const_iterator(it_ -
n);}
124 difference_type operator -(
const const_iterator &
other)
const {
return it_ -
other.it_;}
126 reference operator [](difference_type
n)
const {
return reinterpret_cast<reference
>(it_[
n]);}
128 bool operator ==(
const const_iterator &
other)
const {
return it_ ==
other.it_;}
129 bool operator !=(
const const_iterator &
other)
const {
return it_ !=
other.it_;}
130 bool operator <(
const const_iterator &
other)
const {
return it_ <
other.it_;}
131 bool operator <=(
const const_iterator &
other)
const {
return it_ <=
other.it_;}
132 bool operator >(
const const_iterator &
other)
const {
return it_ >
other.it_;}
133 bool operator >=(
const const_iterator &
other)
const {
return it_ >=
other.it_;}
135 iterator_base_type to_base_type()
const {
return it_;}
138 friend class raw_array;
139 iterator_base_type it_;
141 using reverse_iterator = std::reverse_iterator<iterator>;
142 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
148 inline static constexpr size_type npos = std::numeric_limits<size_type>::max();
149 static inline constexpr size_type bpos = 0;
150 static inline constexpr size_type epos = npos - 1;
156 raw_array() noexcept = default;
157 explicit raw_array(const allocator_type & alloc) noexcept : items_(alloc) {}
158 raw_array(size_type count,
const type_t& value,
const allocator_type& alloc = allocator_type()) : items_(count, value, alloc) {}
159 explicit raw_array(size_type count,
const allocator_type& alloc = allocator_type()) : items_(count, alloc) {}
160 template<
class input_iterator_t>
161 raw_array(input_iterator_t
first, input_iterator_t
last,
const allocator_type& alloc = allocator_type()) : items_(
first,
last, alloc) {}
162 raw_array(
const raw_array & vector) : items_(vector.items_) {}
163 raw_array(
const base_type & vector) : items_(vector) {}
164 raw_array(
const raw_array & vector,
const allocator_type & alloc) : items_(vector.items_, alloc) {}
165 raw_array(
const base_type & vector,
const allocator_type & alloc) : items_(vector, alloc) {}
166 raw_array(std::initializer_list<type_t> items,
const allocator_type& alloc = allocator_type())
requires(!std::is_same_v<type_t, bool>) : items_(items, alloc) {}
167 raw_array(std::initializer_list<bool> items,
const allocator_type& alloc = allocator_type())
requires(std::is_same_v<type_t, bool>) : items_(alloc) {
168 items_.reserve(items.size());
170 items_.push_back(
b ? 1 : 0);
172 raw_array(raw_array&&
other) : items_(std::move(
other.items_)) {}
173 raw_array(base_type&&
other) : items_(std::move(
other)) {}
174 raw_array(raw_array&&
other,
const allocator_type & alloc) : items_(std::move(
other.items_), alloc) {}
175 raw_array(base_type&&
other,
const allocator_type & alloc) : items_(std::move(
other), alloc) {}
181 reference back() {
return at(size() - 1);}
182 const_reference back()
const {
return at(size() - 1);}
184 iterator begin() noexcept {
return to_type_iterator(items_.begin());}
185 const_iterator begin() const noexcept {
return to_type_iterator(items_.cbegin());}
187 size_type capacity() const noexcept {
return items_.capacity();}
189 const_iterator cbegin() const noexcept {
return to_type_iterator(items_.cbegin());}
190 const_iterator cend() const noexcept {
return to_type_iterator(items_.cend()); }
192 const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator(end());}
193 const_reverse_iterator crend() const noexcept {
return const_reverse_iterator(begin());}
195 pointer data() noexcept {
return reinterpret_cast<pointer
>(items_.data());}
196 const_pointer data() const noexcept {
return reinterpret_cast<const_pointer
>(items_.data());}
198 bool empty() const noexcept {
return items_.empty();}
200 iterator end() noexcept {
return to_type_iterator(items_.end());}
201 const_iterator end() const noexcept {
return to_type_iterator(items_.cend());}
203 reference front() {
return at(0);}
204 const_reference front()
const {
return at(0);}
206 const_base_type& items() const noexcept {
return items_;}
207 base_type& items() noexcept {
return items_;}
209 size_type max_size() const noexcept {
return std::min(items_.max_size(), npos / 2);}
211 reverse_iterator rbegin() noexcept {
return reverse_iterator(end());}
212 const_reverse_iterator rbegin() const noexcept {
return const_reverse_iterator(end());}
214 reverse_iterator rend() noexcept {
return reverse_iterator(begin());}
215 const_reverse_iterator rend() const noexcept {
return const_reverse_iterator(begin());}
217 size_type size() const noexcept {
return items_.size();}
219 size_type version() const noexcept {
return version_;}
225 void assign(size_type count,
const type_t& value) {
227 items_.assign(count, value);
229 template<
class input_iterator_t>
230 void assign(input_iterator_t
first, input_iterator_t
last) {
234 void assign(std::initializer_list<type_t> items) {
236 items_.assign(items.begin(), items.end());
239 reference at(size_type index) {
return reinterpret_cast<reference
>(items_.at(index > npos / 2 ? size() - (npos - index) : index));}
240 const_reference at(size_type index)
const {
return reinterpret_cast<const_reference
>(items_.at(index > npos / 2 ? size() - (npos - index) : index));}
247 template<
class ...args_t>
250 return to_type_iterator(items_.emplace(pos.to_base_type(), std::forward<args_t>(args)...));
252 template<
class ...args_t>
253 reference emplace_back(args_t&&... args) {
255 return reinterpret_cast<reference
>(items_.emplace_back(std::forward<args_t>(args)...));
260 return to_type_iterator(items_.erase(pos.to_base_type()));
264 return to_type_iterator(items_.erase(
first.to_base_type(),
last.to_base_type()));
267 allocator_type get_allocator()
const {
return items_.get_allocator();}
269 size_type increment_version() noexcept {
return ++version_;}
273 return to_type_iterator(items_.insert(pos.to_base_type(), value));
277 return to_type_iterator(items_.insert(pos.to_base_type(), std::move(value)));
281 return to_type_iterator(items_.insert(pos.to_base_type(), count, value));
285 return to_type_iterator(items_.insert(pos.to_base_type(), count, std::move(value)));
287 template<
class input_iterator_t>
290 return to_type_iterator(items_.insert(pos.to_base_type(),
first,
last));
294 return to_type_iterator(items_.insert(pos.to_base_type(), items.begin(), items.end()));
301 void push_back(
const type_t& value) {
303 items_.push_back(value);
305 void push_back(type_t&& value) {
307 items_.push_back(std::move(value));
310 void reserve(size_type new_cap) {items_.reserve(new_cap);}
312 void resize(size_type count) {
314 resize(count, value_type {});
316 void resize(size_type count,
const value_type & value) {
318 items_.resize(count, value);
321 void shrink_to_fit() {items_.shrink_to_fit();}
323 void swap(raw_array &
other)
noexcept {
325 items_.swap(
other.items_);
331 raw_array& operator =(
const raw_array &
other) =
default;
332 raw_array& operator =(raw_array&&
other)
noexcept =
default;
333 raw_array& operator =(std::initializer_list<type_t>& items)
requires(!std::is_same_v<type_t, bool>) {
338 raw_array& operator =(std::initializer_list<bool>& items)
requires(std::is_same_v<type_t, bool>) {
341 items_.reserve(items.size());
343 items_.push_back(
b ? 1 : 0);
347 friend bool operator ==(
const raw_array<type_t>&
a,
const raw_array<type_t>&
b) {
348 return a.items() ==
b.items();
350 friend bool operator ==(
const raw_array<type_t>&
a,
const std::vector<type_t>&
b) {
351 return a.items() ==
b;
353 friend bool operator ==(
const std::vector<type_t>&
a,
const raw_array<type_t>&
b) {
354 return a ==
b.items();
357 friend bool operator !=(
const raw_array<type_t>&
a,
const raw_array<type_t>&
b) {
358 return a.items() !=
b.items();
360 friend bool operator !=(
const raw_array<type_t>&
a,
const std::vector<type_t>&
b) {
361 return a.items() !=
b;
363 friend bool operator !=(
const std::vector<type_t>&
a,
const raw_array<type_t>&
b) {
364 return a !=
b.items();
367 const_reference operator [](size_type index)
const {
return at(index);}
368 reference operator [](size_type index) {
return at(index);}
370 operator const base_type& ()
const noexcept {
return items_;}
371 operator base_type& ()
noexcept {
return items_;}
375 iterator to_type_iterator(
typename base_type::iterator it) {
return iterator(it); }
379 size_type version_ = 0;