101 std::is_object<T>::value,
"A span's T must be an object type (not a "
102 "reference type or void)");
106 static_assert(!std::is_abstract<T>::value,
"A span's T cannot be an abstract class type");
111 using element_kind = T;
112 using value_type =
typename std::remove_cv<T>::type;
113 using size_type = span_size_type;
114 using difference_type = span_diff_type;
115 using pointer = element_kind*;
116 using const_pointer =
const element_kind*;
117 using reference = element_kind&;
118 using const_reference =
const element_kind&;
120 using iterator = pointer;
121 using const_iterator = const_pointer;
124 static constexpr size_type extent = Extent;
130 template <span_
size_type E = Extent,
typename std::enable_if<(E == DynamicSpanExtent || E <= 0),
int>::type = 0>
131 constexpr span() noexcept {}
133 constexpr span(po
inter ptr,
size_type count): m_data(ptr, count) {
134 GAIA_ASSERT(extent == DynamicSpanExtent || extent == count);
137 constexpr span(po
inter begin, po
inter end): m_data(begin, end - begin) {
138 GAIA_ASSERT(extent == DynamicSpanExtent || ((u
intptr_t)(end - begin) == (u
intptr_t)extent));
142 span_
size_type N, span_
size_type E = Extent,
143 typename std::enable_if<
144 (E == DynamicSpanExtent || N == E) &&
145 detail::is_container_element_kind_compatible<element_kind (&)[N], T>::value,
147 constexpr span(element_kind (&arr)[N])
noexcept: m_data(arr, N) {}
150 typename Container, span_size_type E = Extent,
151 typename std::enable_if<
155 constexpr span(Container& cont): m_data(detail::data(cont), detail::size(cont)) {}
158 typename Container, span_size_type E = Extent,
159 typename std::enable_if<
163 constexpr span(
const Container& cont): m_data(detail::data(cont), detail::size(cont)) {}
165 constexpr span(
const span& other)
noexcept =
default;
166 constexpr span& operator=(
const span& other)
noexcept =
default;
169 typename T2, span_size_type Extent2,
170 typename std::enable_if<
171 (Extent == DynamicSpanExtent || Extent2 == DynamicSpanExtent || Extent == Extent2) &&
172 std::is_convertible<T2 (*)[], T (*)[]>::value,
176 ~span()
noexcept =
default;
178 GAIA_NODISCARD
constexpr pointer data()
const noexcept {
182 GAIA_NODISCARD
constexpr size_type size()
const noexcept {
183 return size_type(m_data.end - m_data.beg);
186 GAIA_NODISCARD
constexpr bool empty()
const noexcept {
187 return m_data.beg == m_data.end;
190 GAIA_NODISCARD
constexpr reference operator[](size_type index)
const {
191 GAIA_ASSERT((uintptr_t)m_data.beg + index < (uintptr_t)m_data.end);
192 return *(m_data.beg + index);
195 GAIA_NODISCARD
constexpr iterator begin()
noexcept {
199 GAIA_NODISCARD
constexpr iterator begin()
const noexcept {
203 GAIA_NODISCARD
constexpr const_iterator cbegin()
const noexcept {
207 GAIA_NODISCARD
constexpr iterator end()
noexcept {
211 GAIA_NODISCARD
constexpr const_iterator end()
const noexcept {
215 GAIA_NODISCARD
constexpr const_iterator cend()
const noexcept {
219 template <span_
size_type Count>
221 GAIA_ASSERT(Count <= size());
222 return {m_data.beg, Count};
226 GAIA_ASSERT(count <= size());
227 return {m_data.beg, count};
230 template <span_
size_type Count>
232 GAIA_ASSERT(Count <= size());
233 return {m_data.beg + (size() - Count), Count};
237 GAIA_ASSERT(count <= size());
238 return {m_data.beg + (size() - count), count};
241 GAIA_NODISCARD
constexpr reference front()
const {
242 GAIA_ASSERT(!empty());
246 GAIA_NODISCARD
constexpr reference back()
const {
247 GAIA_ASSERT(!empty());
248 return *(m_data.beg + (size() - 1));
251 template <span_
size_type Offset, span_
size_type Count = DynamicSpanExtent>
253 T, Count != DynamicSpanExtent ? Count : (Extent != DynamicSpanExtent ? Extent - Offset : DynamicSpanExtent)>;
255 template <span_
size_type Offset, span_
size_type Count = DynamicSpanExtent>
257 GAIA_ASSERT(Offset <= size() && (Count == DynamicSpanExtent || Offset + Count <= size()));
258 return {m_data.beg + Offset, Count != DynamicSpanExtent ? Count : size() - Offset};
262 subspan(size_type offset, size_type count = DynamicSpanExtent)
const {
263 GAIA_ASSERT(offset <= size() && (count == DynamicSpanExtent || offset + count <= size()));
264 return {m_data.beg + offset, count != DynamicSpanExtent ? count : size() - offset};