13#ifndef TCB_SPAN_HPP_INCLUDED
14#define TCB_SPAN_HPP_INCLUDED
21#ifndef TCB_SPAN_NO_EXCEPTIONS
23#if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND))
24#define TCB_SPAN_NO_EXCEPTIONS
28#ifndef TCB_SPAN_NO_EXCEPTIONS
35#ifndef TCB_SPAN_NAMESPACE_NAME
36#define TCB_SPAN_NAMESPACE_NAME Infinity::Types::Core
39#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
40#define TCB_SPAN_HAVE_CPP17
43#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
44#define TCB_SPAN_HAVE_CPP14
50#if !defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION) && \
51 !defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) && \
52 !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
53#if defined(NDEBUG) || !defined(TCB_SPAN_HAVE_CPP14)
54#define TCB_SPAN_NO_CONTRACT_CHECKING
56#define TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION
60#define TCB_SPAN_THROW_ON_CONTRACT_VIOLATION
61#if defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION)
72#elif defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION)
73[[noreturn]]
inline void contract_violation(
const char* )
79#if !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
80#define TCB_SPAN_STRINGIFY(cond) #cond
81#define TCB_SPAN_EXPECT(cond) \
82 cond ? (void) 0 : contract_violation("Expected " TCB_SPAN_STRINGIFY(cond))
84#define TCB_SPAN_EXPECT(cond)
87#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_inline_variables)
88#define TCB_SPAN_INLINE_VAR inline
90#define TCB_SPAN_INLINE_VAR
93#if defined(TCB_SPAN_HAVE_CPP14) || \
94 (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
95#define TCB_SPAN_HAVE_CPP14_CONSTEXPR
98#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR)
99#define TCB_SPAN_CONSTEXPR14 constexpr
101#define TCB_SPAN_CONSTEXPR14
104#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR) && \
105 (!defined(_MSC_VER) || _MSC_VER > 1900)
106#define TCB_SPAN_CONSTEXPR_ASSIGN constexpr
108#define TCB_SPAN_CONSTEXPR_ASSIGN
111#if defined(TCB_SPAN_NO_CONTRACT_CHECKING)
112#define TCB_SPAN_CONSTEXPR11 constexpr
114#define TCB_SPAN_CONSTEXPR11 TCB_SPAN_CONSTEXPR14
117#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_deduction_guides)
118#define TCB_SPAN_HAVE_DEDUCTION_GUIDES
121#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_byte)
122#define TCB_SPAN_HAVE_STD_BYTE
125#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_array_constexpr)
126#define TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC
129#if defined(TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC)
130#define TCB_SPAN_ARRAY_CONSTEXPR constexpr
132#define TCB_SPAN_ARRAY_CONSTEXPR
135#ifdef TCB_SPAN_HAVE_STD_BYTE
136using byte = std::byte;
141#if defined(TCB_SPAN_HAVE_CPP17)
142#define TCB_SPAN_NODISCARD [[nodiscard]]
144#define TCB_SPAN_NODISCARD
149template <
typename ElementType,
size_t Extent = dynamic_extent>
154template <
typename E,
size_t S>
163 static constexpr size_t size = S;
171 : ptr(p_ptr), size(p_size)
179#if defined(TCB_SPAN_HAVE_CPP17) || \
180 defined(__cpp_lib_nonmember_container_access)
185constexpr auto size(
const C& c) ->
decltype(c.size())
190template <
class T,
size_t N>
191constexpr size_t size(
const T (&)[N])
noexcept
197constexpr auto data(C& c) ->
decltype(c.data())
203constexpr auto data(
const C& c) ->
decltype(c.data())
208template <
class T,
size_t N>
209constexpr T*
data(T (&array)[N])
noexcept
215constexpr const E*
data(std::initializer_list<E> il)
noexcept
221#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_void_t)
224template <
typename...>
230 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
235template <
typename T,
size_t S>
241template <
typename T,
size_t N>
244template <
typename,
typename =
void>
249 decltype(detail::data(std::declval<T>()))>>
252template <
typename C,
typename U = uncvref_t<C>>
262template <
typename,
typename,
typename =
void>
265template <
typename T,
typename E>
268 typename
std::enable_if<
270 typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type,
273 remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[],
278template <
typename,
typename =
size_t>
286template <
typename ElementType,
size_t Extent>
288 static_assert(std::is_object<ElementType>::value,
289 "A span's ElementType must be an object type (not a "
290 "reference type or void)");
292 "A span's ElementType must be a complete type (not a forward "
294 static_assert(!std::is_abstract<ElementType>::value,
295 "A span's ElementType cannot be an abstract class type");
302 using value_type =
typename std::remove_cv<ElementType>::type;
317 typename std::enable_if<(E ==
dynamic_extent || E <= 0), int>::type = 0>
322 : storage_(ptr, count)
328 : storage_(first_elem, last_elem - first_elem)
331 last_elem - first_elem ==
332 static_cast<std::ptrdiff_t
>(extent));
335 template <
size_t N,
size_t E = Extent,
336 typename std::enable_if<
339 element_type (&)[N], ElementType>::value,
344 template <
typename T,
size_t N,
size_t E = Extent,
345 typename std::enable_if<
348 std::array<T, N>&, ElementType>::value,
350 TCB_SPAN_ARRAY_CONSTEXPR
span(std::array<T, N>& arr) noexcept
351 : storage_(arr.data(), N)
354 template <
typename T,
size_t N,
size_t E = Extent,
355 typename std::enable_if<
358 const std::array<T, N>&, ElementType>::value,
360 TCB_SPAN_ARRAY_CONSTEXPR
span(
const std::array<T, N>& arr) noexcept
361 : storage_(arr.data(), N)
365 typename Container,
size_t E = Extent,
366 typename std::enable_if<
369 Container&, ElementType>::value,
371 constexpr span(Container& cont)
372 : storage_(detail::
data(cont), detail::
size(cont))
376 typename Container,
size_t E = Extent,
377 typename std::enable_if<
380 const Container&, ElementType>::value,
382 constexpr span(
const Container& cont)
383 : storage_(detail::
data(cont), detail::
size(cont))
386 constexpr span(
const span& other)
noexcept =
default;
388 template <
typename OtherElementType,
size_t OtherExtent,
389 typename std::enable_if<
391 Extent == OtherExtent) &&
392 std::is_convertible<OtherElementType (*)[],
393 ElementType (*)[]>::value,
396 : storage_(other.data(), other.size())
401 TCB_SPAN_CONSTEXPR_ASSIGN
span&
402 operator=(const
span& other) noexcept = default;
405 template <
size_t Count>
408 TCB_SPAN_EXPECT(Count <=
size());
409 return {
data(), Count};
412 template <
size_t Count>
415 TCB_SPAN_EXPECT(Count <=
size());
416 return {
data() + (
size() - Count), Count};
419 template <
size_t Offset,
size_t Count = dynamic_extent>
426 template <
size_t Offset,
size_t Count = dynamic_extent>
429 TCB_SPAN_EXPECT(Offset <=
size() &&
431 return {
data() + Offset,
438 TCB_SPAN_EXPECT(count <=
size());
439 return {
data(), count};
445 TCB_SPAN_EXPECT(count <=
size());
446 return {
data() + (
size() - count), count};
452 TCB_SPAN_EXPECT(offset <=
size() &&
454 return {
data() + offset,
466 TCB_SPAN_NODISCARD
constexpr bool empty() const noexcept
474 TCB_SPAN_EXPECT(idx <
size());
475 return *(
data() + idx);
480 TCB_SPAN_EXPECT(!
empty());
486 TCB_SPAN_EXPECT(!
empty());
508 storage_type storage_{};
511#ifdef TCB_SPAN_HAVE_DEDUCTION_GUIDES
514template <
class T,
size_t N>
515span(T (&)[N])->span<T, N>;
517template <
class T,
size_t N>
518span(std::array<T, N>&)->span<T, N>;
520template <
class T,
size_t N>
521span(
const std::array<T, N>&)->span<
const T, N>;
523template <
class Container>
524span(Container&)->span<
typename std::remove_reference<
525 decltype(*detail::data(std::declval<Container&>()))>::type>;
527template <
class Container>
528span(
const Container&)->span<
const typename Container::value_type>;
532template <
typename ElementType,
size_t Extent>
533constexpr span<ElementType, Extent>
539template <
typename T,
size_t N>
545template <
typename T,
size_t N>
551template <
typename T,
size_t N>
552TCB_SPAN_ARRAY_CONSTEXPR span<const T, N>
558template <
typename Container>
559constexpr span<
typename std::remove_reference<
560 decltype(*detail::data(std::declval<Container&>()))>::type>
566template <
typename Container>
567constexpr span<const typename Container::value_type>
573template <
typename ElementType,
size_t Extent>
574span<
const byte, ((Extent == dynamic_extent) ? dynamic_extent
575 : sizeof(ElementType) * Extent)>
578 return {
reinterpret_cast<const byte*
>(s.data()), s.size_bytes()};
582 class ElementType,
size_t Extent,
583 typename std::enable_if<!std::is_const<ElementType>::value,
int>::type = 0>
584span<byte, ((Extent == dynamic_extent) ? dynamic_extent
585 : sizeof(ElementType) * Extent)>
588 return {
reinterpret_cast<byte*
>(s.data()), s.size_bytes()};
591template <
size_t N,
typename E,
size_t S>
601template <
typename ElementType,
size_t Extent>
603 :
public integral_constant<size_t, Extent> {};
605template <
typename ElementType>
607 ElementType, TCB_SPAN_NAMESPACE_NAME::dynamic_extent>>;
609template <size_t I, typename ElementType, size_t Extent>
610class tuple_element<I, TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>> {
612 static_assert(Extent != TCB_SPAN_NAMESPACE_NAME::dynamic_extent &&
615 using type = ElementType;
constexpr span(Container &cont)
Definition Span.hpp:371
TCB_SPAN_CONSTEXPR11 span< element_type, Count > last() const
Definition Span.hpp:413
constexpr span() noexcept
Definition Span.hpp:318
constexpr iterator end() const noexcept
Definition Span.hpp:495
constexpr span(const Container &cont)
Definition Span.hpp:382
std::reverse_iterator< iterator > reverse_iterator
Definition Span.hpp:310
ElementType element_type
Definition Span.hpp:301
constexpr iterator begin() const noexcept
Definition Span.hpp:493
TCB_SPAN_CONSTEXPR11 span(pointer first_elem, pointer last_elem)
Definition Span.hpp:327
static constexpr size_type extent
Definition Span.hpp:312
const element_type * const_pointer
Definition Span.hpp:306
constexpr span(const span &other) noexcept=default
typename std::remove_cv< ElementType >::type value_type
Definition Span.hpp:302
TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin() const noexcept
Definition Span.hpp:497
const element_type & const_reference
Definition Span.hpp:308
std::ptrdiff_t difference_type
Definition Span.hpp:304
TCB_SPAN_CONSTEXPR11 span< element_type, dynamic_extent > first(size_type count) const
Definition Span.hpp:436
pointer iterator
Definition Span.hpp:309
TCB_SPAN_CONSTEXPR11 reference back() const
Definition Span.hpp:484
constexpr size_type size() const noexcept
Definition Span.hpp:459
TCB_SPAN_CONSTEXPR11 reference front() const
Definition Span.hpp:478
constexpr size_type size_bytes() const noexcept
Definition Span.hpp:461
TCB_SPAN_CONSTEXPR11 reference operator[](size_type idx) const
Definition Span.hpp:472
TCB_SPAN_CONSTEXPR11 subspan_return_t< Offset, Count > subspan() const
Definition Span.hpp:427
constexpr span(element_type(&arr)[N]) noexcept
Definition Span.hpp:341
TCB_SPAN_ARRAY_CONSTEXPR span(std::array< T, N > &arr) noexcept
Definition Span.hpp:350
TCB_SPAN_ARRAY_CONSTEXPR span(const std::array< T, N > &arr) noexcept
Definition Span.hpp:360
TCB_SPAN_CONSTEXPR11 span< element_type, dynamic_extent > subspan(size_type offset, size_type count=dynamic_extent) const
Definition Span.hpp:450
TCB_SPAN_CONSTEXPR11 span(pointer ptr, size_type count)
Definition Span.hpp:321
constexpr pointer data() const noexcept
Definition Span.hpp:490
TCB_SPAN_CONSTEXPR11 span< element_type, dynamic_extent > last(size_type count) const
Definition Span.hpp:443
TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rend() const noexcept
Definition Span.hpp:502
constexpr span(const span< OtherElementType, OtherExtent > &other) noexcept
Definition Span.hpp:395
element_type * pointer
Definition Span.hpp:305
element_type & reference
Definition Span.hpp:307
size_t size_type
Definition Span.hpp:303
TCB_SPAN_NODISCARD constexpr bool empty() const noexcept
Definition Span.hpp:466
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition Span.hpp:230
constexpr auto size(const C &c) -> decltype(c.size())
Definition Span.hpp:185
void void_t
Definition Span.hpp:225
typename std::remove_pointer< T >::type remove_pointer_t
Definition Span.hpp:260
constexpr auto data(C &c) -> decltype(c.data())
Definition Span.hpp:197
span< byte,((Extent==dynamic_extent) ? dynamic_extent :sizeof(ElementType) *Extent)> as_writable_bytes(span< ElementType, Extent > s) noexcept
Definition Span.hpp:586
constexpr span< ElementType, Extent > make_span(span< ElementType, Extent > s) noexcept
Definition Span.hpp:534
span< const byte,((Extent==dynamic_extent) ? dynamic_extent :sizeof(ElementType) *Extent)> as_bytes(span< ElementType, Extent > s) noexcept
Definition Span.hpp:576
void contract_violation(const char *msg)
Definition Span.hpp:67
constexpr auto get(span< E, S > s) -> decltype(s[N])
Definition Span.hpp:592
unsigned char byte
Definition Span.hpp:138
TCB_SPAN_INLINE_VAR constexpr size_t dynamic_extent
Definition Span.hpp:147
contract_violation_error(const char *msg)
Definition Span.hpp:63
static constexpr bool value
Definition Span.hpp:254
constexpr span_storage() noexcept=default
constexpr span_storage() noexcept=default
static constexpr size_t size
Definition Span.hpp:163
E * ptr
Definition Span.hpp:162