xtd 0.2.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>
9
11namespace xtd {
13 namespace collections {
15 namespace generic {
17 namespace helpers {
28 template<class type_t, class allocator_t = std::allocator<type_t>>
29 class raw_array {
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>;
33
34 class internal_iterator {
35 public:
36 using iterator_base_type = typename internal_base_type::iterator;
37 using iterator_category = std::random_access_iterator_tag;
38 using value_type = type_t;
39 using difference_type = std::ptrdiff_t;
40 using pointer = type_t*;
41 using reference = type_t&;
42
43 internal_iterator() = default;
44 explicit internal_iterator(iterator_base_type it) : it_(it) {}
45
46 reference operator *() const {return reinterpret_cast<reference>(*it_);}
47 pointer operator ->() const {return reinterpret_cast<pointer>(std::addressof(*it_));}
48
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;}
53
54 internal_iterator& operator +=(difference_type n) {it_ += n; return *this;}
55 internal_iterator operator +(difference_type n) const {return internal_iterator(it_ + n);}
56 internal_iterator& operator -=(difference_type n) {it_ -= n; return *this;}
57 internal_iterator operator -(difference_type n) const {return internal_iterator(it_ - n);}
58 difference_type operator -(const internal_iterator & other) const {return it_ - other.it_;}
59
60 reference operator [](difference_type n) const {return reinterpret_cast<reference>(it_[n]);}
61
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_;}
68
69 iterator_base_type to_base_type() const {return it_;}
70
71 private:
72 friend class raw_array;
73 iterator_base_type it_;
74 };
75
76 class internal_const_iterator {
77 public:
78 using iterator_base_type = typename internal_base_type::const_iterator;
79 using iterator_category = std::random_access_iterator_tag;
80 using value_type = const type_t;
81 using difference_type = std::ptrdiff_t;
82 using pointer = const type_t*;
83 using reference = const type_t&;
84
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_) {}
88
89 reference operator*() const {return reinterpret_cast<reference>(*it_);}
90 pointer operator->() const {return reinterpret_cast<pointer>(std::addressof(*it_));}
91
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;}
96
97 internal_const_iterator& operator +=(difference_type n) {it_ += n; return *this;}
98 internal_const_iterator operator +(difference_type n) const {return internal_const_iterator(it_ + n);}
99 internal_const_iterator& operator -=(difference_type n) {it_ -= n; return *this;}
100 internal_const_iterator operator -(difference_type n) const {return internal_const_iterator(it_ - n);}
101 difference_type operator -(const internal_const_iterator & other) const {return it_ - other.it_;}
102
103 reference operator [](difference_type n) const { return reinterpret_cast<reference>(it_[n]);}
104
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_;}
111
112 iterator_base_type to_base_type() const {return it_;}
113
114 private:
115 friend class raw_array;
116 iterator_base_type it_;
117 };
118 public:
120
122 using value_type = type_t;
123 using base_type = internal_base_type;
125 using allocator_type = typename base_type::allocator_type;
126 using size_type = size_t;
127 using difference_type = std::ptrdiff_t;
131 using const_pointer = const value_type*;
132 using iterator = internal_iterator;
133 using const_iterator = internal_const_iterator;
134 using reverse_iterator = std::reverse_iterator<iterator>;
135 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
137
139
141 inline static constexpr size_type npos = std::numeric_limits<size_type>::max();
142 static inline constexpr size_type bpos = 0;
143 static inline constexpr size_type epos = npos - 1;
145
147
150 raw_array() noexcept = default;
153 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) {}
162 explicit raw_array(size_type count, const allocator_type& alloc = allocator_type()) : items_(count, alloc) {}
167 template<class input_iterator_t>
168 raw_array(input_iterator_t first, input_iterator_t last, const allocator_type& alloc = allocator_type()) : items_(first, last, alloc) {}
169 raw_array(const raw_array & vector) : items_(vector.items_) {}
170 raw_array(const base_type & vector) : items_(vector) {}
171 raw_array(const raw_array & vector, const allocator_type & alloc) : items_(vector.items_, alloc) {}
172 raw_array(const base_type & vector, const allocator_type & alloc) : items_(vector, alloc) {}
173 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) {}
174 raw_array(std::initializer_list<bool> items, const allocator_type& alloc = allocator_type()) requires(std::is_same_v<type_t, bool>) : items_(alloc) {
175 items_.reserve(items.size());
176 for (auto b : items)
177 items_.push_back(b ? 1 : 0);
178 }
179 raw_array(raw_array&& other) : items_(std::move(other.items_)) {}
180 raw_array(base_type&& other) : items_(std::move(other)) {}
181 raw_array(raw_array&& other, const allocator_type & alloc) : items_(std::move(other.items_), alloc) {}
182 raw_array(base_type&& other, const allocator_type & alloc) : items_(std::move(other), alloc) {}
184
186
188 reference back() {return at(size() - 1);}
189 const_reference back() const {return at(size() - 1);}
190
191 iterator begin() noexcept {return to_type_iterator(items_.begin());}
192 const_iterator begin() const noexcept {return to_type_iterator(items_.cbegin());}
193
194 size_type capacity() const noexcept {return items_.capacity();}
195
196 const_iterator cbegin() const noexcept {return to_type_iterator(items_.cbegin());}
197 const_iterator cend() const noexcept {return to_type_iterator(items_.cend()); }
198
199 const_reverse_iterator crbegin() const noexcept {return const_reverse_iterator(end());}
200 const_reverse_iterator crend() const noexcept {return const_reverse_iterator(begin());}
201
202 pointer data() noexcept {return reinterpret_cast<pointer>(items_.data());}
203 const_pointer data() const noexcept {return reinterpret_cast<const_pointer>(items_.data());}
204
205 bool empty() const noexcept {return items_.empty();}
206
207 iterator end() noexcept {return to_type_iterator(items_.end());}
208 const_iterator end() const noexcept {return to_type_iterator(items_.cend());}
209
210 reference front() {return at(0);}
211 const_reference front() const {return at(0);}
212
213 const_base_type& items() const noexcept {return items_;}
214 base_type& items() noexcept {return items_;}
215
216 size_type max_size() const noexcept {return std::min(items_.max_size(), npos / 2);}
217
218 reverse_iterator rbegin() noexcept {return reverse_iterator(end());}
219 const_reverse_iterator rbegin() const noexcept {return const_reverse_iterator(end());}
220
221 reverse_iterator rend() noexcept {return reverse_iterator(begin());}
222 const_reverse_iterator rend() const noexcept {return const_reverse_iterator(begin());}
223
224 size_type size() const noexcept {return items_.size();}
225
226 size_type version() const noexcept {return version_;}
228
230
232 void assign(size_type count, const type_t& value) {
233 ++version_;
234 items_.assign(count, value);
235 }
236 template<class input_iterator_t>
237 void assign(input_iterator_t first, input_iterator_t last) {
238 ++version_;
239 items_.assign(first, last);
240 }
241 void assign(std::initializer_list<type_t> items) {
242 ++version_;
243 items_.assign(items.begin(), items.end());
244 }
245
246 reference at(size_type index) {return reinterpret_cast<reference>(items_.at(index > npos / 2 ? size() - (npos - index) : index));}
247 const_reference at(size_type index) const {return reinterpret_cast<const_reference>(items_.at(index > npos / 2 ? size() - (npos - index) : index));}
248
249 void clear() {
250 ++version_;
251 items_.clear();
252 }
253
254 template<class ...args_t>
255 iterator emplace(const_iterator pos, args_t&&... args) {
256 ++version_;
257 return to_type_iterator(items_.emplace(pos.to_base_type(), std::forward<args_t>(args)...));
258 }
259 template<class ...args_t>
260 reference emplace_back(args_t&&... args) {
261 ++version_;
262 return reinterpret_cast<reference>(items_.emplace_back(std::forward<args_t>(args)...));
263 }
264
265 iterator erase(const_iterator pos) {
266 ++version_;
267 return to_type_iterator(items_.erase(pos.to_base_type()));
268 }
270 ++version_;
271 return to_type_iterator(items_.erase(first.to_base_type(), last.to_base_type()));
272 }
273
274 allocator_type get_allocator() const {return items_.get_allocator();}
275
276 size_type increment_version() noexcept {return ++version_;}
277
278 iterator insert(const_iterator pos, const type_t& value) {
279 ++version_;
280 return to_type_iterator(items_.insert(pos.to_base_type(), value));
281 }
282 iterator insert(const_iterator pos, type_t&& value) {
283 ++version_;
284 return to_type_iterator(items_.insert(pos.to_base_type(), std::move(value)));
285 }
286 iterator insert(const_iterator pos, size_type count, const type_t& value) {
287 ++version_;
288 return to_type_iterator(items_.insert(pos.to_base_type(), count, value));
289 }
290 iterator insert(const_iterator pos, size_type count, type_t&& value) {
291 ++version_;
292 return to_type_iterator(items_.insert(pos.to_base_type(), count, std::move(value)));
293 }
294 template<class input_iterator_t>
295 iterator insert(const_iterator pos, input_iterator_t first, input_iterator_t last) {
296 ++version_;
297 return to_type_iterator(items_.insert(pos.to_base_type(), first, last));
298 }
299 iterator insert(const_iterator pos, const std::initializer_list<type_t>& items) {
300 ++version_;
301 return to_type_iterator(items_.insert(pos.to_base_type(), items.begin(), items.end()));
302 }
303
304 void pop_back() {
305 ++version_;
306 items_.pop_back();
307 }
308 void push_back(const type_t& value) {
309 ++version_;
310 items_.push_back(value);
311 }
312 void push_back(type_t&& value) {
313 ++version_;
314 items_.push_back(std::move(value));
315 }
316
317 void reserve(size_type new_cap) {items_.reserve(new_cap);}
318
319 void resize(size_type count) {
320 ++version_;
321 resize(count, value_type {});
322 }
323 void resize(size_type count, const value_type & value) {
324 ++version_;
325 items_.resize(count, value);
326 }
327
328 void shrink_to_fit() {items_.shrink_to_fit();}
329
330 void swap(raw_array & other) noexcept {
331 ++version_;
332 items_.swap(other.items_);
333 }
335
338 raw_array& operator =(const raw_array & other) = default;
339 raw_array& operator =(raw_array&& other) noexcept = default;
340 raw_array& operator =(std::initializer_list<type_t>& items) requires(!std::is_same_v<type_t, bool>) {
341 ++version_;
342 items_ = items;
343 return *this;
344 }
345 raw_array& operator =(std::initializer_list<bool>& items) requires(std::is_same_v<type_t, bool>) {
346 ++version_;
347 items_.clear();
348 items_.reserve(items.size());
349 for (auto b : items)
350 items_.push_back(b ? 1 : 0);
351 return *this;
352 }
353
354 friend bool operator ==(const raw_array<type_t>& a, const raw_array<type_t>& b) {
355 return a.items() == b.items();
356 }
357 friend bool operator ==(const raw_array<type_t>& a, const std::vector<type_t>& b) {
358 return a.items() == b;
359 }
360 friend bool operator ==(const std::vector<type_t>& a, const raw_array<type_t>& b) {
361 return a == b.items();
362 }
363
364 friend bool operator !=(const raw_array<type_t>& a, const raw_array<type_t>& b) {
365 return a.items() != b.items();
366 }
367 friend bool operator !=(const raw_array<type_t>& a, const std::vector<type_t>& b) {
368 return a.items() != b;
369 }
370 friend bool operator !=(const std::vector<type_t>& a, const raw_array<type_t>& b) {
371 return a != b.items();
372 }
373
374 const_reference operator [](size_type index) const {return at(index);}
375 reference operator [](size_type index) {return at(index);}
376
377 operator const base_type& () const noexcept {return items_;}
378 operator base_type& () noexcept {return items_;}
380
381 private:
382 iterator to_type_iterator(typename base_type::iterator it) { return iterator(it); }
383 const_iterator to_type_iterator(typename base_type::const_iterator it) const { return const_iterator(it); }
384
385 base_type items_;
386 size_type version_ = 0;
387 };
388
390 // Deduction guides for xtd::collections::generic::helpers::raw_array
391 // {
392 template<class type_t>
393 raw_array(std::initializer_list<type_t>) -> raw_array<type_t, std::allocator<type_t >>;
394
395 template<class type_t>
396 raw_array(const std::vector<type_t>&) -> raw_array<type_t, std::allocator<type_t >>;
397
398 template<class type_t, class allocator_t = std::allocator<type_t>>
400
401 template<class type_t>
402 raw_array(std::vector<type_t>&&) -> raw_array<type_t, std::allocator<type_t >>;
403
404 template<class type_t, class allocator_t = std::allocator<type_t>>
406 // }
408 }
409 }
410 }
411}
Internal vector-like container used as a storage backend for xtd collections.
Definition raw_array.hpp:29
const value_type & const_reference
Const reference to element.
Definition raw_array.hpp:129
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:162
size_t size_type
Type used for sizes.
Definition raw_array.hpp:126
internal_const_iterator const_iterator
Const forward iterator for raw_array.
Definition raw_array.hpp:133
std::ptrdiff_t difference_type
Type used for differences between iterators.
Definition raw_array.hpp:127
static constexpr size_type npos
Represents an invalid index.
Definition raw_array.hpp:141
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:158
internal_base_type base_type
Underlying vector type.
Definition raw_array.hpp:123
internal_iterator iterator
Forward iterator for raw_array.
Definition raw_array.hpp:132
value_type * pointer
Pointer to element.
Definition raw_array.hpp:130
const base_type const_base_type
Const version of base_type.
Definition raw_array.hpp:124
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:168
static constexpr size_type bpos
Beginning position.
Definition raw_array.hpp:142
static constexpr size_type epos
End position.
Definition raw_array.hpp:143
value_type & reference
Reference to element.
Definition raw_array.hpp:128
std::reverse_iterator< const_iterator > const_reverse_iterator
Const reverse iterator.
Definition raw_array.hpp:135
typename base_type::allocator_type allocator_type
Allocator type.
Definition raw_array.hpp:125
type_t value_type
Type of the elements.
Definition raw_array.hpp:122
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator.
Definition raw_array.hpp:134
raw_array() noexcept=default
Create a new raw_array instance.
const value_type * const_pointer
Const pointer to element.
Definition raw_array.hpp:131
@ 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
@ insert
The INS (INSERT) key.
Definition console_key.hpp:62
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
read_only_span< type_t, count > first() const
Obtains a subspan consisting of the first count elements of the sequence.
Definition read_only_span.hpp:282
read_only_span< type_t, count > last() const
Obtains a subspan consisting of the last N elements of the sequence.
Definition read_only_span.hpp:307