30 using internal_storage_value_type = std::conditional_t<std::is_same_v<type_t, bool>, std::uint8_t, type_t>;
31 using internal_storage_allocator_type =
typename std::allocator_traits<allocator_t>::template rebind_alloc<internal_storage_value_type>;
32 using internal_base_type = std::vector<internal_storage_value_type, internal_storage_allocator_type>;
34 class internal_iterator {
36 using iterator_base_type =
typename internal_base_type::iterator;
37 using iterator_category = std::random_access_iterator_tag;
43 internal_iterator() =
default;
44 explicit internal_iterator(iterator_base_type it) : it_(it) {}
47 pointer operator ->()
const {
return reinterpret_cast<pointer>(std::addressof(*it_));}
49 internal_iterator& operator ++() {++it_;
return *
this;}
50 internal_iterator operator ++(
int) {internal_iterator tmp(*
this); ++(*this);
return tmp;}
51 internal_iterator& operator --() {--it_;
return *
this;}
52 internal_iterator operator --(
int) {internal_iterator tmp(*
this); --(*this);
return tmp;}
55 internal_iterator operator +(
difference_type n)
const {
return internal_iterator(it_ +
n);}
57 internal_iterator operator -(
difference_type n)
const {
return internal_iterator(it_ -
n);}
62 bool operator ==(
const internal_iterator &
other)
const {
return it_ ==
other.it_;}
63 bool operator !=(
const internal_iterator &
other)
const {
return it_ !=
other.it_;}
64 bool operator <(
const internal_iterator &
other)
const {
return it_ <
other.it_;}
65 bool operator <=(
const internal_iterator &
other)
const {
return it_ <=
other.it_;}
66 bool operator >(
const internal_iterator &
other)
const {
return it_ >
other.it_;}
67 bool operator >=(
const internal_iterator &
other)
const {
return it_ >=
other.it_;}
69 iterator_base_type to_base_type()
const {
return it_;}
73 iterator_base_type it_;
76 class internal_const_iterator {
78 using iterator_base_type =
typename internal_base_type::const_iterator;
79 using iterator_category = std::random_access_iterator_tag;
85 internal_const_iterator() =
default;
86 explicit internal_const_iterator(iterator_base_type it) : it_(it) {}
87 internal_const_iterator(
const internal_iterator & it) : it_(it.it_) {}
90 pointer operator->()
const {
return reinterpret_cast<pointer>(std::addressof(*it_));}
92 internal_const_iterator& operator ++() {++it_;
return *
this;}
93 internal_const_iterator operator ++(
int) {internal_const_iterator tmp(*
this); ++(*this);
return tmp;}
94 internal_const_iterator& operator --() {--it_;
return *
this;}
95 internal_const_iterator operator --(
int) {internal_const_iterator tmp(*
this); --(*this);
return tmp;}
98 internal_const_iterator operator +(
difference_type n)
const {
return internal_const_iterator(it_ +
n);}
100 internal_const_iterator operator -(
difference_type n)
const {
return internal_const_iterator(it_ -
n);}
105 bool operator ==(
const internal_const_iterator &
other)
const {
return it_ ==
other.it_;}
106 bool operator !=(
const internal_const_iterator &
other)
const {
return it_ !=
other.it_;}
107 bool operator <(
const internal_const_iterator &
other)
const {
return it_ <
other.it_;}
108 bool operator <=(
const internal_const_iterator &
other)
const {
return it_ <=
other.it_;}
109 bool operator >(
const internal_const_iterator &
other)
const {
return it_ >
other.it_;}
110 bool operator >=(
const internal_const_iterator &
other)
const {
return it_ >=
other.it_;}
112 iterator_base_type to_base_type()
const {
return it_;}
116 iterator_base_type it_;
141 inline static constexpr size_type npos = std::numeric_limits<size_type>::max();
167 template<
class input_iterator_t>
175 items_.reserve(items.size());
177 items_.push_back(
b ? 1 : 0);
188 reference back() {
return at(size() - 1);}
191 iterator begin() noexcept {
return to_type_iterator(items_.begin());}
192 const_iterator begin() const noexcept {
return to_type_iterator(items_.cbegin());}
194 size_type capacity() const noexcept {
return items_.capacity();}
196 const_iterator cbegin() const noexcept {
return to_type_iterator(items_.cbegin());}
197 const_iterator cend() const noexcept {
return to_type_iterator(items_.cend()); }
202 pointer data() noexcept {
return reinterpret_cast<pointer>(items_.data());}
205 bool empty() const noexcept {
return items_.empty();}
207 iterator end() noexcept {
return to_type_iterator(items_.end());}
208 const_iterator end() const noexcept {
return to_type_iterator(items_.cend());}
214 base_type& items() noexcept {
return items_;}
216 size_type max_size() const noexcept {
return std::min(items_.max_size(),
npos / 2);}
224 size_type size() const noexcept {
return items_.size();}
226 size_type version() const noexcept {
return version_;}
232 void assign(
size_type count,
const type_t& value) {
234 items_.assign(count, value);
236 template<
class input_iterator_t>
237 void assign(input_iterator_t
first, input_iterator_t
last) {
241 void assign(std::initializer_list<type_t> items) {
243 items_.assign(items.begin(), items.end());
254 template<
class ...args_t>
257 return to_type_iterator(items_.emplace(pos.to_base_type(), std::forward<args_t>(args)...));
259 template<
class ...args_t>
260 reference emplace_back(args_t&&... args) {
262 return reinterpret_cast<reference>(items_.emplace_back(std::forward<args_t>(args)...));
267 return to_type_iterator(items_.erase(pos.to_base_type()));
271 return to_type_iterator(items_.erase(
first.to_base_type(),
last.to_base_type()));
274 allocator_type get_allocator()
const {
return items_.get_allocator();}
276 size_type increment_version() noexcept {
return ++version_;}
280 return to_type_iterator(items_.insert(pos.to_base_type(), value));
284 return to_type_iterator(items_.insert(pos.to_base_type(), std::move(value)));
288 return to_type_iterator(items_.insert(pos.to_base_type(), count, value));
292 return to_type_iterator(items_.insert(pos.to_base_type(), count, std::move(value)));
294 template<
class input_iterator_t>
297 return to_type_iterator(items_.insert(pos.to_base_type(),
first,
last));
301 return to_type_iterator(items_.insert(pos.to_base_type(), items.begin(), items.end()));
308 void push_back(
const type_t& value) {
310 items_.push_back(value);
312 void push_back(type_t&& value) {
314 items_.push_back(std::move(value));
317 void reserve(
size_type new_cap) {items_.reserve(new_cap);}
325 items_.resize(count, value);
328 void shrink_to_fit() {items_.shrink_to_fit();}
332 items_.swap(
other.items_);
340 raw_array& operator =(std::initializer_list<type_t>& items)
requires(!std::is_same_v<type_t, bool>) {
345 raw_array& operator =(std::initializer_list<bool>& items)
requires(std::is_same_v<type_t, bool>) {
348 items_.reserve(items.size());
350 items_.push_back(
b ? 1 : 0);
355 return a.items() ==
b.items();
358 return a.items() ==
b;
361 return a ==
b.items();
365 return a.items() !=
b.items();
368 return a.items() !=
b;
371 return a !=
b.items();
377 operator const base_type& ()
const noexcept {
return items_;}
378 operator base_type& ()
noexcept {
return items_;}
382 iterator to_type_iterator(
typename base_type::iterator it) {
return iterator(it); }