10#include "gaia/config/config.h"
15#include "gaia/core/iterator.h"
16#include "gaia/core/utility.h"
21 using span_diff_type = size_t;
23 using span_size_type = size_t;
27 template <
typename T, u
int32_t N>
29 template <
typename T, u
int32_t N>
30 using sarray = cnt::sarr<T, N>;
35 inline constexpr span_size_type DynamicSpanExtent = (span_size_type)-1;
40 template <
typename T, span_
size_type Extent = DynamicSpanExtent>
45 template <
typename T, span_
size_type Extent>
47 constexpr span_storage() noexcept = default;
48 constexpr span_storage(const span_storage&) noexcept = default;
49 constexpr span_storage(span_storage&&) noexcept = default;
50 constexpr span_storage& operator=(const span_storage&) noexcept = default;
51 constexpr span_storage& operator=(span_storage&&) noexcept = default;
52 constexpr span_storage(T* ptr_, span_size_type ) noexcept: beg(ptr_), end(ptr_ + Extent) {}
53 ~span_storage() noexcept = default;
57 static constexpr span_size_type size = Extent;
61 struct span_storage<T, DynamicSpanExtent> {
62 constexpr span_storage() noexcept = default;
63 constexpr span_storage(const span_storage&) noexcept = default;
64 constexpr span_storage(span_storage&&) noexcept = default;
65 constexpr span_storage& operator=(const span_storage&) noexcept = default;
66 constexpr span_storage& operator=(span_storage&&) noexcept = default;
67 constexpr span_storage(T* ptr_, span_size_type size_) noexcept: beg(ptr_), end(ptr_ + size_) {}
68 ~span_storage() noexcept = default;
75 struct is_span: std::false_type {};
77 template <
typename T, span_
size_type S>
78 struct is_span<span<T, S>>: std::true_type {};
81 struct is_std_array: std::false_type {};
83 template <
typename T, auto N>
84 struct is_std_array<gaia::cnt::sarray<T, N>>: std::true_type {};
86 template <
typename C,
typename U = raw_t<C>>
88 static constexpr bool value =
89 !is_span<U>::value && !is_std_array<U>::value && !std::is_array<U>::value && has_data_size<C>::value;
92 template <
typename,
typename,
typename =
void>
93 struct is_container_element_kind_compatible: std::false_type {};
95 template <
typename T,
typename E>
96 struct is_container_element_kind_compatible<
98 typename std::enable_if<
99 !std::is_same<typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type, void>::value &&
101 typename std::remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[],
102 E (*)[]>::value>::type>: std::true_type {};
109 template <
typename T, span_
size_type Extent>
112 std::is_object<T>::value,
"A span's T must be an object type (not a "
113 "reference type or void)");
115 detail::is_complete<T>::value,
"A span's T must be a complete type (not a forward "
117 static_assert(!std::is_abstract<T>::value,
"A span's T cannot be an abstract class type");
119 using m_datatype = detail::span_storage<T, Extent>;
155 template <span_
size_type E = Extent,
typename std::enable_if<(E == DynamicSpanExtent || E <= 0),
int>::type = 0>
156 constexpr span() noexcept {}
161 constexpr span(po
inter ptr,
size_type count): m_data(ptr, count) {
162 GAIA_ASSERT(extent == DynamicSpanExtent || extent == count);
168 constexpr span(po
inter begin, po
inter end): m_data(begin, end - begin) {
169 GAIA_ASSERT(extent == DynamicSpanExtent || ((u
intptr_t)(end - begin) == (u
intptr_t)extent));
177 span_
size_type N, span_
size_type E = Extent,
178 typename std::enable_if<
179 (E == DynamicSpanExtent || N == E) &&
180 detail::is_container_element_kind_compatible<element_kind (&)[N], T>::value,
189 typename Container, span_size_type E = Extent,
190 typename std::enable_if<
191 E == DynamicSpanExtent && detail::is_container<Container>::value &&
192 detail::is_container_element_kind_compatible<Container&, T>::value,
194 constexpr span(Container& cont): m_data(detail::data(cont), detail::size(cont)) {}
201 typename Container, span_size_type E = Extent,
202 typename std::enable_if<
203 E == DynamicSpanExtent && detail::is_container<Container>::value &&
204 detail::is_container_element_kind_compatible<const Container&, T>::value,
206 constexpr span(
const Container& cont): m_data(detail::data(cont), detail::size(cont)) {}
208 constexpr span(
const span&)
noexcept =
default;
209 constexpr span& operator=(
const span&)
noexcept =
default;
216 typename T2, span_size_type Extent2,
217 typename std::enable_if<
218 (Extent == DynamicSpanExtent || Extent2 == DynamicSpanExtent || Extent == Extent2) &&
219 std::is_convertible<T2 (*)[], T (*)[]>::value,
223 ~span() noexcept = default;
227 GAIA_NODISCARD constexpr
pointer data() const noexcept {
234 return size_type(m_data.end - m_data.beg);
239 GAIA_NODISCARD
constexpr bool empty() const noexcept {
240 return m_data.beg == m_data.end;
247 GAIA_ASSERT((uintptr_t)m_data.beg + index < (uintptr_t)m_data.end);
248 return *(m_data.beg + index);
290 template <span_
size_type Count>
292 GAIA_ASSERT(Count <= size());
293 return {m_data.beg, Count};
300 GAIA_ASSERT(count <= size());
301 return {m_data.beg, count};
307 template <span_
size_type Count>
309 GAIA_ASSERT(Count <= size());
310 return {m_data.beg + (size() - Count), Count};
317 GAIA_ASSERT(count <= size());
318 return {m_data.beg + (size() - count), count};
324 GAIA_ASSERT(!empty());
331 GAIA_ASSERT(!empty());
332 return *(m_data.beg + (size() - 1));
338 template <span_
size_type Offset, span_
size_type Count = DynamicSpanExtent>
340 T, Count != DynamicSpanExtent ? Count : (Extent != DynamicSpanExtent ? Extent - Offset : DynamicSpanExtent)>;
346 template <span_
size_type Offset, span_
size_type Count = DynamicSpanExtent>
348 GAIA_ASSERT(Offset <= size() && (Count == DynamicSpanExtent || Offset + Count <= size()));
349 return {m_data.beg + Offset, Count != DynamicSpanExtent ? Count : size() - Offset};
358 GAIA_ASSERT(offset <= size() && (count == DynamicSpanExtent || offset + count <= size()));
359 return {m_data.beg + offset, count != DynamicSpanExtent ? count : size() - offset};
367 template <
typename T,
size_t N>
368 span(T (&arr)[N]) -> span<T, N>;
374 template <
typename T,
size_t N>
381 template <
typename T,
size_t N>
387 template <
typename Container>
388 span(Container& cont)
389 -> span<typename std::remove_reference<decltype(*detail::data(std::declval<Container&>()))>::type>;
394 template <
typename Container>
395 span(
const Container& cont) -> span<const typename Container::value_type>;
403 template <span_
size_type N,
typename E, span_
size_type S>
404 constexpr auto get(span<E, S> s) ->
decltype(s[N]) {
412 template <
typename T,
size_t Extent>
413 struct tuple_size<gaia::core::span<T, Extent>>:
public integral_constant<size_t, Extent> {};
415 template <
typename T>
416 struct tuple_size<gaia::core::span<T, gaia::core::DynamicSpanExtent>>;
418 template <size_t I, typename T, size_t Extent>
419 struct tuple_element<I, gaia::core::span<T, Extent>> {
420 static_assert(Extent != gaia::core::DynamicSpanExtent && I < Extent,
"");
Array with variable size of elements of type.
Definition darray_impl.h:27
Non-owning view over a contiguous sequence of objects.
Definition span_impl.h:110
typename std::remove_cv< T >::type value_type
Element type without const qualification.
Definition span_impl.h:125
constexpr span(const Container &cont)
Constructs a dynamic-extent view over a compatible const container.
Definition span_impl.h:206
GAIA_NODISCARD constexpr iterator begin() noexcept
Returns an iterator to the first element.
Definition span_impl.h:253
constexpr span(element_kind(&arr)[N]) noexcept
Constructs a view over a compatible built-in array.
Definition span_impl.h:182
element_kind * pointer
Pointer to an element.
Definition span_impl.h:131
GAIA_NODISCARD constexpr reference front() const
Returns the first element.
Definition span_impl.h:323
GAIA_NODISCARD constexpr reference back() const
Returns the final element.
Definition span_impl.h:330
const_pointer const_iterator
Const iterator type.
Definition span_impl.h:142
span_size_type size_type
Type used for element counts.
Definition span_impl.h:127
const element_kind * const_pointer
Pointer to a const element.
Definition span_impl.h:133
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:357
GAIA_NODISCARD constexpr const_iterator cend() const noexcept
Returns a const iterator one past the final element.
Definition span_impl.h:283
constexpr span(const span< T2, Extent2 > &other) noexcept
Constructs a compatible span from another element type or extent.
Definition span_impl.h:221
GAIA_NODISCARD constexpr iterator begin() const noexcept
Returns an iterator to the first element.
Definition span_impl.h:259
element_kind & reference
Reference to an element.
Definition span_impl.h:135
pointer iterator
Mutable iterator type.
Definition span_impl.h:140
GAIA_NODISCARD constexpr const_iterator end() const noexcept
Returns a const iterator one past the final element.
Definition span_impl.h:277
span_diff_type difference_type
Type used for iterator differences.
Definition span_impl.h:129
GAIA_NODISCARD constexpr reference operator[](size_type index) const
Returns the element at index.
Definition span_impl.h:246
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:299
const element_kind & const_reference
Reference to a const element.
Definition span_impl.h:137
GAIA_NODISCARD constexpr bool empty() const noexcept
Checks whether the view is empty.
Definition span_impl.h:239
GAIA_NODISCARD constexpr subspan_return_t< Offset, Count > subspan() const
Returns a subspan selected with compile-time offset and count.
Definition span_impl.h:347
GAIA_NODISCARD constexpr size_type size() const noexcept
Returns the number of elements in the view.
Definition span_impl.h:233
GAIA_NODISCARD constexpr span< element_kind, Count > first() const
Returns the first Count elements with a compile-time extent.
Definition span_impl.h:291
T element_kind
Element type, including const qualification.
Definition span_impl.h:123
GAIA_NODISCARD constexpr iterator end() noexcept
Returns an iterator one past the final element.
Definition span_impl.h:271
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:316
constexpr span(Container &cont)
Constructs a dynamic-extent view over a compatible mutable container.
Definition span_impl.h:194
GAIA_NODISCARD constexpr const_iterator cbegin() const noexcept
Returns a const iterator to the first element.
Definition span_impl.h:265
GAIA_NODISCARD constexpr span< element_kind, Count > last() const
Returns the last Count elements with a compile-time extent.
Definition span_impl.h:308