xtd 0.2.0
span.hpp
Go to the documentation of this file.
1
4#pragma once
5#define __XTD_STD_INTERNAL__
7#undef __XTD_STD_INTERNAL__
11#include "array.hpp"
12#include "dynamic_extent.hpp"
13#include "iequatable.hpp"
15#include "is.hpp"
16#include "null.hpp"
17#include "object.hpp"
18#include "ptrdiff.hpp"
19#include "ranges.hpp"
20#include "typeof.hpp"
21#include <type_traits>
22#include <vector>
23
25namespace xtd {
57 template<class type_t, xtd::size extent = dynamic_extent>
58 class span : public xtd::object, public xtd::iequatable<xtd::span<type_t, extent>> {
59 public:
61
64 using element_type = type_t;
66 using value_type = std::remove_cv_t<type_t>;
72 using pointer = type_t*;
74 using const_pointer = const type_t*;
76 using reference = type_t&;
78 using const_reference = const type_t&;
84 using reverse_iterator = std::reverse_iterator<xtd::collections::generic::helpers::wrap_pointer_iterator<pointer>>;
86 using const_reverse_iterator = const std::reverse_iterator<xtd::collections::generic::helpers::wrap_pointer_iterator<pointer>>;
88
90
93 template <xtd::size count = 0>
94 constexpr span() : data_ {xtd::null}, length_ {0} {}
95
100 template<class iterator_t>
101 constexpr span(iterator_t first, iterator_t last) : data_ {&(*first)}, length_ {extent != dynamic_extent ? extent : static_cast<size_type>(std::distance(first, last))} {}
102 /* Conflict with span(collection_t& items, xtd::size count)
106 template<class iterator_t>
107 span(iterator_t first, xtd::size count) : data_ {&(*first)}, length_ {extent != dynamic_extent ? extent : count} {}
108 */
109#if defined(__xtd__cpp_lib_type_identity)
112 template<xtd::size len>
113 constexpr span(std::type_identity_t<element_type> (&array)[len]) noexcept : data_ {array}, length_ {extent != dynamic_extent ? extent : len} {}
114#else
117 template<xtd::size len>
118 constexpr span(element_type (&array)[len]) noexcept : data_ {const_cast<element_type*>(array)}, length_ {extent != dynamic_extent ? extent : len} {}
119#endif
122 template<class array_type_t, xtd::size len>
123 constexpr span(const std::array<array_type_t, len>& array) noexcept : data_ {array.data()}, length_ {extent != dynamic_extent ? extent : len} {}
126 template<class array_type_t, xtd::size len>
127 constexpr span(std::array<array_type_t, len>& array) noexcept : data_ {array.data()}, length_ {extent != dynamic_extent ? extent : len} {}
128#if defined(__xtd__cpp_lib_ranges)
131 template<class range_t>
132 constexpr span(range_t&& range) noexcept : data_ {xtd::ranges::data(range)}, length_ {extent != dynamic_extent ? extent : xtd::ranges::size(range)} {}
133#else
136 template<class range_t>
137 constexpr span(range_t&& range) noexcept : data_ {range.data()}, length_ {extent != dynamic_extent ? extent : range.size()} {}
138#endif
139#if __cplusplus >= 202002l
142 constexpr span(std::initializer_list<type_t> items) noexcept requires std::is_const_v<element_type> : data_ {items.begin()}, length_ {extent != dynamic_extent ? extent : items.size()} {}
143#else
146 constexpr span(std::initializer_list<type_t> items) noexcept : data_ {const_cast<type_t*>(items.begin())}, length_ {extent != dynamic_extent ? extent : items.size()} {
147 static_assert(std::is_const_v<element_type>, "type_t must be const");
148 }
149#endif
150 /* Conflict with span(range_t&& range) noexcept
154 template<class collection_t>
155 constexpr span(collection_t& items) noexcept : span {items, size_type {0}, items.size()} {}
156 */
161 template<class collection_t>
162 constexpr span(collection_t& items, size_type length) : span {items, size_type {0}, length} {}
168 template<class collection_t>
169 constexpr span(collection_t& items, size_type start, size_type length) : data_ {items.data() + start}, length_ {extent != dynamic_extent ? extent : length} {
171 }
175 constexpr span(type_t* const data, size_type length) : data_ {data}, length_ {extent != dynamic_extent ? extent : length} {
177 }
179
181 constexpr span(span&& items) = default;
182 constexpr span(const span& items) = default;
183
184 span& operator =(span&& items) = default;
185 span& operator =(const span& items) = default;
187
189
196 return *(data_ + length_ - 1);
197 }
198
201 const_iterator begin() const {return cbegin();}
204 iterator begin() {return iterator {data_};}
205
208 const_iterator cbegin() const {return const_iterator {data_};}
211 const_iterator cend() const {return const_iterator {data_ + length_};}
212
215 const_reverse_iterator crbegin() const {return const_reverse_iterator {iterator {data_ + length_}};}
219
222 constexpr const_pointer data() const noexcept {return data_;}
223
226 constexpr bool empty() const noexcept {return is_empty();}
227
230 static const span empty_span;
231
234 const_iterator end() const {return cend();}
237 iterator end() {return iterator {data_ + length_};}
238
244 return *data_;
245 }
246
249 constexpr bool is_empty() const noexcept {return !length_;}
250
253 constexpr size_type length() const noexcept {return length_;}
254
260 reverse_iterator rbegin() {return reverse_iterator {iterator {data_ + length_}};}
261
268
271 constexpr size_type size() const noexcept {return length();}
272
275 constexpr size_type size_bytes() const noexcept {return length_ * sizeof(value_type);}
277
279
287 return *(data_ + pos);
288 }
295 return *(data_ + pos);
296 }
297
300 void clear() noexcept {
301 for (auto& item : *this)
302 item = value_type {};
303 }
304
308 template<xtd::size length>
309 void copy_to(span<type_t, length>& destination) const {
310 if (!try_copy_to(destination))
312 }
313
317 bool equals(const object& obj) const noexcept override {return is<span<value_type>>(obj) && equals(static_cast<const span<value_type>&>(obj));}
321 bool equals(const span& rhs) const noexcept override {return length() == rhs.length() && data() == rhs.data();}
322
325 void fill(const type_t& value) {
326 for (auto& item : *this)
327 item = value;
328 }
329
333 template<xtd::size count>
336 return span<type_t, count> {data_, count};
337 }
343 return span<type_t> {data_, count};
344 }
345
348 xtd::size get_hash_code() const noexcept override {
349 auto result = hash_code {};
350 for (const auto& item : *this)
351 result.add(item);
352 return result.to_hash_code();
353 }
354
358 template<xtd::size count>
361 return span<type_t, count> {data_ + length_ - count, count};
362 }
368 return span<type_t> {data_ + length_ - count, count};
369 }
370
376 template<xtd::size start, size_type lenght = xtd::dynamic_extent>
378 return lenght == xtd::dynamic_extent ? slice(start) : slice(start, lenght);
379 }
380
386 return slice(start, length_ - start);
387 }
388
396 return span<type_t> {data_ + start, length};
397 }
398
404 template<xtd::size offset, size_type count = xtd::dynamic_extent>
406 return count == xtd::dynamic_extent ? slice(offset) : slice(offset, count);
407 }
408
415 return count == xtd::dynamic_extent ? slice(offset) : slice(offset, count);
416 }
417
421 return data_ && length_ ? xtd::array<value_type>(data_, length_) : xtd::array<value_type> {};
422 }
423
427 string to_string() const noexcept override {
428 if (typeof_<type_t>() == typeof_<char>()) return xtd::string::join("", *this);
429 return xtd::string::format("[{}]", xtd::string::join(", ", *this));
430 }
431
436 template<xtd::size length>
437 bool try_copy_to(span<type_t, length>& destination) const noexcept {
438 if (destination.length() < this->length()) return false;
439 for (auto index = xtd::size {}; index < length_; ++index)
440 destination.at(index) = at(index);
441 return true;
442 }
444
446
452 const_reference operator[](size_type index) const {return at(index);}
457 reference operator[](size_type index) {return at(index);}
459
460 private:
461 pointer data_ = null;
462 size_type length_ = size_type {};
463 };
464
465 template<class type_t, xtd::size extent>
466 inline const span<type_t, extent> span<type_t, extent>::empty_span;
467
469 // C++17 deduction guides for xtd::span
470 // {
471 template<class iterator_t>
472 span(iterator_t, iterator_t) -> span<typename iterator_t::value_type>;
473
474 template<class type_t, xtd::size len>
475 span(type_t (&)[len]) noexcept -> span<type_t>;
476
477 template< class type_t, xtd::size len>
478 span(const std::array<type_t, len>&) noexcept -> span<const type_t>;
479
480 template< class type_t, xtd::size len>
481 span(std::array<type_t, len>&) noexcept -> span<type_t>;
482
483#if defined(__xtd__cpp_lib_ranges)
484 template<class range_t>
485 span(range_t&&) noexcept -> span<std::remove_reference_t<xtd::ranges::range_reference_t<range_t>>>;
486#else
487 template<class range_t>
488 span(range_t&&) noexcept -> span<std::remove_reference_t<typename range_t::value_type>>;
489#endif
490
491 template<class type_t>
492 span(std::initializer_list<type_t>) noexcept -> span<const type_t>;
493
494 template<class collection_t>
495 span(const collection_t& items) noexcept -> span<const typename collection_t::value_type>;
496
497 template<class collection_t>
498 span(const collection_t&, xtd::size) -> span<const typename collection_t::value_type>;
499
500 template<class collection_t>
501 span(collection_t&, xtd::size) -> span<typename collection_t::value_type>;
502
503 template<class collection_t>
504 span(const collection_t&, xtd::size, xtd::size) -> span<const typename collection_t::value_type>;
505
506 template<class collection_t>
507 span(collection_t&, xtd::size, xtd::size) -> span<typename collection_t::value_type>;
508
509 template<class type_t>
510 span(type_t* const, xtd::size) -> span<type_t>;
511 // }
513}
Contains __xtd_std_version definitions.
Contains xtd::argument_null_exception exception.
Contains xtd::argument_out_of_range_exception exception.
Contains xtd::array class.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition array.hpp:59
virtual pointer data() noexcept
Returns pointer to the underlying array serving as element storage.
Definition basic_array.hpp:149
static basic_string join(const basic_string separator, const collection_t &values) noexcept
Concatenates a specified separator basic_string between each element of a specified object array,...
Definition basic_string.hpp:2288
Represents a wrap pointer iterator.
Definition wrap_pointer_iterator.hpp:35
Combines the hash code for multiple values into a single hash code.
Definition hash_code.hpp:26
xtd::size to_hash_code() const noexcept
Calculates the final hash code after consecutive xtd::hash_code::add invocations.
hash_code & add(const type_t value) noexcept
Adds a single value to the hash code.
Definition hash_code.hpp:43
static void throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current())
Throws an exption with specified exception case.
Defines a generalized method that a value type or class implements to create a type-specific method f...
Definition iequatable.hpp:22
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.hpp:44
Represents a non-owning view over a contiguous sequence of objects.
Definition span.hpp:58
const_reverse_iterator rend() const
Returns a reverse iterator to the end.
Definition span.hpp:264
constexpr span(const std::array< array_type_t, len > &array) noexcept
Creates an xtd::span with specified std::array.
Definition span.hpp:123
constexpr span(element_type(&array)[len]) noexcept
Creates an xtd::span with specified native array.
Definition span.hpp:118
const_reverse_iterator crbegin() const
Returns a reverse iterator to the beginning.
Definition span.hpp:215
bool equals(const span &rhs) const noexcept override
Indicates whether the current object is equal to another object of the same type.
Definition span.hpp:321
const_reference back() const
Gets the last element.
Definition span.hpp:194
constexpr span(range_t &&range) noexcept
Creates an xtd::span with specified range.
Definition span.hpp:137
span< type_t > slice() const
Forms a slice out of the current span starting at a specified index for a specified length.
Definition span.hpp:377
span< type_t > slice(size_type start) const
Forms a slice out of the current span that begins at a specified index.
Definition span.hpp:385
span< type_t, count > first() const
Obtains a subspan consisting of the first count elements of the sequence.
Definition span.hpp:334
constexpr const_pointer data() const noexcept
Gets direct access to the underlying contiguous storage.
Definition span.hpp:222
const type_t * const_pointer
Represents the span const pointer type.
Definition span.hpp:74
span< type_t > slice(size_type start, size_type length) const
Forms a slice out of the current span starting at a specified index for a specified length.
Definition span.hpp:394
constexpr size_type length() const noexcept
Returns the length of the current span.
Definition span.hpp:253
std::reverse_iterator< xtd::collections::generic::helpers::wrap_pointer_iterator< pointer > > reverse_iterator
Represents the reverse iterator of span value type.
Definition span.hpp:84
constexpr bool is_empty() const noexcept
Returns a value that indicates whether the current xtd::span <type_t> is empty.
Definition span.hpp:249
xtd::size size_type
Represents the span size type (usually xtd::size).
Definition span.hpp:68
type_t * pointer
Represents the span pointer type.
Definition span.hpp:72
const type_t & const_reference
Represents the span const reference type.
Definition span.hpp:78
constexpr bool empty() const noexcept
Returns a value that indicates whether the current xtd::span <type_t> is empty.
Definition span.hpp:226
const std::reverse_iterator< xtd::collections::generic::helpers::wrap_pointer_iterator< pointer > > const_reverse_iterator
Represents the const reverse iterator of span value type.
Definition span.hpp:86
iterator begin()
Returns an iterator to the beginning.
Definition span.hpp:204
static const span empty_span
Returns an empty xtd::span <type_t> object.
Definition span.hpp:230
span< type_t > subspan() const
Forms a subspan of the current span starting at a specified index for a specified length.
Definition span.hpp:405
const_iterator cbegin() const
Returns an iterator to the beginning.
Definition span.hpp:208
const_iterator end() const
Returns an iterator to the end.
Definition span.hpp:234
constexpr span()
Creates an empty xtd::span whose xtd::span::data is null and xtd::span::size is 0.
Definition span.hpp:94
reference operator[](size_type index)
Gets the element at the specified zero-based index.
Definition span.hpp:457
constexpr span(iterator_t first, iterator_t last)
Creates an xtd::span with specified iterators.
Definition span.hpp:101
const_iterator begin() const
Returns an iterator to the beginning.
Definition span.hpp:201
void fill(const type_t &value)
Fills the elements of this span with a specified value.
Definition span.hpp:325
constexpr span(std::array< array_type_t, len > &array) noexcept
Creates an xtd::span with specified std::array.
Definition span.hpp:127
span< type_t > first(xtd::size count) const
Obtains a subspan consisting of the first count elements of the sequence.
Definition span.hpp:341
constexpr size_type size_bytes() const noexcept
Returns the size of the sequence in bytes.
Definition span.hpp:275
span< type_t, count > last() const
Obtains a subspan consisting of the last N elements of the sequence.
Definition span.hpp:359
constexpr span(collection_t &items, size_type start, size_type length)
Creates an xtd::span with specified collection, offest and count.
Definition span.hpp:169
reverse_iterator rend()
Returns a reverse iterator to the end.
Definition span.hpp:267
void copy_to(span< type_t, length > &destination) const
Copies the contents of this xtd::span <type_t> into a destination xtd:span <type_t>.
Definition span.hpp:309
reference at(size_type pos)
Gets the specified element with bounds checking.
Definition span.hpp:293
reverse_iterator rbegin()
Returns a reverse iterator to the beginning.
Definition span.hpp:260
span< type_t > last(xtd::size count) const
Obtains a subspan consisting of the last N elements of the sequence.
Definition span.hpp:366
xtd::size get_hash_code() const noexcept override
Serves as a hash function for a particular type.
Definition span.hpp:348
const_reverse_iterator crend() const
Returns a reverse iterator to the end.
Definition span.hpp:218
iterator end()
Returns an iterator to the end.
Definition span.hpp:237
type_t element_type
Represents the span elemeent type.
Definition span.hpp:64
std::remove_cv_t< type_t > value_type
Represents the span value type.
Definition span.hpp:66
string to_string() const noexcept override
Returns the string representation of this xtd::span <type_t> object.
Definition span.hpp:427
const_reference at(size_type pos) const
Gets the specified element with bounds checking.
Definition span.hpp:285
const_reverse_iterator rbegin() const
Returns a reverse iterator to the beginning.
Definition span.hpp:257
type_t & reference
Represents the span reference type.
Definition span.hpp:76
xtd::ptrdiff difference_type
Represents the span difference type (usually xtd::ptrdiff).
Definition span.hpp:70
bool try_copy_to(span< type_t, length > &destination) const noexcept
Attempts to copy the current xtd::span <type_t> to a destination xtd::span <type_t> and returns a val...
Definition span.hpp:437
const_iterator cend() const
Returns an iterator to the end.
Definition span.hpp:211
const_reference front() const
Gets the first element.
Definition span.hpp:242
constexpr span(type_t *const data, size_type length)
Creates an xtd::span with specified data pointer and count.
Definition span.hpp:175
span< type_t > subspan(size_type offset, size_type count=xtd::dynamic_extent) const
Forms a subspan of the current span starting at a specified index for a specified length.
Definition span.hpp:414
void clear() noexcept
Clears the contents of this xtd::span <type> object.
Definition span.hpp:300
xtd::array< value_type > to_array() const noexcept
Copies the contents of this span into a new array.
Definition span.hpp:420
constexpr span(collection_t &items, size_type length)
Creates an xtd::span with specified collection and count.
Definition span.hpp:162
constexpr size_type size() const noexcept
Returns the number of elements.
Definition span.hpp:271
const_reference operator[](size_type index) const
Gets the element at the specified zero-based index.
Definition span.hpp:452
bool equals(const object &obj) const noexcept override
Determines whether the specified object is equal to the current object.
Definition span.hpp:317
constexpr span(std::initializer_list< type_t > items) noexcept
Creates an xtd::span with specified initializer list.
Definition span.hpp:146
Contains xtd::dynamic_extent field.
static basic_string format(const basic_string< char > &fmt, args_t &&... args)
Writes the text representation of the specified arguments list, to string using the specified format ...
@ argument
The argument is not valid.
@ index_out_of_range
The index is out of range.
@ argument_null
The argument is null.
@ argument_out_of_range
The argument is out of range.
constexpr xtd::size dynamic_extent
Represents the constant of type xtd::size signifying that the span has dynamic extent.
Definition dynamic_extent.hpp:24
null_ptr null
Represents a null pointer value.
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
std::ptrdiff_t ptrdiff
Represent the signed integer type of the result of subtracting two pointers.
Definition ptrdiff.hpp:23
Contains xtd::iequatable interface.
Contains xtd::index_out_of_range_exception exception.
Contains xtd::is method.
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.hpp:10
Contains xtd::null pointer valiue.
Contains xtd::object class.
Contains xtd::ptrdiff type.
Contains xtd::ranges and xtd::views namespaces.
Contains typeof_ keyword.
Contains xtd::collections::generic::helpers::wrap_pointer_iterator class.