39 using internal_storage_value_type = std::conditional_t<std::is_same_v<type_t, bool>, std::uint8_t, type_t>;
40 using internal_storage_allocator_type =
typename std::allocator_traits<allocator_t>::template rebind_alloc<internal_storage_value_type>;
41 using internal_base_type = std::vector<internal_storage_value_type, internal_storage_allocator_type>;
43 class internal_iterator {
45 using iterator_base_type =
typename internal_base_type::iterator;
46 using iterator_category = std::random_access_iterator_tag;
52 internal_iterator() =
default;
53 explicit internal_iterator(iterator_base_type it) : it_(it) {}
56 pointer operator ->()
const {
return reinterpret_cast<pointer>(std::addressof(*it_));}
58 internal_iterator& operator ++() {++it_;
return *
this;}
59 internal_iterator operator ++(
int) {internal_iterator tmp(*
this); ++(*this);
return tmp;}
60 internal_iterator& operator --() {--it_;
return *
this;}
61 internal_iterator operator --(
int) {internal_iterator tmp(*
this); --(*this);
return tmp;}
64 internal_iterator operator +(
difference_type n)
const {
return internal_iterator(it_ +
n);}
66 internal_iterator operator -(
difference_type n)
const {
return internal_iterator(it_ -
n);}
71 bool operator ==(
const internal_iterator &
other)
const {
return it_ ==
other.it_;}
72 bool operator !=(
const internal_iterator &
other)
const {
return it_ !=
other.it_;}
73 bool operator <(
const internal_iterator &
other)
const {
return it_ <
other.it_;}
74 bool operator <=(
const internal_iterator &
other)
const {
return it_ <=
other.it_;}
75 bool operator >(
const internal_iterator &
other)
const {
return it_ >
other.it_;}
76 bool operator >=(
const internal_iterator &
other)
const {
return it_ >=
other.it_;}
78 iterator_base_type to_base_type()
const {
return it_;}
82 iterator_base_type it_;
85 class internal_const_iterator {
87 using iterator_base_type =
typename internal_base_type::const_iterator;
88 using iterator_category = std::random_access_iterator_tag;
94 internal_const_iterator() =
default;
95 explicit internal_const_iterator(iterator_base_type it) : it_(it) {}
96 internal_const_iterator(
const internal_iterator & it) : it_(it.it_) {}
99 pointer operator->()
const {
return reinterpret_cast<pointer>(std::addressof(*it_));}
101 internal_const_iterator& operator ++() {++it_;
return *
this;}
102 internal_const_iterator operator ++(
int) {internal_const_iterator tmp(*
this); ++(*this);
return tmp;}
103 internal_const_iterator& operator --() {--it_;
return *
this;}
104 internal_const_iterator operator --(
int) {internal_const_iterator tmp(*
this); --(*this);
return tmp;}
106 internal_const_iterator& operator +=(
difference_type n) {it_ +=
n;
return *
this;}
107 internal_const_iterator operator +(
difference_type n)
const {
return internal_const_iterator(it_ +
n);}
108 internal_const_iterator& operator -=(
difference_type n) {it_ -=
n;
return *
this;}
109 internal_const_iterator operator -(
difference_type n)
const {
return internal_const_iterator(it_ -
n);}
114 bool operator ==(
const internal_const_iterator &
other)
const {
return it_ ==
other.it_;}
115 bool operator !=(
const internal_const_iterator &
other)
const {
return it_ !=
other.it_;}
116 bool operator <(
const internal_const_iterator &
other)
const {
return it_ <
other.it_;}
117 bool operator <=(
const internal_const_iterator &
other)
const {
return it_ <=
other.it_;}
118 bool operator >(
const internal_const_iterator &
other)
const {
return it_ >
other.it_;}
119 bool operator >=(
const internal_const_iterator &
other)
const {
return it_ >=
other.it_;}
121 iterator_base_type to_base_type()
const {
return it_;}
125 iterator_base_type it_;
150 inline static constexpr size_type npos = std::numeric_limits<size_type>::max();
174 template<
typename input_iterator_t>
182 items_.reserve(items.size());
183 for (
const auto&
b : items)
184 items_.push_back(
b ? 1 : 0);
188 template<xtd::forward_iterable source_t>
197 [[nodiscard]]
auto back() ->
reference {
return at(
size() - 1);}
200 [[nodiscard]]
auto begin() noexcept ->
iterator {
return to_type_iterator(items_.begin());}
201 [[nodiscard]]
auto begin() const noexcept ->
const_iterator {
return to_type_iterator(items_.cbegin());}
203 [[nodiscard]]
auto capacity() const noexcept ->
size_type {
return items_.capacity();}
205 [[nodiscard]]
auto cbegin() const noexcept ->
const_iterator {
return to_type_iterator(items_.cbegin());}
206 [[nodiscard]]
auto cend() const noexcept ->
const_iterator {
return to_type_iterator(items_.cend()); }
211 [[nodiscard]]
auto data() noexcept ->
pointer {
return reinterpret_cast<pointer>(items_.data());}
214 [[nodiscard]]
auto empty() const noexcept ->
bool {
return items_.empty();}
216 [[nodiscard]]
auto end() noexcept ->
iterator {
return to_type_iterator(items_.end());}
217 [[nodiscard]]
auto end() const noexcept ->
const_iterator {
return to_type_iterator(items_.cend());}
219 [[nodiscard]]
auto front() ->
reference {
return at(0);}
222 [[nodiscard]]
auto items() const noexcept ->
const_base_type& {
return items_;}
223 [[nodiscard]]
auto items() noexcept ->
base_type& {
return items_;}
225 [[nodiscard]]
auto max_size() const noexcept ->
size_type {
return std::min(items_.max_size(),
npos / 2);}
233 [[nodiscard]]
auto size() const noexcept ->
size_type {
return items_.size();}
235 [[nodiscard]]
auto version() const noexcept ->
size_type {
return version_;}
241 auto assign(
size_type count,
const type_t& value) ->
void {++version_; items_.assign(count, value);}
242 template<
typename input_iterator_t>
243 auto assign(input_iterator_t
first, input_iterator_t
last) ->
void {++version_; items_.assign(
first,
last);}
244 auto assign(std::initializer_list<type_t> items) ->
void {++version_; items_.assign(items.begin(), items.end());}
249 auto clear() ->
void {++version_; items_.clear();}
251 template<
typename ...args_t>
252 auto emplace(
const_iterator pos, args_t&&... args) ->
iterator {++version_;
return to_type_iterator(items_.emplace(pos.to_base_type(), std::forward<args_t>(args)...));}
253 template<
typename ...args_t>
254 auto emplace_back(args_t&&... args) ->
reference {++version_;
return reinterpret_cast<reference>(items_.emplace_back(std::forward<args_t>(args)...));}
256 auto erase(
const_iterator pos) ->
iterator {++version_;
return to_type_iterator(items_.erase(pos.to_base_type()));}
259 auto get_allocator() const ->
allocator_type {
return items_.get_allocator();}
261 auto increment_version() noexcept ->
size_type {
return ++version_;}
263 auto insert(
const_iterator pos,
const type_t& value) ->
iterator {++version_;
return to_type_iterator(items_.insert(pos.to_base_type(), value));}
264 auto insert(
const_iterator pos, type_t&& value) ->
iterator {++version_;
return to_type_iterator(items_.insert(pos.to_base_type(), std::move(value)));}
265 auto insert(
const_iterator pos,
size_type count,
const type_t& value) ->
iterator {++version_;
return to_type_iterator(items_.insert(pos.to_base_type(), count, value));}
266 auto insert(
const_iterator pos,
size_type count, type_t&& value) ->
iterator {++version_;
return to_type_iterator(items_.insert(pos.to_base_type(), count, std::move(value)));}
267 template<
typename input_iterator_t>
269 auto insert(
const_iterator pos,
const std::initializer_list<type_t>& items) ->
iterator {++version_;
return to_type_iterator(items_.insert(pos.to_base_type(), items.begin(), items.end()));}
271 auto pop_back() ->
void {++version_; items_.pop_back();}
272 auto push_back(
const type_t& value) ->
void {++version_; items_.push_back(value);}
273 auto push_back(type_t&& value) ->
void {++version_; items_.push_back(std::move(value));}
275 auto reserve(
size_type new_cap) ->
void {++version_; items_.reserve(new_cap);}
278 auto resize(
size_type count,
const value_type & value) ->
void {++version_; items_.resize(count, value);}
280 auto shrink_to_fit() ->
void {++version_; items_.shrink_to_fit();}
289 auto operator =(std::initializer_list<type_t>& items) ->
raw_array&
requires(!std::is_same_v<type_t, bool>) {
294 auto operator =(std::initializer_list<bool>& items) ->
raw_array&
requires(std::is_same_v<type_t, bool>) {
297 items_.reserve(items.size());
298 for (
const auto&
b : items)
299 items_.push_back(
b ? 1 : 0);
304 return a.items() ==
b.items();
306 friend auto operator ==(
const raw_array<type_t>&
a,
const std::vector<type_t>&
b) ->
bool {
307 return a.items() ==
b;
309 friend auto operator ==(
const std::vector<type_t>&
a,
const raw_array<type_t>&
b) ->
bool {
310 return a ==
b.items();
314 return a.items() !=
b.items();
316 friend auto operator !=(
const raw_array<type_t>&
a,
const std::vector<type_t>&
b) ->
bool {
317 return a.items() !=
b;
319 friend auto operator !=(
const std::vector<type_t>&
a,
const raw_array<type_t>&
b) ->
bool {
320 return a !=
b.items();
326 auto operator [](
const xtd::index& index) ->
reference;
328 auto operator [](
const xtd::range& range) -> xtd::span<type_t>;
333 auto operator ()(
const xtd::index& index) ->
reference;
335 auto operator ()(
const xtd::range& range) -> xtd::span<type_t>;
337 operator const base_type& ()
const noexcept {
return items_;}
338 operator base_type& ()
noexcept {
return items_;}
342 auto to_type_iterator(
typename base_type::iterator it) ->
iterator {
return iterator(it); }