xtd 0.2.0
Loading...
Searching...
No Matches
__xtd_raw_array_data.hpp
Go to the documentation of this file.
1
4#pragma once
6#if !defined(__XTD_CORE_INTERNAL__)
7#error "Do not include this file: Internal use only"
8#endif
10
11#include <algorithm>
12#include <cstdint>
13#include <limits>
14#include <vector>
15
32template<class type_t, class allocator_t = std::allocator<type_t>>
33class __xtd_raw_array_data__ {
34public:
37 using value_type = type_t;
38 using storage_value_type = std::conditional_t<std::is_same_v<value_type, bool>, std::uint8_t, value_type >;
39 using storage_allocator_type = typename std::allocator_traits<allocator_t>::template rebind_alloc<storage_value_type>;
40 using base_type = std::vector<storage_value_type, storage_allocator_type>;
41 using const_base_type = const base_type;
42 using allocator_type = typename base_type::allocator_type;
43 using size_type = size_t;
44 using difference_type = std::ptrdiff_t;
45 using reference = value_type&;
46 using const_reference = const value_type&;
47 using pointer = value_type*;
48 using const_pointer = const value_type*;
50
53 //using iterator = typename base_type::iterator;
54 class iterator {
55 public:
56 using iterator_base_type = typename base_type::iterator;
57 using iterator_category = std::random_access_iterator_tag;
58 using value_type = type_t;
59 using difference_type = std::ptrdiff_t;
60 using pointer = type_t*;
61 using reference = type_t&;
62
63 iterator() = default;
64 explicit iterator(iterator_base_type it) : it_(it) {}
65
66 reference operator *() const {return reinterpret_cast<reference>(*it_);}
67 pointer operator ->() const {return reinterpret_cast<pointer>(std::addressof(*it_));}
68
69 iterator & operator ++() {++it_; return *this;}
70 iterator operator ++(int) {iterator tmp(*this); ++(*this); return tmp;}
71 iterator & operator --() {--it_; return *this;}
72 iterator operator --(int) {iterator tmp(*this); --(*this); return tmp;}
73
74 iterator & operator +=(difference_type n) {it_ += n; return *this;}
75 iterator operator +(difference_type n) const {return iterator(it_ + n);}
76 iterator & operator -=(difference_type n) {it_ -= n; return *this;}
77 iterator operator -(difference_type n) const {return iterator(it_ - n);}
78 difference_type operator -(const iterator & other) const {return it_ - other.it_;}
79
80 reference operator [](difference_type n) const {return reinterpret_cast<reference>(it_[n]);}
81
82 bool operator ==(const iterator & other) const {return it_ == other.it_;}
83 bool operator !=(const iterator & other) const {return it_ != other.it_;}
84 bool operator <(const iterator & other) const {return it_ < other.it_;}
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
89 iterator_base_type to_base_type() const {return it_;}
90
91 private:
92 friend class __xtd_raw_array_data__;
93 iterator_base_type it_;
94 };
95 //using const_iterator = typename base_type::const_iterator;
96 class const_iterator {
97 public:
98 using iterator_base_type = typename base_type::const_iterator;
99 using iterator_category = std::random_access_iterator_tag;
100 using value_type = const type_t;
101 using difference_type = std::ptrdiff_t;
102 using pointer = const type_t*;
103 using reference = const type_t&;
104
105 const_iterator() = default;
106 explicit const_iterator(iterator_base_type it) : it_(it) {}
107 const_iterator(const iterator & it) : it_(it.it_) {}
108
109 reference operator*() const {return reinterpret_cast<reference>(*it_);}
110 pointer operator->() const {return reinterpret_cast<pointer>(std::addressof(*it_));}
111
112 const_iterator & operator ++() {++it_; return *this;}
113 const_iterator operator ++(int) {const_iterator tmp(*this); ++(*this); return tmp;}
114 const_iterator & operator --() {--it_; return *this;}
115 const_iterator operator --(int) {const_iterator tmp(*this); --(*this); return tmp;}
116
117 const_iterator & operator +=(difference_type n) {it_ += n; return *this;}
118 const_iterator operator +(difference_type n) const {return const_iterator(it_ + n);}
119 const_iterator & operator -=(difference_type n) {it_ -= n; return *this;}
120 const_iterator operator -(difference_type n) const {return const_iterator(it_ - n);}
121 difference_type operator -(const const_iterator & other) const {return it_ - other.it_;}
122
123 reference operator [](difference_type n) const { return reinterpret_cast<reference>(it_[n]);}
124
125 bool operator ==(const const_iterator & other) const {return it_ == other.it_;}
126 bool operator !=(const const_iterator & other) const {return it_ != other.it_;}
127 bool operator <(const const_iterator & other) const {return it_ < other.it_;}
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
132 iterator_base_type to_base_type() const {return it_;}
133
134 private:
135 friend class __xtd_raw_array_data__;
136 iterator_base_type it_;
137 };
138 using reverse_iterator = std::reverse_iterator<iterator>;
139 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
141
144 inline static constexpr size_type npos = std::numeric_limits<size_type>::max();
145 static inline constexpr size_type bpos = 0;
146 static inline constexpr size_type epos = npos - 1;
148
151 __xtd_raw_array_data__() noexcept = default;
152 explicit __xtd_raw_array_data__(const allocator_type & alloc) noexcept : items_(alloc) {}
153 __xtd_raw_array_data__(size_type count, const type_t& value, const allocator_type& alloc = allocator_type()) : items_(count, value, alloc) {}
154 explicit __xtd_raw_array_data__(size_type count, const allocator_type& alloc = allocator_type()) : items_(count, alloc) {}
155 template<class input_iterator_t>
156 __xtd_raw_array_data__(input_iterator_t first, input_iterator_t last, const allocator_type& alloc = allocator_type()) : items_(first, last, alloc) {}
157 __xtd_raw_array_data__(const __xtd_raw_array_data__ & vector) : items_(vector.items_) {}
158 __xtd_raw_array_data__(const base_type & vector) : items_(vector) {}
159 __xtd_raw_array_data__(const __xtd_raw_array_data__ & vector, const allocator_type & alloc) : items_(vector.items_, alloc) {}
160 __xtd_raw_array_data__(const base_type & vector, const allocator_type & alloc) : items_(vector, alloc) {}
161 __xtd_raw_array_data__(std::initializer_list<type_t> items, const allocator_type& alloc = allocator_type()) requires(!std::is_same_v<type_t, bool>) : items_(items, alloc) {}
162 __xtd_raw_array_data__(std::initializer_list<bool> items, const allocator_type& alloc = allocator_type()) requires(std::is_same_v<type_t, bool>) : items_(alloc) {
163 items_.reserve(items.size());
164 for (auto b : items)
165 items_.push_back(b ? 1 : 0);
166 }
167 __xtd_raw_array_data__(__xtd_raw_array_data__&& other) : items_(std::move(other.items_)) {}
168 __xtd_raw_array_data__(base_type&& other) : items_(std::move(other)) {}
169 __xtd_raw_array_data__(__xtd_raw_array_data__&& other, const allocator_type & alloc) : items_(std::move(other.items_), alloc) {}
170 __xtd_raw_array_data__(base_type&& other, const allocator_type & alloc) : items_(std::move(other), alloc) {}
172
175 reference back() {return at(size() - 1);}
176 const_reference back() const {return at(size() - 1);}
177
178 iterator begin() noexcept {return to_type_iterator(items_.begin());}
179 const_iterator begin() const noexcept {return to_type_iterator(items_.cbegin());}
180
181 size_type capacity() const noexcept {return items_.capacity();}
182
183 const_iterator cbegin() const noexcept {return to_type_iterator(items_.cbegin());}
184 const_iterator cend() const noexcept {return to_type_iterator(items_.cend()); }
185
186 const_reverse_iterator crbegin() const noexcept {return const_reverse_iterator(end());}
187 const_reverse_iterator crend() const noexcept {return const_reverse_iterator(begin());}
188
189 pointer data() noexcept {return reinterpret_cast<pointer>(items_.data());}
190 const_pointer data() const noexcept {return reinterpret_cast<const_pointer>(items_.data());}
191
192 bool empty() const noexcept {return items_.empty();}
193
194 iterator end() noexcept {return to_type_iterator(items_.end());}
195 const_iterator end() const noexcept {return to_type_iterator(items_.cend());}
196
197 reference front() {return at(0);}
198 const_reference front() const {return at(0);}
199
200 const_base_type & items() const noexcept {return items_;}
201 base_type & items() noexcept {return items_;}
202
203 size_type max_size() const noexcept {return std::min(items_.max_size(), npos / 2);}
204
205 reverse_iterator rbegin() noexcept {return reverse_iterator(end());}
206 const_reverse_iterator rbegin() const noexcept {return const_reverse_iterator(end());}
207
208 reverse_iterator rend() noexcept {return reverse_iterator(begin());}
209 const_reverse_iterator rend() const noexcept {return const_reverse_iterator(begin());}
210
211 size_type size() const noexcept {return items_.size();}
212
213 size_type version() const noexcept {return version_;}
215
218 void assign(size_type count, const type_t& value) {
219 ++version_;
220 items_.assign(count, value);
221 }
222 template<class input_iterator_t>
223 void assign(input_iterator_t first, input_iterator_t last) {
224 ++version_;
225 items_.assign(first, last);
226 }
227 void assign(std::initializer_list<type_t> items) {
228 ++version_;
229 items_.assign(items.begin(), items.end());
230 }
231
232 reference at(size_type index) {return reinterpret_cast<reference>(items_.at(index > npos / 2 ? size() - (npos - index) : index));}
233 const_reference at(size_type index) const {return reinterpret_cast<const_reference>(items_.at(index > npos / 2 ? size() - (npos - index) : index));}
234
235 void clear() {
236 ++version_;
237 items_.clear();
238 }
239
240 template<class ...args_t>
241 iterator emplace(const_iterator pos, args_t&&... args) {
242 ++version_;
243 return to_type_iterator(items_.emplace(pos.to_base_type(), std::forward<args_t>(args)...));
244 }
245 template<class ...args_t>
246 reference emplace_back(args_t&&... args) {
247 ++version_;
248 return reinterpret_cast<reference>(items_.emplace_back(std::forward<args_t>(args)...));
249 }
250
251 iterator erase(const_iterator pos) {
252 ++version_;
253 return to_type_iterator(items_.erase(pos.to_base_type()));
254 }
255 iterator erase(const_iterator first, const_iterator last) {
256 ++version_;
257 return to_type_iterator(items_.erase(first.to_base_type(), last.to_base_type()));
258 }
259
260 allocator_type get_allocator() const {return items_.get_allocator();}
261
262 size_type increment_version() noexcept {return ++version_;}
263
264 iterator insert(const_iterator pos, const type_t& value) {
265 ++version_;
266 return to_type_iterator(items_.insert(pos.to_base_type(), value));
267 }
268 iterator insert(const_iterator pos, type_t&& value) {
269 ++version_;
270 return to_type_iterator(items_.insert(pos.to_base_type(), std::move(value)));
271 }
272 iterator insert(const_iterator pos, size_type count, const type_t& value) {
273 ++version_;
274 return to_type_iterator(items_.insert(pos.to_base_type(), count, value));
275 }
276 iterator insert(const_iterator pos, size_type count, type_t&& value) {
277 ++version_;
278 return to_type_iterator(items_.insert(pos.to_base_type(), count, std::move(value)));
279 }
280 template<class input_iterator_t>
281 iterator insert(const_iterator pos, input_iterator_t first, input_iterator_t last) {
282 ++version_;
283 return to_type_iterator(items_.insert(pos.to_base_type(), first, last));
284 }
285 iterator insert(const_iterator pos, const std::initializer_list<type_t>& items) {
286 ++version_;
287 return to_type_iterator(items_.insert(pos.to_base_type(), items.begin(), items.end()));
288 }
289
290 void pop_back() {
291 ++version_;
292 items_.pop_back();
293 }
294 void push_back(const type_t& value) {
295 ++version_;
296 items_.push_back(value);
297 }
298 void push_back(type_t&& value) {
299 ++version_;
300 items_.push_back(std::move(value));
301 }
302
303 void reserve(size_type new_cap) {items_.reserve(new_cap);}
304
305 void resize(size_type count) {
306 ++version_;
307 resize(count, value_type {});
308 }
309 void resize(size_type count, const value_type & value) {
310 ++version_;
311 items_.resize(count, value);
312 }
313
314 void shrink_to_fit() {items_.shrink_to_fit();}
315
316 void swap(__xtd_raw_array_data__ & other) noexcept {
317 ++version_;
318 items_.swap(other.items_);
319 }
321
324 __xtd_raw_array_data__& operator =(const __xtd_raw_array_data__ & other) = default;
325 __xtd_raw_array_data__& operator =(__xtd_raw_array_data__&& other) noexcept = default;
326 __xtd_raw_array_data__& operator =(std::initializer_list<type_t>& items) requires(!std::is_same_v<type_t, bool>) {
327 ++version_;
328 items_ = items;
329 return *this;
330 }
331 __xtd_raw_array_data__& operator =(std::initializer_list<bool>& items) requires(std::is_same_v<type_t, bool>) {
332 ++version_;
333 items_.clear();
334 items_.reserve(items.size());
335 for (auto b : items)
336 items_.push_back(b ? 1 : 0);
337 return *this;
338 }
339
340 friend bool operator ==(const __xtd_raw_array_data__<type_t>& a, const __xtd_raw_array_data__<type_t>& b) {
341 return a.items() == b.items();
342 }
343 friend bool operator ==(const __xtd_raw_array_data__<type_t>& a, const std::vector<type_t>& b) {
344 return a.items() == b;
345 }
346 friend bool operator ==(const std::vector<type_t>& a, const __xtd_raw_array_data__<type_t>& b) {
347 return a == b.items();
348 }
349
350 friend bool operator !=(const __xtd_raw_array_data__<type_t>& a, const __xtd_raw_array_data__<type_t>& b) {
351 return a.items() != b.items();
352 }
353 friend bool operator !=(const __xtd_raw_array_data__<type_t>& a, const std::vector<type_t>& b) {
354 return a.items() != b;
355 }
356 friend bool operator !=(const std::vector<type_t>& a, const __xtd_raw_array_data__<type_t>& b) {
357 return a != b.items();
358 }
359
360 const_reference operator [](size_type index) const {return at(index);}
361 reference operator [](size_type index) {return at(index);}
362
363 operator const base_type & () const noexcept {return items_;}
364 operator base_type & () noexcept {return items_;}
366
367private:
368 iterator to_type_iterator(typename base_type::iterator it) { return iterator(it); }
369 const_iterator to_type_iterator(typename base_type::const_iterator it) const { return const_iterator(it); }
370
371 base_type items_;
372 size_type version_ = 0;
373};
374
375template<class type_t>
376__xtd_raw_array_data__(std::initializer_list<type_t>) -> __xtd_raw_array_data__<type_t, std::allocator<type_t >>;
377
378template<class type_t>
379__xtd_raw_array_data__(const std::vector<type_t>&) -> __xtd_raw_array_data__<type_t, std::allocator<type_t >>;
380
381template<class type_t, class allocator_t = std::allocator<type_t>>
382__xtd_raw_array_data__(const __xtd_raw_array_data__<type_t, allocator_t>&) -> __xtd_raw_array_data__<type_t, allocator_t>;
383
384template<class type_t>
385__xtd_raw_array_data__(std::vector<type_t>&&) -> __xtd_raw_array_data__<type_t, std::allocator<type_t >>;
386
387template<class type_t, class allocator_t = std::allocator<type_t>>
388__xtd_raw_array_data__(__xtd_raw_array_data__<type_t, allocator_t>&&) -> __xtd_raw_array_data__<type_t, allocator_t>;
constexpr xtd::size npos
Represents a value that is not a valid position in a collection.
Definition npos.hpp:26
constexpr xtd::size epos
Represents the index of the last valid element in a collection.
Definition epos.hpp:33
constexpr xtd::size bpos
Represents the index of the firsy valid element in a collection.
Definition bpos.hpp:25
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
@ other
The operating system is other.
Definition platform_id.hpp:58
@ clear
The CLEAR key.
Definition console_key.hpp:26
@ 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
size_type
Specifies how rows or columns of user interface (UI) elements should be sized relative to their conta...
Definition size_type.hpp:22
const_reference front() const
Gets the first element.
Definition read_only_span.hpp:218
const_reverse_iterator rend() const
Returns a reverse iterator to the end.
Definition read_only_span.hpp:237
const_iterator begin() const
Returns an iterator to the beginning.
Definition read_only_span.hpp:183
const_iterator cbegin() const
Returns an iterator to the beginning.
Definition read_only_span.hpp:187
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
const_iterator end() const
Returns an iterator to the end.
Definition read_only_span.hpp:213
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
const_iterator cend() const
Returns an iterator to the end.
Definition read_only_span.hpp:190
const_reverse_iterator rbegin() const
Returns a reverse iterator to the beginning.
Definition read_only_span.hpp:233
const_reverse_iterator crbegin() const
Returns a reverse iterator to the beginning.
Definition read_only_span.hpp:194
const_reference at(size_type pos) const
Gets the specified element with bounds checking.
Definition read_only_span.hpp:255
const_reference back() const
Gets the last element.
Definition read_only_span.hpp:176
constexpr const_pointer data() const noexcept
Gets direct access to the underlying contiguous storage.
Definition read_only_span.hpp:201
constexpr bool empty() const noexcept
Returns a value that indicates whether the current xtd::read_only_span <type_t> is empty.
Definition read_only_span.hpp:205
const_reverse_iterator crend() const
Returns a reverse iterator to the end.
Definition read_only_span.hpp:197