10#include "gaia/config/config.h"
12#include <initializer_list>
16#include "gaia/core/iterator.h"
17#include "gaia/core/utility.h"
22 using span_difference_type = size_t;
24 using span_size_type = size_t;
28 template <
typename T, u
int32_t N>
30 template <
typename T, u
int32_t N>
31 using sarray = cnt::sarr<T, N>;
36 inline constexpr span_size_type DynamicSpanExtent = (span_size_type)-1;
41 template <
typename T, span_
size_type Extent = DynamicSpanExtent>
46 template <
typename T, span_
size_type Extent>
48 constexpr span_storage() noexcept = default;
49 constexpr span_storage(const span_storage&) noexcept = default;
50 constexpr span_storage(span_storage&&) noexcept = default;
51 constexpr span_storage& operator=(const span_storage&) noexcept = default;
52 constexpr span_storage& operator=(span_storage&&) noexcept = default;
53 constexpr span_storage(T* ptr_, span_size_type ) noexcept: beg(ptr_), end(ptr_ + Extent) {}
54 ~span_storage() noexcept = default;
58 static constexpr span_size_type size = Extent;
62 struct span_storage<T, DynamicSpanExtent> {
63 constexpr span_storage() noexcept = default;
64 constexpr span_storage(const span_storage&) noexcept = default;
65 constexpr span_storage(span_storage&&) noexcept = default;
66 constexpr span_storage& operator=(const span_storage&) noexcept = default;
67 constexpr span_storage& operator=(span_storage&&) noexcept = default;
68 constexpr span_storage(T* ptr_, span_size_type size_) noexcept: beg(ptr_), end(ptr_ + size_) {}
69 ~span_storage() noexcept = default;
76 struct is_span: std::false_type {};
78 template <
typename T, span_
size_type S>
79 struct is_span<span<T, S>>: std::true_type {};
82 struct is_std_array: std::false_type {};
84 template <
typename T, auto N>
85 struct is_std_array<gaia::cnt::sarray<T, N>>: std::true_type {};
87 template <
typename C,
typename U = raw_t<C>>
89 static constexpr bool value =
90 !is_span<U>::value && !is_std_array<U>::value && !std::is_array<U>::value && has_data_size<C>::value;
93 template <
typename,
typename,
typename =
void>
94 struct is_container_element_kind_compatible: std::false_type {};
96 template <
typename T,
typename E>
97 struct is_container_element_kind_compatible<
99 typename std::enable_if<
100 !std::is_same<typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type, void>::value &&
102 typename std::remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[],
103 E (*)[]>::value>::type>: std::true_type {};
110 template <
typename T, span_
size_type Extent>
113 std::is_object<T>::value,
"A span's T must be an object type (not a "
114 "reference type or void)");
116 detail::is_complete<T>::value,
"A span's T must be a complete type (not a forward "
118 static_assert(!std::is_abstract<T>::value,
"A span's T cannot be an abstract class type");
120 using m_datatype = detail::span_storage<T, Extent>;
156 template <span_
size_type E = Extent,
typename std::enable_if<(E == DynamicSpanExtent || E <= 0),
int>::type = 0>
157 constexpr span() noexcept {}
163 typename std::enable_if<std::is_convertible<U (*)[], element_kind (*)[]>::value,
int>::type = 0>
164 span(std::initializer_list<U>) =
delete;
170 GAIA_ASSERT(extent == DynamicSpanExtent || extent == count);
177 GAIA_ASSERT(extent == DynamicSpanExtent || ((uintptr_t)(end - begin) == (uintptr_t)extent));
185 span_size_type N, span_size_type E = Extent,
186 typename std::enable_if<
187 (E == DynamicSpanExtent || N == E) &&
188 detail::is_container_element_kind_compatible<element_kind (&)[N], T>::value,
197 typename Container, span_size_type E = Extent,
198 typename std::enable_if<
199 E == DynamicSpanExtent && detail::is_container<Container>::value &&
200 detail::is_container_element_kind_compatible<Container&, T>::value,
202 constexpr span(Container& cont): m_data(detail::data(cont), detail::size(cont)) {}
209 typename Container, span_size_type E = Extent,
210 typename std::enable_if<
211 E == DynamicSpanExtent && detail::is_container<Container>::value &&
212 detail::is_container_element_kind_compatible<const Container&, T>::value,
214 constexpr span(
const Container& cont): m_data(detail::data(cont), detail::size(cont)) {}
216 constexpr span(
const span&)
noexcept =
default;
217 constexpr span& operator=(
const span&)
noexcept =
default;
224 typename T2, span_size_type Extent2,
225 typename std::enable_if<
226 (Extent == DynamicSpanExtent || Extent2 == DynamicSpanExtent || Extent == Extent2) &&
227 std::is_convertible<T2 (*)[], T (*)[]>::value,
231 ~span() noexcept = default;
235 GAIA_NODISCARD constexpr
pointer data() const noexcept {
242 return size_type(m_data.end - m_data.beg);
247 GAIA_NODISCARD
constexpr bool empty() const noexcept {
248 return m_data.beg == m_data.end;
255 GAIA_ASSERT((uintptr_t)m_data.beg + index < (uintptr_t)m_data.end);
256 return *(m_data.beg + index);
298 template <span_
size_type Count>
300 GAIA_ASSERT(Count <= size());
301 return {m_data.beg, Count};
308 GAIA_ASSERT(count <= size());
309 return {m_data.beg, count};
315 template <span_
size_type Count>
317 GAIA_ASSERT(Count <= size());
318 return {m_data.beg + (size() - Count), Count};
325 GAIA_ASSERT(count <= size());
326 return {m_data.beg + (size() - count), count};
332 GAIA_ASSERT(!empty());
339 GAIA_ASSERT(!empty());
340 return *(m_data.beg + (size() - 1));
346 template <span_
size_type Offset, span_
size_type Count = DynamicSpanExtent>
348 T, Count != DynamicSpanExtent ? Count : (Extent != DynamicSpanExtent ? Extent - Offset : DynamicSpanExtent)>;
354 template <span_
size_type Offset, span_
size_type Count = DynamicSpanExtent>
356 GAIA_ASSERT(Offset <= size() && (Count == DynamicSpanExtent || Offset + Count <= size()));
357 return {m_data.beg + Offset, Count != DynamicSpanExtent ? Count : size() - Offset};
366 GAIA_ASSERT(offset <= size() && (count == DynamicSpanExtent || offset + count <= size()));
367 return {m_data.beg + offset, count != DynamicSpanExtent ? count : size() - offset};
375 template <
typename T,
size_t N>
376 span(T (&arr)[N]) -> span<T, N>;
382 template <
typename T,
size_t N>
389 template <
typename T,
size_t N>
395 template <
typename Container>
396 span(Container& cont)
397 -> span<typename std::remove_reference<decltype(*detail::data(std::declval<Container&>()))>::type>;
402 template <
typename Container>
403 span(
const Container& cont) -> span<const typename Container::value_type>;
411 template <span_
size_type N,
typename E, span_
size_type S>
412 constexpr auto get(span<E, S> s) ->
decltype(s[N]) {
420 template <
typename T,
size_t Extent>
421 struct tuple_size<gaia::core::span<T, Extent>>:
public integral_constant<size_t, Extent> {};
423 template <
typename T>
424 struct tuple_size<gaia::core::span<T, gaia::core::DynamicSpanExtent>>;
426 template <size_t I, typename T, size_t Extent>
427 struct tuple_element<I, gaia::core::span<T, Extent>> {
428 static_assert(Extent != gaia::core::DynamicSpanExtent && I < Extent,
"");
Array of elements of type.
Definition darray_ext_impl.h:31
Non-owning view over a contiguous sequence of objects.
Definition span_impl.h:111
typename std::remove_cv< T >::type value_type
Element type without const qualification.
Definition span_impl.h:126
constexpr span(const Container &cont)
Constructs a dynamic-extent view over a compatible const container.
Definition span_impl.h:214
GAIA_NODISCARD constexpr iterator begin() noexcept
Returns an iterator to the first element.
Definition span_impl.h:261
constexpr span(element_kind(&arr)[N]) noexcept
Constructs a view over a compatible built-in array.
Definition span_impl.h:190
element_kind * pointer
Pointer to an element.
Definition span_impl.h:132
GAIA_NODISCARD constexpr reference front() const
Returns the first element.
Definition span_impl.h:331
GAIA_NODISCARD constexpr reference back() const
Returns the final element.
Definition span_impl.h:338
const_pointer const_iterator
Const iterator type.
Definition span_impl.h:143
span_difference_type difference_type
Type used for iterator differences.
Definition span_impl.h:130
span_size_type size_type
Type used for element counts.
Definition span_impl.h:128
const element_kind * const_pointer
Pointer to a const element.
Definition span_impl.h:134
GAIA_NODISCARD constexpr span< element_kind, DynamicSpanExtent > subspan(size_type offset, size_type count=DynamicSpanExtent) const
Returns a dynamic-extent subspan.
Definition span_impl.h:365
GAIA_NODISCARD constexpr const_iterator cend() const noexcept
Returns a const iterator one past the final element.
Definition span_impl.h:291
constexpr span(const span< T2, Extent2 > &other) noexcept
Constructs a compatible span from another element type or extent.
Definition span_impl.h:229
GAIA_NODISCARD constexpr iterator begin() const noexcept
Returns an iterator to the first element.
Definition span_impl.h:267
element_kind & reference
Reference to an element.
Definition span_impl.h:136
pointer iterator
Mutable iterator type.
Definition span_impl.h:141
GAIA_NODISCARD constexpr const_iterator end() const noexcept
Returns a const iterator one past the final element.
Definition span_impl.h:285
constexpr span(pointer ptr, size_type count)
Constructs a view over count elements starting at ptr.
Definition span_impl.h:169
GAIA_NODISCARD constexpr reference operator[](size_type index) const
Returns the element at index.
Definition span_impl.h:254
GAIA_NODISCARD constexpr span< element_kind, DynamicSpanExtent > first(size_type count) const
Returns a dynamic-extent view over the first count elements.
Definition span_impl.h:307
const element_kind & const_reference
Reference to a const element.
Definition span_impl.h:138
GAIA_NODISCARD constexpr bool empty() const noexcept
Checks whether the view is empty.
Definition span_impl.h:247
GAIA_NODISCARD constexpr subspan_return_t< Offset, Count > subspan() const
Returns a subspan selected with compile-time offset and count.
Definition span_impl.h:355
GAIA_NODISCARD constexpr size_type size() const noexcept
Returns the number of elements in the view.
Definition span_impl.h:241
GAIA_NODISCARD constexpr span< element_kind, Count > first() const
Returns the first Count elements with a compile-time extent.
Definition span_impl.h:299
T element_kind
Element type, including const qualification.
Definition span_impl.h:124
GAIA_NODISCARD constexpr iterator end() noexcept
Returns an iterator one past the final element.
Definition span_impl.h:279
GAIA_NODISCARD constexpr span< element_kind, DynamicSpanExtent > last(size_type count) const
Returns a dynamic-extent view over the last count elements.
Definition span_impl.h:324
constexpr span(Container &cont)
Constructs a dynamic-extent view over a compatible mutable container.
Definition span_impl.h:202
GAIA_NODISCARD constexpr const_iterator cbegin() const noexcept
Returns a const iterator to the first element.
Definition span_impl.h:273
constexpr span(pointer begin, pointer end)
Constructs a view over the half-open range [begin, end).
Definition span_impl.h:176
GAIA_NODISCARD constexpr span< element_kind, Count > last() const
Returns the last Count elements with a compile-time extent.
Definition span_impl.h:316
span(std::initializer_list< U >)=delete
Rejects temporary initializer-list storage because its backing array expires at the end of the full e...