xtd 1.0.0
Loading...
Searching...
No Matches
span.hpp
Go to the documentation of this file.
1
4#pragma once
5#define __XTD_CORE_INTERNAL__
7#undef __XTD_CORE_INTERNAL__
11#include "array.hpp"
12#include "dynamic_extent.hpp"
13#include "iequatable.hpp"
14#include "index.hpp"
15#include "is.hpp"
16#include "iterable.hpp"
18#include "null.hpp"
19#include "object.hpp"
20#include "ptrdiff.hpp"
21#include "range.hpp"
22#include "views/views.hpp"
23#include "typeof.hpp"
24#include <span>
25#include <type_traits>
26#include <vector>
27
29namespace xtd {
61 template<typename type_t, xtd::usize extent>
62 class span : public xtd::object, public xtd::iequatable<xtd::span<type_t, extent>>, public xtd::collections::generic::ienumerable<type_t> {
63 public:
65
68 using element_type = type_t;
70 using value_type = std::remove_cv_t<type_t>;
76 using pointer = type_t*;
78 using const_pointer = const type_t*;
80 using reference = type_t&;
82 using const_reference = const type_t&;
84
86
89 template <xtd::usize count = 0>
90 constexpr span() : data_ {xtd::null}, length_ {0} {}
91
96 template<typename iterator_t>
97 constexpr span(iterator_t first, iterator_t last) : data_ {const_cast<pointer>(&(*first))}, length_ {extent != dynamic_extent ? extent : static_cast<size_type>(std::distance(first, last))} {}
98 /* Conflict with span(collection_t& items, xtd::usize count)
102 template<typename iterator_t>
103 span(iterator_t first, xtd::usize count) : data_ {&(*first)}, length_ {extent != dynamic_extent ? extent : count} {}
104 */
105 #if defined(__xtd__cpp_lib_type_identity)
108 template<xtd::usize len>
109 constexpr span(std::type_identity_t<element_type> (&array)[len]) noexcept : data_ {array}, length_ {extent != dynamic_extent ? extent : len} {}
110 #else
113 template<xtd::usize len>
114 constexpr span(element_type(&array)[len]) noexcept : data_ {const_cast<element_type*>(array)}, length_ {extent != dynamic_extent ? extent : len} {}
115 #endif
118 template<typename array_type_t, xtd::usize len>
119 constexpr span(const std::array<array_type_t, len>& array) noexcept : data_ {array.data()}, length_ {extent != dynamic_extent ? extent : len} {}
122 template<typename array_type_t, xtd::usize len>
123 constexpr span(std::array<array_type_t, len>& array) noexcept : data_ {array.data()}, length_ {extent != dynamic_extent ? extent : len} {}
128 template<typename array_type_t>
129 constexpr span(const xtd::array<array_type_t>& items) : span {items, size_type {0}, items.length()} {}
134 template<typename array_type_t>
135 constexpr span(xtd::array<array_type_t>& items) : span {items, size_type {0}, items.length()} {}
136 #if defined(__xtd__cpp_lib_ranges)
139 template<typename range_t>
140 constexpr span(range_t&& range) noexcept : data_ {std::ranges::data(range)}, length_ {extent != dynamic_extent ? extent : std::ranges::size(range)} {}
141 #else
144 template<typename range_t>
145 constexpr span(range_t&& range) noexcept : data_ {range.data()}, length_ {extent != dynamic_extent ? extent : range.size()} {}
146 #endif
147 #if __cplusplus >= 202002l
150 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()} {}
151 #else
154 constexpr span(std::initializer_list<type_t> items) noexcept : data_ {const_cast<type_t*>(items.begin())}, length_ {extent != dynamic_extent ? extent : items.size()} {
155 static_assert(std::is_const_v<element_type>, "type_t must be const");
156 }
157 #endif
158 /* Conflict with span(range_t&& range) noexcept
162 template<typename collection_t>
163 constexpr span(collection_t& items) noexcept : span {items, size_type {0}, items.size()} {}
164 */
169 template<typename collection_t>
170 constexpr span(collection_t& items, size_type length) : span {items, size_type {0}, length} {}
176 template<typename collection_t>
177 constexpr span(collection_t& items, size_type start, size_type length) : data_ {const_cast<pointer>(items.data()) + start}, length_ {extent != dynamic_extent ? extent : length} {
179 }
180
183 constexpr span(type_t* const data, size_type length) : data_ {const_cast<pointer>(data)}, length_ {extent != dynamic_extent ? extent : length} {
185 }
186
190 template<typename collection_t>
191 constexpr span(collection_t& items, const xtd::range& range) {
192 auto [start, length] = range.get_offset_and_length(items.size());
193 data_ = items.data() + start;
194 length_ = extent != dynamic_extent ? extent : length;
195 }
196
197
199 template<xtd::usize extent_>
200 constexpr span(const std::span<type_t, extent_>& s) : data_ {s.data()}, length_ {s.size()} {}
201
202 constexpr span(span&& items) = default;
203 constexpr span(const span& items) = default;
204
205 auto operator =(span&& items) -> span& = default;
206 auto operator =(const span& items) -> span& = default;
208
210
214 static const span empty_span;
216
218
222 [[nodiscard]] constexpr auto data() const noexcept -> const_pointer {return data_;}
225 [[nodiscard]] constexpr auto data() noexcept -> pointer {return data_;}
226
229 [[nodiscard]] constexpr auto empty() const noexcept -> bool {return is_empty();}
230
233 [[nodiscard]] constexpr auto is_empty() const noexcept -> bool {return !length_;}
234
237 [[nodiscard]] constexpr auto length() const noexcept -> size_type {return length_;}
238
241 [[nodiscard]] constexpr auto size() const noexcept -> size_type {return length();}
242
245 [[nodiscard]] constexpr auto size_bytes() const noexcept -> size_type {return length_ * sizeof(value_type);}
247
249
253 auto clear() noexcept -> void {
254 for (auto& item : *this)
255 item = value_type {};
256 }
257
261 template<xtd::usize length>
262 auto copy_to(span<type_t, length>& destination) const -> void {
263 if (!try_copy_to(destination))
265 }
266
270 [[nodiscard]] auto equals(const object& obj) const noexcept -> bool override {return is<span<value_type>>(obj) && equals(static_cast<const span<value_type>& > (obj));}
274 [[nodiscard]] auto equals(const span& rhs) const noexcept -> bool override {return length() == rhs.length() && data() == rhs.data();}
275
278 auto fill(const type_t& value) -> void {
279 for (auto& item : *this)
280 item = value;
281 }
282
286 template<xtd::usize count>
287 [[nodiscard]] auto first() const -> span<type_t, count> {
289 return span<type_t, count> {data_, count};
290 }
291
298
299 auto get_enumerator() const -> xtd::collections::generic::enumerator<type_t> override {
300 class span_enumerator : public xtd::collections::generic::ienumerator<type_t> {
301 public:
302 explicit span_enumerator(const_pointer data, xtd::usize length) : data_(data), length_(length) {}
303 const type_t& current() const override {return *(data_ + index_);}
304 bool move_next() override {return ++index_ < length_;}
305 void reset() override {index_ = xtd::npos;}
306
307 protected:
308 const_pointer data_;
309 xtd::usize length_;
310 xtd::usize index_ = xtd::npos;
311 };
312 return {new_ptr<span_enumerator>(data_, length_)};
313 }
314
317 [[nodiscard]] auto get_hash_code() const noexcept -> xtd::usize override {
318 auto result = hash_code {};
319 for (const auto& item : *this)
320 result.add(item);
321 return result.to_hash_code();
322 }
323
327 template<xtd::usize count>
328 [[nodiscard]] auto last() const -> span<type_t, count> {
330 return span<type_t, count> {data_ + length_ - count, count};
331 }
332
335 [[nodiscard]] auto last(xtd::usize count) const -> span<type_t> {
337 return span<type_t> {data_ + length_ - count, count};
338 }
339
345 template<xtd::usize start, size_type lenght = xtd::dynamic_extent>
346 [[nodiscard]] auto slice() const -> span<type_t> {
347 return lenght == xtd::dynamic_extent ? slice(start) : slice(start, lenght);
348 }
349
354 [[nodiscard]] auto slice(size_type start) const -> span<type_t> {
355 return slice(start, length_ - start);
356 }
357
363 [[nodiscard]] auto slice(size_type start, size_type length) const -> span<type_t> {
365 return span<type_t> {data_ + start, length};
366 }
367
373 template<xtd::usize offset, size_type count = xtd::dynamic_extent>
374 [[nodiscard]] auto subspan() const -> span<type_t> {
375 return count == xtd::dynamic_extent ? slice(offset) : slice(offset, count);
376 }
377
383 [[nodiscard]] auto subspan(size_type offset, size_type count = xtd::dynamic_extent) const -> span<type_t> {
384 return count == xtd::dynamic_extent ? slice(offset) : slice(offset, count);
385 }
386
389 [[nodiscard]] auto to_array() const noexcept -> xtd::array<value_type> {
390 return data_ && length_ ? xtd::array<value_type>(data_, data_ + length_) : xtd::array<value_type> {};
391 }
392
396 [[nodiscard]] auto to_string() const noexcept -> xtd::string override {
397 if (typeof_<type_t>() == typeof_<char>()) return xtd::string::join("", *this);
398 return xtd::string::format("[{}]", xtd::string::join(", ", *this));
399 }
400
405 template<xtd::usize length>
406 auto try_copy_to(span<type_t, length>& destination) const noexcept -> bool {
407 if (destination.length() < this->length()) return false;
408 for (auto index = xtd::usize {}; index < length_; ++index)
409 destination[index] = operator [](index);
410 return true;
411 }
412
413
415
425
433
438 return operator[](index.get_offset(size()));
439 }
440
445 return operator[](index.get_offset(size()));
446 }
447
455 return span {*this, range};
456 }
457
463 return operator[](index);
464 }
465
470 return operator[](index);
471 }
472
477 return operator[](index);
478 }
479
484 return operator[](index);
485 }
486
494 return operator[](range);
495 }
496
497
499 operator std::span<type_t, extent>() const {return std::span<type_t, extent>(data_, length_);}
501
502 private:
503 pointer data_ = null;
504 size_type length_ = size_type {};
505 };
506
507 template<typename type_t, xtd::usize extent>
509
511 // Deduction guides for xtd::span
512 // {
513 template<typename iterator_t>
514 span(iterator_t, iterator_t) -> span<typename iterator_t::value_type>;
515
516 template<typename type_t, xtd::usize len>
517 span(type_t (&)[len]) noexcept -> span<type_t>;
518
519 template< class type_t, xtd::usize len>
520 span(const std::array<type_t, len>&) noexcept -> span<const type_t>;
521
522 template< class type_t, xtd::usize len>
523 span(std::array<type_t, len>&) noexcept -> span<type_t>;
524
525 template<xtd::iterable iterable_t>
526 span(iterable_t&& items) -> span<xtd::iterable_value_type<iterable_t>>;
527
528 template<typename type_t>
529 span(std::initializer_list<type_t>) noexcept -> span<const type_t>;
530
531 template<typename collection_t>
532 span(const collection_t& items) noexcept -> span<const typename collection_t::value_type>;
533
534 template<typename collection_t>
536
537 template<typename collection_t>
539
540 template<typename collection_t>
542
543 template<typename collection_t>
545
546 template<typename collection_t>
547 span(const collection_t&, const xtd::range&) -> span<const typename collection_t::value_type>;
548
549 template<typename type_t>
550 span(type_t* const, xtd::usize) -> span<type_t>;
551 // }
553}
554
556template<typename type_t, typename list_t>
558 return xtd::span<type_t>(self(), range);
559}
560
561template<typename type_t, typename list_t>
563 return xtd::span<type_t>(self(), range);
564}
565
566template<typename type_t, typename allocator_t>
568 return xtd::span<type_t>(*this, range);
569}
570
571template<typename type_t, typename allocator_t>
573 return xtd::span<type_t>(*this, range);
574}
Contains xtd::array class.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition array.hpp:64
virtual auto data() noexcept -> pointer override
Returns pointer to the underlying array serving as element storage.
Definition basic_array.hpp:77
static auto join(const basic_string &separator, const collection_t &values) noexcept -> basic_string
Definition basic_string.hpp:1240
virtual auto operator()(xtd::usize index) const -> const type_t &
Gets the element at the specified index.
Definition list_common.hpp:48
auto operator[](const xtd::index &index) const -> const type_t &
Gets the element at the specified index.
Internal vector-like container used as a storage backend for xtd collections.
Definition raw_array.hpp:38
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
Definition ienumerable.hpp:40
Supports a simple iteration over a generic collection.
Definition ienumerator.hpp:58
Combines the hash code for multiple values into a single hash code.
Definition hash_code.hpp:26
auto add(const type_t &value) noexcept -> hash_code &
Adds a single value to the hash code.
Definition hash_code.hpp:43
static auto throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current()) -> void
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:23
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.hpp:40
Represents a range that has start and end indexes.
Definition range.hpp:38
auto get_offset_and_length(size_type length) const -> offset_and_length
Calculates the start offset and length of the range object using a collection length.
Definition range.hpp:112
Definition __span_definitions.hpp:16
Represents a non-owning view over a contiguous sequence of objects.
Definition span.hpp:62
constexpr span(const std::array< array_type_t, len > &array) noexcept
Creates an xtd::span with specified std::array.
Definition span.hpp:119
auto last(xtd::usize count) const -> span< type_t >
Obtains a subspan consisting of the last N elements of the sequence.
Definition span.hpp:335
constexpr span(element_type(&array)[len]) noexcept
Creates an xtd::span with specified native array.
Definition span.hpp:114
auto operator()(size_type index) const -> const_reference
Gets the element at the specified zero-based index.
Definition span.hpp:462
static const span empty_span
Returns an empty xtd::span <type_t> object.
Definition span.hpp:214
auto operator[](size_type index) const -> const_reference
Gets the element at the specified zero-based index.
Definition span.hpp:421
constexpr auto data() const noexcept -> const_pointer
Gets direct access to the underlying contiguous storage.
Definition span.hpp:222
auto subspan() const -> span< type_t >
Forms a subspan of the current span starting at a specified index for a specified length.
Definition span.hpp:374
xtd::usize size_type
Represents the span size type (usually xtd::usize).
Definition span.hpp:72
constexpr span(range_t &&range) noexcept
Creates an xtd::span with specified range.
Definition span.hpp:145
auto get_enumerator() const -> xtd::collections::generic::enumerator< type_t > override
Returns an enumerator that iterates through a collection.
Definition span.hpp:299
constexpr auto data() noexcept -> pointer
Gets direct access to the underlying contiguous storage.
Definition span.hpp:225
const type_t * const_pointer
Represents the span const pointer type.
Definition span.hpp:78
auto clear() noexcept -> void
Clears the contents of this xtd::span <type> object.
Definition span.hpp:253
auto to_array() const noexcept -> xtd::array< value_type >
Copies the contents of this span into a new array.
Definition span.hpp:389
auto first(xtd::usize count) const -> span< type_t >
Obtains a subspan consisting of the first count elements of the sequence.
Definition span.hpp:294
auto get_hash_code() const noexcept -> xtd::usize override
Serves as a hash function for a particular type.
Definition span.hpp:317
constexpr auto length() const noexcept -> size_type
Returns the length of the current span.
Definition span.hpp:237
constexpr auto size_bytes() const noexcept -> size_type
Returns the size of the sequence in bytes.
Definition span.hpp:245
type_t * pointer
Represents the span pointer type.
Definition span.hpp:76
const type_t & const_reference
Represents the span const reference type.
Definition span.hpp:82
constexpr auto size() const noexcept -> size_type
Returns the number of elements.
Definition span.hpp:241
constexpr span(xtd::array< array_type_t > &items)
Creates an xtd::span with specified collection and count.
Definition span.hpp:135
auto copy_to(span< type_t, length > &destination) const -> void
Copies the contents of this xtd::span <type_t> into a destination xtd:span <type_t>.
Definition span.hpp:262
constexpr span()
Creates an empty xtd::span whose xtd::span::data is null and xtd::span::size is 0.
Definition span.hpp:90
constexpr span(const xtd::array< array_type_t > &items)
Creates an xtd::span with specified collection and count.
Definition span.hpp:129
constexpr span(iterator_t first, iterator_t last)
Creates an xtd::span with specified iterators.
Definition span.hpp:97
auto slice(size_type start) const -> span< type_t >
Forms a slice out of the current span that begins at a specified index.
Definition span.hpp:354
constexpr span(std::array< array_type_t, len > &array) noexcept
Creates an xtd::span with specified std::array.
Definition span.hpp:123
auto subspan(size_type offset, size_type count=xtd::dynamic_extent) const -> span< type_t >
Forms a subspan of the current span starting at a specified index for a specified length.
Definition span.hpp:383
constexpr span(collection_t &items, size_type start, size_type length)
Creates an xtd::span with specified collection, offest and count.
Definition span.hpp:177
auto slice() const -> span< type_t >
Forms a slice out of the current span starting at a specified index for a specified length.
Definition span.hpp:346
auto equals(const span &rhs) const noexcept -> bool override
Indicates whether the current object is equal to another object of the same type.
Definition span.hpp:274
constexpr auto empty() const noexcept -> bool
Returns a value that indicates whether the current xtd::span <type_t> is empty.
Definition span.hpp:229
type_t element_type
Represents the span elemeent type.
Definition span.hpp:68
auto slice(size_type start, size_type length) const -> span< type_t >
Forms a slice out of the current span starting at a specified index for a specified length.
Definition span.hpp:363
std::remove_cv_t< type_t > value_type
Represents the span value type.
Definition span.hpp:70
auto try_copy_to(span< type_t, length > &destination) const noexcept -> bool
Attempts to copy the current xtd::span <type_t> to a destination xtd::span <type_t> and returns a val...
Definition span.hpp:406
auto equals(const object &obj) const noexcept -> bool override
Determines whether the specified object is equal to the current object.
Definition span.hpp:270
type_t & reference
Represents the span reference type.
Definition span.hpp:80
auto fill(const type_t &value) -> void
Fills the elements of this span with a specified value.
Definition span.hpp:278
xtd::ptrdiff difference_type
Represents the span difference type (usually xtd::ptrdiff).
Definition span.hpp:74
constexpr span(type_t *const data, size_type length)
Creates an xtd::span with specified data pointer and count.
Definition span.hpp:183
auto last() const -> span< type_t, count >
Obtains a subspan consisting of the last N elements of the sequence.
Definition span.hpp:328
constexpr span(collection_t &items, size_type length)
Creates an xtd::span with specified collection and count.
Definition span.hpp:170
constexpr auto is_empty() const noexcept -> bool
Returns a value that indicates whether the current xtd::span <type_t> is empty.
Definition span.hpp:233
constexpr span(collection_t &items, const xtd::range &range)
Creates an xtd::span with specified collection, and range.
Definition span.hpp:191
constexpr span(std::initializer_list< type_t > items) noexcept
Creates an xtd::span with specified initializer list.
Definition span.hpp:154
auto to_string() const noexcept -> xtd::string override
Returns the string representation of this xtd::span <type_t> object.
Definition span.hpp:396
auto first() const -> span< type_t, count >
Obtains a subspan consisting of the first count elements of the sequence.
Definition span.hpp:287
Contains xtd::collections::generic::enumerable concept.
Contains xtd::dynamic_extent field.
static auto format(const basic_string< char > &fmt, args_t &&... args) -> basic_string
@ argument
The argument is not valid.
Definition exception_case.hpp:31
@ index_out_of_range
The index is out of range.
Definition exception_case.hpp:61
@ argument_null
The argument is null.
Definition exception_case.hpp:33
@ argument_out_of_range
The argument is out of range.
Definition exception_case.hpp:35
#define typeof_
Used to obtain the type object of a specified type or object.
Definition typeof.hpp:24
constexpr auto dynamic_extent
Represents the constant of type xtd::usize signifying that the span has dynamic extent.
Definition dynamic_extent.hpp:23
constexpr auto npos
Represents a value that is not a valid position in a collection.
Definition npos.hpp:26
null_ptr null
Represents a null pointer value.
std::ptrdiff_t ptrdiff
Represent the signed integer type of the result of subtracting two pointers.
Definition ptrdiff.hpp:23
std::size_t usize
Represents an unsigned size of any object in bytes.
Definition usize.hpp:22
auto is(xtd::any value) -> bool
Checks if the result of an expression is compatible with a given type.
Definition is.hpp:485
auto new_ptr(args_t &&... args) -> xtd::ptr< type_t >
The xtd::new_ptr operator creates a xtd::ptr object.
Definition new_ptr.hpp:24
@ s
The S key.
Definition console_key.hpp:124
Contains xtd::iequatable interface.
Contains xtd::index struct.
Contains xtd::is method.
Contains xtd::iterable concept.
Contains xtd::iterable_value_type alias.
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
constexpr auto data() const noexcept -> const_pointer
Gets direct access to the underlying contiguous storage.
Definition read_only_span.hpp:197
constexpr auto size() const noexcept -> size_type
Returns the number of elements.
Definition read_only_span.hpp:213
Contains xtd::null pointer valiue.
Contains xtd::object class.
Contains xtd::ptrdiff type.
Contains xtd::range class.
Contains xtd::collections::generic::helpers::raw_array class.
Represents a type that can be used to index a collection either from the beginning or the end.
Definition index.hpp:38
auto get_offset(value_type length) const noexcept -> xtd::usize
Calculates the offset from the start of the collection using the specified collection length.
Contains typeof_ keyword.
Contains xtd::views alias namespace.
Contains xtd::collections::generic::helpers::wrap_pointer_iterator class.