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 {
33 template<class type_t, class allocator_t = std::allocator<type_t>>
34 class raw_array {
35 public:
37
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*;
52
54
56 //using iterator = typename base_type::iterator;
57 class iterator {
58 public:
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&;
65
66 iterator() = default;
67 explicit iterator(iterator_base_type it) : it_(it) {}
68
69 reference operator *() const {return reinterpret_cast<reference>(*it_);}
70 pointer operator ->() const {return reinterpret_cast<pointer>(std::addressof(*it_));}
71
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;}
76
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_;}
82
83 reference operator [](difference_type n) const {return reinterpret_cast<reference>(it_[n]);}
84
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_;}
91
92 iterator_base_type to_base_type() const {return it_;}
93
94 private:
95 friend class raw_array;
96 iterator_base_type it_;
97 };
98 //using const_iterator = typename base_type::const_iterator;
99 class const_iterator {
100 public:
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&;
107
108 const_iterator() = default;
109 explicit const_iterator(iterator_base_type it) : it_(it) {}
110 const_iterator(const iterator & it) : it_(it.it_) {}
111
112 reference operator*() const {return reinterpret_cast<reference>(*it_);}
113 pointer operator->() const {return reinterpret_cast<pointer>(std::addressof(*it_));}
114
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;}
119
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_;}
125
126 reference operator [](difference_type n) const { return reinterpret_cast<reference>(it_[n]);}
127
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_;}
134
135 iterator_base_type to_base_type() const {return it_;}
136
137 private:
138 friend class raw_array;
139 iterator_base_type it_;
140 };
141 using reverse_iterator = std::reverse_iterator<iterator>;
142 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
144
146
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;
152
154
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());
169 for (auto b : items)
170 items_.push_back(b ? 1 : 0);
171 }
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) {}
177
179
181 reference back() {return at(size() - 1);}
182 const_reference back() const {return at(size() - 1);}
183
184 iterator begin() noexcept {return to_type_iterator(items_.begin());}
185 const_iterator begin() const noexcept {return to_type_iterator(items_.cbegin());}
186
187 size_type capacity() const noexcept {return items_.capacity();}
188
189 const_iterator cbegin() const noexcept {return to_type_iterator(items_.cbegin());}
190 const_iterator cend() const noexcept {return to_type_iterator(items_.cend()); }
191
192 const_reverse_iterator crbegin() const noexcept {return const_reverse_iterator(end());}
193 const_reverse_iterator crend() const noexcept {return const_reverse_iterator(begin());}
194
195 pointer data() noexcept {return reinterpret_cast<pointer>(items_.data());}
196 const_pointer data() const noexcept {return reinterpret_cast<const_pointer>(items_.data());}
197
198 bool empty() const noexcept {return items_.empty();}
199
200 iterator end() noexcept {return to_type_iterator(items_.end());}
201 const_iterator end() const noexcept {return to_type_iterator(items_.cend());}
202
203 reference front() {return at(0);}
204 const_reference front() const {return at(0);}
205
206 const_base_type& items() const noexcept {return items_;}
207 base_type& items() noexcept {return items_;}
208
209 size_type max_size() const noexcept {return std::min(items_.max_size(), npos / 2);}
210
211 reverse_iterator rbegin() noexcept {return reverse_iterator(end());}
212 const_reverse_iterator rbegin() const noexcept {return const_reverse_iterator(end());}
213
214 reverse_iterator rend() noexcept {return reverse_iterator(begin());}
215 const_reverse_iterator rend() const noexcept {return const_reverse_iterator(begin());}
216
217 size_type size() const noexcept {return items_.size();}
218
219 size_type version() const noexcept {return version_;}
221
223
225 void assign(size_type count, const type_t& value) {
226 ++version_;
227 items_.assign(count, value);
228 }
229 template<class input_iterator_t>
230 void assign(input_iterator_t first, input_iterator_t last) {
231 ++version_;
232 items_.assign(first, last);
233 }
234 void assign(std::initializer_list<type_t> items) {
235 ++version_;
236 items_.assign(items.begin(), items.end());
237 }
238
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));}
241
242 void clear() {
243 ++version_;
244 items_.clear();
245 }
246
247 template<class ...args_t>
248 iterator emplace(const_iterator pos, args_t&&... args) {
249 ++version_;
250 return to_type_iterator(items_.emplace(pos.to_base_type(), std::forward<args_t>(args)...));
251 }
252 template<class ...args_t>
253 reference emplace_back(args_t&&... args) {
254 ++version_;
255 return reinterpret_cast<reference>(items_.emplace_back(std::forward<args_t>(args)...));
256 }
257
258 iterator erase(const_iterator pos) {
259 ++version_;
260 return to_type_iterator(items_.erase(pos.to_base_type()));
261 }
263 ++version_;
264 return to_type_iterator(items_.erase(first.to_base_type(), last.to_base_type()));
265 }
266
267 allocator_type get_allocator() const {return items_.get_allocator();}
268
269 size_type increment_version() noexcept {return ++version_;}
270
271 iterator insert(const_iterator pos, const type_t& value) {
272 ++version_;
273 return to_type_iterator(items_.insert(pos.to_base_type(), value));
274 }
275 iterator insert(const_iterator pos, type_t&& value) {
276 ++version_;
277 return to_type_iterator(items_.insert(pos.to_base_type(), std::move(value)));
278 }
279 iterator insert(const_iterator pos, size_type count, const type_t& value) {
280 ++version_;
281 return to_type_iterator(items_.insert(pos.to_base_type(), count, value));
282 }
283 iterator insert(const_iterator pos, size_type count, type_t&& value) {
284 ++version_;
285 return to_type_iterator(items_.insert(pos.to_base_type(), count, std::move(value)));
286 }
287 template<class input_iterator_t>
288 iterator insert(const_iterator pos, input_iterator_t first, input_iterator_t last) {
289 ++version_;
290 return to_type_iterator(items_.insert(pos.to_base_type(), first, last));
291 }
292 iterator insert(const_iterator pos, const std::initializer_list<type_t>& items) {
293 ++version_;
294 return to_type_iterator(items_.insert(pos.to_base_type(), items.begin(), items.end()));
295 }
296
297 void pop_back() {
298 ++version_;
299 items_.pop_back();
300 }
301 void push_back(const type_t& value) {
302 ++version_;
303 items_.push_back(value);
304 }
305 void push_back(type_t&& value) {
306 ++version_;
307 items_.push_back(std::move(value));
308 }
309
310 void reserve(size_type new_cap) {items_.reserve(new_cap);}
311
312 void resize(size_type count) {
313 ++version_;
314 resize(count, value_type {});
315 }
316 void resize(size_type count, const value_type & value) {
317 ++version_;
318 items_.resize(count, value);
319 }
320
321 void shrink_to_fit() {items_.shrink_to_fit();}
322
323 void swap(raw_array & other) noexcept {
324 ++version_;
325 items_.swap(other.items_);
326 }
328
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>) {
334 ++version_;
335 items_ = items;
336 return *this;
337 }
338 raw_array& operator =(std::initializer_list<bool>& items) requires(std::is_same_v<type_t, bool>) {
339 ++version_;
340 items_.clear();
341 items_.reserve(items.size());
342 for (auto b : items)
343 items_.push_back(b ? 1 : 0);
344 return *this;
345 }
346
347 friend bool operator ==(const raw_array<type_t>& a, const raw_array<type_t>& b) {
348 return a.items() == b.items();
349 }
350 friend bool operator ==(const raw_array<type_t>& a, const std::vector<type_t>& b) {
351 return a.items() == b;
352 }
353 friend bool operator ==(const std::vector<type_t>& a, const raw_array<type_t>& b) {
354 return a == b.items();
355 }
356
357 friend bool operator !=(const raw_array<type_t>& a, const raw_array<type_t>& b) {
358 return a.items() != b.items();
359 }
360 friend bool operator !=(const raw_array<type_t>& a, const std::vector<type_t>& b) {
361 return a.items() != b;
362 }
363 friend bool operator !=(const std::vector<type_t>& a, const raw_array<type_t>& b) {
364 return a != b.items();
365 }
366
367 const_reference operator [](size_type index) const {return at(index);}
368 reference operator [](size_type index) {return at(index);}
369
370 operator const base_type& () const noexcept {return items_;}
371 operator base_type& () noexcept {return items_;}
373
374 private:
375 iterator to_type_iterator(typename base_type::iterator it) { return iterator(it); }
376 const_iterator to_type_iterator(typename base_type::const_iterator it) const { return const_iterator(it); }
377
378 base_type items_;
379 size_type version_ = 0;
380 };
381
383 // Deduction guides for xtd::collections::generic::helpers::raw_array
384 // {
385 template<class type_t>
386 raw_array(std::initializer_list<type_t>) -> raw_array<type_t, std::allocator<type_t >>;
387
388 template<class type_t>
389 raw_array(const std::vector<type_t>&) -> raw_array<type_t, std::allocator<type_t >>;
390
391 template<class type_t, class allocator_t = std::allocator<type_t>>
393
394 template<class type_t>
395 raw_array(std::vector<type_t>&&) -> raw_array<type_t, std::allocator<type_t >>;
396
397 template<class type_t, class allocator_t = std::allocator<type_t>>
399 // }
401 }
402 }
403 }
404}
@ 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