xtd 1.0.0
Loading...
Searching...
No Matches
raw_array.hpp
Go to the documentation of this file.
1
4#pragma once
5#include <algorithm>
6#include <cstdint>
7#include <limits>
8#include <vector>
10#define __XTD_CORE_INTERNAL__
12#undef __XTD_CORE_INTERNAL__
13
15namespace xtd {
17 struct index;
18 class range;
20
22 namespace collections {
24 namespace generic {
26 namespace helpers {
37 template<typename type_t, typename allocator_t = std::allocator<type_t>>
38 class raw_array {
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>;
42
43 class internal_iterator {
44 public:
45 using iterator_base_type = typename internal_base_type::iterator;
46 using iterator_category = std::random_access_iterator_tag;
47 using value_type = type_t;
48 using difference_type = std::ptrdiff_t;
49 using pointer = type_t*;
50 using reference = type_t&;
51
52 internal_iterator() = default;
53 explicit internal_iterator(iterator_base_type it) : it_(it) {}
54
55 reference operator *() const {return reinterpret_cast<reference>(*it_);}
56 pointer operator ->() const {return reinterpret_cast<pointer>(std::addressof(*it_));}
57
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;}
62
63 internal_iterator& operator +=(difference_type n) {it_ += n; return *this;}
64 internal_iterator operator +(difference_type n) const {return internal_iterator(it_ + n);}
65 internal_iterator& operator -=(difference_type n) {it_ -= n; return *this;}
66 internal_iterator operator -(difference_type n) const {return internal_iterator(it_ - n);}
67 difference_type operator -(const internal_iterator & other) const {return it_ - other.it_;}
68
69 reference operator [](difference_type n) const {return reinterpret_cast<reference>(it_[n]);}
70
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_;}
77
78 iterator_base_type to_base_type() const {return it_;}
79
80 private:
81 friend class raw_array;
82 iterator_base_type it_;
83 };
84
85 class internal_const_iterator {
86 public:
87 using iterator_base_type = typename internal_base_type::const_iterator;
88 using iterator_category = std::random_access_iterator_tag;
89 using value_type = const type_t;
90 using difference_type = std::ptrdiff_t;
91 using pointer = const type_t*;
92 using reference = const type_t&;
93
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_) {}
97
98 reference operator*() const {return reinterpret_cast<reference>(*it_);}
99 pointer operator->() const {return reinterpret_cast<pointer>(std::addressof(*it_));}
100
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;}
105
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);}
110 difference_type operator -(const internal_const_iterator & other) const {return it_ - other.it_;}
111
112 reference operator [](difference_type n) const { return reinterpret_cast<reference>(it_[n]);}
113
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_;}
120
121 iterator_base_type to_base_type() const {return it_;}
122
123 private:
124 friend class raw_array;
125 iterator_base_type it_;
126 };
127 public:
129
131 using value_type = type_t;
132 using base_type = internal_base_type;
134 using allocator_type = typename base_type::allocator_type;
135 using size_type = std::size_t;
136 using difference_type = std::ptrdiff_t;
140 using const_pointer = const value_type*;
141 using iterator = internal_iterator;
142 using const_iterator = internal_const_iterator;
143 using reverse_iterator = std::reverse_iterator<iterator>;
144 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
146
148
150 inline static constexpr size_type npos = std::numeric_limits<size_type>::max();
152
154
157 raw_array() noexcept = default;
160 explicit raw_array(const allocator_type & alloc) noexcept : items_(alloc) {}
165 raw_array(size_type count, const type_t& value, const allocator_type& alloc = allocator_type()) : items_(count, value, alloc) {}
169 explicit raw_array(size_type count, const allocator_type& alloc = allocator_type()) : items_(count, alloc) {}
174 template<typename input_iterator_t>
175 raw_array(input_iterator_t first, input_iterator_t last, const allocator_type& alloc = allocator_type()) : items_(first, last, alloc) {}
176 raw_array(const raw_array & vector) : items_(vector.items_) {}
177 raw_array(const base_type & vector) : items_(vector) {}
178 raw_array(const raw_array & vector, const allocator_type & alloc) : items_(vector.items_, alloc) {}
179 raw_array(const base_type & vector, const allocator_type & alloc) : items_(vector, alloc) {}
180 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) {}
181 raw_array(std::initializer_list<bool> items, const allocator_type& alloc = allocator_type()) requires(std::is_same_v<type_t, bool>) : items_(alloc) {
182 items_.reserve(items.size());
183 for (const auto& b : items)
184 items_.push_back(b ? 1 : 0);
185 }
186 raw_array(raw_array&& other) : items_(std::move(other.items_)) {}
187 raw_array(base_type&& other) : items_(std::move(other)) {}
188 template<xtd::forward_iterable source_t>
189 raw_array(source_t&& other) : items_(std::move(other)) {}
190 raw_array(raw_array&& other, const allocator_type & alloc) : items_(std::move(other.items_), alloc) {}
191 raw_array(base_type&& other, const allocator_type & alloc) : items_(std::move(other), alloc) {}
193
195
197 [[nodiscard]] auto back() -> reference {return at(size() - 1);}
198 [[nodiscard]] auto back() const -> const_reference {return at(size() - 1);}
199
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());}
202
203 [[nodiscard]] auto capacity() const noexcept -> size_type {return items_.capacity();}
204
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()); }
207
208 [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator {return const_reverse_iterator(end());}
209 [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator {return const_reverse_iterator(begin());}
210
211 [[nodiscard]] auto data() noexcept -> pointer {return reinterpret_cast<pointer>(items_.data());}
212 [[nodiscard]] auto data() const noexcept -> const_pointer {return reinterpret_cast<const_pointer>(items_.data());}
213
214 [[nodiscard]] auto empty() const noexcept -> bool {return items_.empty();}
215
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());}
218
219 [[nodiscard]] auto front() -> reference {return at(0);}
220 [[nodiscard]] auto front() const -> const_reference {return at(0);}
221
222 [[nodiscard]] auto items() const noexcept -> const_base_type& {return items_;}
223 [[nodiscard]] auto items() noexcept -> base_type& {return items_;}
224
225 [[nodiscard]] auto max_size() const noexcept -> size_type {return std::min(items_.max_size(), npos / 2);}
226
227 [[nodiscard]] auto rbegin() noexcept -> reverse_iterator {return reverse_iterator(end());}
228 [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator {return const_reverse_iterator(end());}
229
230 [[nodiscard]] auto rend() noexcept -> reverse_iterator {return reverse_iterator(begin());}
231 [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator {return const_reverse_iterator(begin());}
232
233 [[nodiscard]] auto size() const noexcept -> size_type {return items_.size();}
234
235 [[nodiscard]] auto version() const noexcept -> size_type {return version_;}
237
239
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());}
245
246 auto at(size_type index) -> reference {return reinterpret_cast<reference>(items_.at(index > npos / 2 ? size() - (npos - index) : index));}
247 auto at(size_type index) const -> const_reference {return reinterpret_cast<const_reference>(items_.at(index > npos / 2 ? size() - (npos - index) : index));}
248
249 auto clear() -> void {++version_; items_.clear();}
250
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)...));}
255
256 auto erase(const_iterator pos) -> iterator {++version_; return to_type_iterator(items_.erase(pos.to_base_type()));}
257 auto erase(const_iterator first, const_iterator last) -> iterator {++version_; return to_type_iterator(items_.erase(first.to_base_type(), last.to_base_type()));}
258
259 auto get_allocator() const -> allocator_type {return items_.get_allocator();}
260
261 auto increment_version() noexcept -> size_type {return ++version_;}
262
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>
268 auto insert(const_iterator pos, input_iterator_t first, input_iterator_t last) -> iterator {++version_; return to_type_iterator(items_.insert(pos.to_base_type(), first, last));}
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()));}
270
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));}
274
275 auto reserve(size_type new_cap) -> void {++version_; items_.reserve(new_cap);}
276
277 auto resize(size_type count) -> void {++version_; resize(count, value_type {});}
278 auto resize(size_type count, const value_type & value) -> void {++version_; items_.resize(count, value);}
279
280 auto shrink_to_fit() -> void {++version_; items_.shrink_to_fit();}
281
282 auto swap(raw_array & other) noexcept -> void {++version_; items_.swap(other.items_);}
284
287 auto operator =(const raw_array & other) -> raw_array& = default;
288 auto operator =(raw_array&& other) noexcept -> raw_array& = default;
289 auto operator =(std::initializer_list<type_t>& items) -> raw_array& requires(!std::is_same_v<type_t, bool>) {
290 ++version_;
291 items_ = items;
292 return *this;
293 }
294 auto operator =(std::initializer_list<bool>& items) -> raw_array& requires(std::is_same_v<type_t, bool>) {
295 ++version_;
296 items_.clear();
297 items_.reserve(items.size());
298 for (const auto& b : items)
299 items_.push_back(b ? 1 : 0);
300 return *this;
301 }
302
303 friend auto operator ==(const raw_array<type_t>& a, const raw_array<type_t>& b) -> bool {
304 return a.items() == b.items();
305 }
306 friend auto operator ==(const raw_array<type_t>& a, const std::vector<type_t>& b) -> bool {
307 return a.items() == b;
308 }
309 friend auto operator ==(const std::vector<type_t>& a, const raw_array<type_t>& b) -> bool {
310 return a == b.items();
311 }
312
313 friend auto operator !=(const raw_array<type_t>& a, const raw_array<type_t>& b) -> bool {
314 return a.items() != b.items();
315 }
316 friend auto operator !=(const raw_array<type_t>& a, const std::vector<type_t>& b) -> bool {
317 return a.items() != b;
318 }
319 friend auto operator !=(const std::vector<type_t>& a, const raw_array<type_t>& b) -> bool {
320 return a != b.items();
321 }
322
323 auto operator [](size_type index) const -> const_reference {return at(index);}
324 auto operator [](size_type index) -> reference {return at(index);}
325 auto operator [](const xtd::index& index) const -> const_reference;
326 auto operator [](const xtd::index& index) -> reference;
327 auto operator [](const xtd::range& range) const -> xtd::read_only_span<type_t>;
328 auto operator [](const xtd::range& range) -> xtd::span<type_t>;
329
330 auto operator ()(size_type index) const -> const_reference {return at(index);}
331 auto operator ()(size_type index) -> reference {return at(index);}
332 auto operator ()(const xtd::index& index) const -> const_reference;
333 auto operator ()(const xtd::index& index) -> reference;
334 auto operator ()(const xtd::range& range) const -> xtd::read_only_span<type_t>;
335 auto operator ()(const xtd::range& range) -> xtd::span<type_t>;
336
337 operator const base_type& () const noexcept {return items_;}
338 operator base_type& () noexcept {return items_;}
340
341 private:
342 auto to_type_iterator(typename base_type::iterator it) -> iterator { return iterator(it); }
343 auto to_type_iterator(typename base_type::const_iterator it) const -> const_iterator { return const_iterator(it); }
344
345 base_type items_;
346 size_type version_ = 0;
347 };
348
350 // Deduction guides for xtd::collections::generic::helpers::raw_array
351 // {
352 template<typename type_t>
353 raw_array(std::initializer_list<type_t>) -> raw_array<type_t, std::allocator<type_t >>;
354
355 template<typename type_t>
356 raw_array(const std::vector<type_t>&) -> raw_array<type_t, std::allocator<type_t >>;
357
358 template<typename type_t, typename allocator_t = std::allocator<type_t>>
360
361 template<typename type_t>
362 raw_array(std::vector<type_t>&&) -> raw_array<type_t, std::allocator<type_t >>;
363
364 template<typename type_t, typename allocator_t = std::allocator<type_t>>
366 // }
368 }
369 }
370 }
371}
Internal vector-like container used as a storage backend for xtd collections.
Definition raw_array.hpp:38
const value_type & const_reference
Const reference to element.
Definition raw_array.hpp:138
raw_array(size_type count, const allocator_type &alloc=allocator_type())
Create a new raw_array instance with specified count, and allocator.
Definition raw_array.hpp:169
internal_const_iterator const_iterator
Const forward iterator for raw_array.
Definition raw_array.hpp:142
std::ptrdiff_t difference_type
Type used for differences between iterators.
Definition raw_array.hpp:136
static constexpr size_type npos
Represents an invalid index.
Definition raw_array.hpp:150
raw_array(size_type count, const type_t &value, const allocator_type &alloc=allocator_type())
Create a new raw_array instance with specified count, value, and allocator.
Definition raw_array.hpp:165
internal_base_type base_type
Underlying vector type.
Definition raw_array.hpp:132
internal_iterator iterator
Forward iterator for raw_array.
Definition raw_array.hpp:141
value_type * pointer
Pointer to element.
Definition raw_array.hpp:139
const base_type const_base_type
Const version of base_type.
Definition raw_array.hpp:133
raw_array(input_iterator_t first, input_iterator_t last, const allocator_type &alloc=allocator_type())
Create a new raw_array instance with specified first iterator, last iterator, and allocator.
Definition raw_array.hpp:175
std::size_t size_type
Type used for sizes.
Definition raw_array.hpp:135
value_type & reference
Reference to element.
Definition raw_array.hpp:137
std::reverse_iterator< const_iterator > const_reverse_iterator
Const reverse iterator.
Definition raw_array.hpp:144
typename base_type::allocator_type allocator_type
Allocator type.
Definition raw_array.hpp:134
type_t value_type
Type of the elements.
Definition raw_array.hpp:131
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator.
Definition raw_array.hpp:143
raw_array() noexcept=default
Create a new raw_array instance.
const value_type * const_pointer
Const pointer to element.
Definition raw_array.hpp:140
Represents a range that has start and end indexes.
Definition range.hpp:28
Contains xtd::forward_iterable concept.
@ other
The operating system is other.
Definition platform_id.hpp:60
@ a
The A key.
Definition console_key.hpp:88
@ n
The N key.
Definition console_key.hpp:114
@ b
The B key.
Definition console_key.hpp:90
The xtd::collections::generic::helpers namespace contains helpers for generic collections,...
Definition allocator.hpp:14
The xtd::collections::generic namespace contains interfaces and classes that define generic collectio...
Definition comparer.hpp:16
The xtd::collections namespace contains interfaces and classes that define various collections of obj...
Definition any_pair.hpp:10
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8
auto first() const -> read_only_span< type_t, count >
Obtains a subspan consisting of the first count elements of the sequence.
Definition read_only_span.hpp:263
constexpr auto empty() const noexcept -> bool
Returns a value that indicates whether the current xtd::read_only_span <type_t> is empty.
Definition read_only_span.hpp:215
constexpr auto data() const noexcept -> const_pointer
Gets direct access to the underlying contiguous storage.
Definition read_only_span.hpp:211
auto last() const -> read_only_span< type_t, count >
Obtains a subspan consisting of the last N elements of the sequence.
Definition read_only_span.hpp:288
constexpr read_only_span()
Creates an empty xtd::read_only_span whose xtd::read_only_span::data is null and xtd::read_only_span:...
Definition read_only_span.hpp:89
constexpr auto size() const noexcept -> size_type
Returns the number of elements.
Definition read_only_span.hpp:231