6#ifdef TCB_SPAN_NAMESPACE_NAME
8#define TTG_TCB_SPAN_NAMESPACE_NAME_AT_TOP_OF_SPAN_H TCB_SPAN_NAMESPACE_NAME
9#undef TCB_SPAN_NAMESPACE_NAME
14#define TCB_SPAN_NAMESPACE_NAME ttg
33#ifndef TCB_SPAN_NO_EXCEPTIONS
35#if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND))
36#define TCB_SPAN_NO_EXCEPTIONS
40#ifndef TCB_SPAN_NO_EXCEPTIONS
47#ifndef TCB_SPAN_NAMESPACE_NAME
48#define TCB_SPAN_NAMESPACE_NAME tcb
51#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
52#define TCB_SPAN_HAVE_CPP17
55#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
56#define TCB_SPAN_HAVE_CPP14
62#if !defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION) && !defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) && \
63 !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
64#if defined(NDEBUG) || !defined(TCB_SPAN_HAVE_CPP14)
65#define TCB_SPAN_NO_CONTRACT_CHECKING
67#define TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION
71#if defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION)
72 struct contract_violation_error : std::logic_error {
73 explicit contract_violation_error(
const char* msg) : std::logic_error(msg) {}
76 inline void contract_violation(
const char* msg) {
throw contract_violation_error(msg); }
78#elif defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION)
79 [[noreturn]]
inline void contract_violation(
const char* ) { std::terminate(); }
82#if !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
83#define TCB_SPAN_STRINGIFY(cond) #cond
84#define TCB_SPAN_EXPECT(cond) cond ? (void)0 : contract_violation("Expected " TCB_SPAN_STRINGIFY(cond))
86#define TCB_SPAN_EXPECT(cond)
89#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_inline_variables)
90#define TCB_SPAN_INLINE_VAR inline
92#define TCB_SPAN_INLINE_VAR
95#if defined(TCB_SPAN_HAVE_CPP14) || (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
96#define TCB_SPAN_HAVE_CPP14_CONSTEXPR
99#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR)
100#define TCB_SPAN_CONSTEXPR14 constexpr
102#define TCB_SPAN_CONSTEXPR14
105#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR) && (!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
136 using byte = std::byte;
141#if defined(TCB_SPAN_HAVE_CPP17)
142#define TCB_SPAN_NODISCARD [[nodiscard]]
144#define TCB_SPAN_NODISCARD
149 template <
typename ElementType, std::
size_t Extent = dynamic_extent>
154 template <
typename E, std::
size_t S>
161 static constexpr std::size_t
size = S;
164 template <
typename E>
168 constexpr
span_storage(E* p_ptr,
std::
size_t p_size) noexcept : ptr(p_ptr), size(p_size) {}
171 std::size_t size = 0;
175#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_nonmember_container_access)
180 constexpr auto size(
const C& c) ->
decltype(c.size()) {
184 template <
class T, std::
size_t N>
185 constexpr std::size_t size(
const T (&)[N])
noexcept {
190 constexpr auto data(C& c) ->
decltype(c.data()) {
195 constexpr auto data(
const C& c) ->
decltype(c.data()) {
199 template <
class T, std::
size_t N>
200 constexpr T*
data(T (&array)[N])
noexcept {
205 constexpr const E*
data(std::initializer_list<E> il)
noexcept {
210#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_void_t)
213 template <
typename...>
217 template <
typename T>
218 using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
223 template <
typename T, std::
size_t S>
229 template <
typename T, std::
size_t N>
232 template <
typename,
typename =
void>
235 template <
typename T>
237 T,
void_t<decltype(detail::size(std::declval<T>())), decltype(detail::data(std::declval<T>()))> >
240 template <
typename C,
typename U = uncvref_t<C> >
246 template <
typename T>
249 template <
typename,
typename,
typename =
void>
252 template <
typename T,
typename E>
255 typename
std::enable_if<
256 !std::is_same<typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type, void>::value>::type>
257 : std::is_convertible<remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[], E (*)[]> {};
259 template <
typename,
typename =
size_t>
262 template <
typename T>
267 template <
typename ElementType, std::
size_t Extent>
269 static_assert(std::is_object<ElementType>::value,
270 "A span's ElementType must be an object type (not a "
271 "reference type or void)");
273 "A span's ElementType must be a complete type (not a forward "
275 static_assert(!std::is_abstract<ElementType>::value,
"A span's ElementType cannot be an abstract class type");
282 using value_type =
typename std::remove_cv<ElementType>::type;
295 template <std::
size_t E = Extent,
typename std::enable_if<(E == dynamic_extent || E <= 0),
int>::type = 0>
296 constexpr span() noexcept {}
298 TCB_SPAN_CONSTEXPR11 span(po
inter ptr,
size_type count) : storage_(ptr, count) {
299 TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent);
302 TCB_SPAN_CONSTEXPR11 span(po
inter first_elem, po
inter last_elem) : storage_(first_elem, last_elem - first_elem) {
303 TCB_SPAN_EXPECT(extent == dynamic_extent || last_elem - first_elem == static_cast<std::ptrdiff_t>(extent));
306 template <std::
size_t N, std::
size_t E = Extent,
307 typename std::enable_if<(E == dynamic_extent || N == E) && detail::is_container_element_type_compatible<
308 element_type (&)[N], ElementType>::value,
312 template <std::size_t N, std::size_t E = Extent,
313 typename std::enable_if<
319 template <std::size_t N, std::size_t E = Extent,
326 template <
typename Container, std::size_t E = Extent,
327 typename std::enable_if<E == dynamic_extent && detail::is_container<Container>::value &&
330 constexpr span(Container& cont) : storage_(detail::
data(cont), detail::
size(cont)) {}
333 typename Container, std::size_t E = Extent,
334 typename std::enable_if<E == dynamic_extent && detail::is_container<Container>::value &&
337 constexpr span(
const Container& cont) : storage_(detail::
data(cont), detail::
size(cont)) {}
339 constexpr span(
const span& other)
noexcept =
default;
341 template <
typename OtherElementType, std::size_t OtherExtent,
342 typename std::enable_if<(Extent == OtherExtent || Extent ==
dynamic_extent) &&
343 std::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value,
352 template <
std::
size_t Count>
355 return {
data(), Count};
358 template <std::
size_t Count>
361 return {
data() + (
size() - Count), Count};
364 template <std::
size_t Offset, std::
size_t Count = dynamic_extent>
369 template <std::
size_t Offset, std::
size_t Count = dynamic_extent>
377 return {
data(), count};
382 return {
data() + (
size() - count), count};
386 size_type count = dynamic_extent)
const {
401 return *(
data() + idx);
426 storage_type storage_{};
429#ifdef TCB_SPAN_HAVE_DEDUCTION_GUIDES
432 template <
class T,
size_t N>
433 span(T (&)[N]) -> span<T, N>;
435 template <
class T,
size_t N>
436 span(std::array<T, N>&) -> span<T, N>;
438 template <
class T,
size_t N>
439 span(
const std::array<T, N>&) -> span<const T, N>;
441 template <
class Container>
442 span(Container&) -> span<typename Container::value_type>;
444 template <
class Container>
445 span(
const Container&) -> span<const typename Container::value_type>;
449 template <
typename ElementType, std::
size_t Extent>
454 template <
typename T, std::
size_t N>
459 template <
typename T, std::
size_t N>
464 template <
typename T, std::
size_t N>
469 template <
typename Container>
474 template <
typename Container>
479 template <
typename ElementType, std::
size_t Extent>
481 span<ElementType, Extent> s) noexcept {
482 return {reinterpret_cast<const
byte*>(s.data()), s.size_bytes()};
485 template <
class ElementType,
size_t Extent,
486 typename std::enable_if<!std::is_const<ElementType>::value,
int>::type = 0>
488 span<ElementType, Extent> s) noexcept {
489 return {reinterpret_cast<
byte*>(s.data()), s.size_bytes()};
492 template <std::
size_t N,
typename E, std::
size_t S>
501 template <
typename ElementType,
size_t Extent>
502 class tuple_size<
TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent> > :
public integral_constant<size_t, Extent> {};
504 template <
typename ElementType>
508 template <size_t I, typename ElementType, size_t Extent>
509 class tuple_element<I, TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent> > {
512 using type = ElementType;
518#ifdef TTG_TCB_SPAN_NAMESPACE_NAME_AT_TOP_OF_SPAN_H
520#undef TCB_SPAN_NAMESPACE_NAME
521#define TCB_SPAN_NAMESPACE_NAME TTG_TCB_SPAN_NAMESPACE_NAME_AT_TOP_OF_SPAN_H
522#undef TTG_TCB_SPAN_NAMESPACE_NAME_AT_TOP_OF_SPAN_H
constexpr span(Container &cont)
TCB_SPAN_CONSTEXPR11 span< element_type, Count > last() const
TCB_SPAN_ARRAY_CONSTEXPR span(const std::array< value_type, N > &arr) noexcept
constexpr iterator end() const noexcept
constexpr span(const Container &cont)
std::reverse_iterator< iterator > reverse_iterator
constexpr iterator begin() const noexcept
TCB_SPAN_ARRAY_CONSTEXPR span(std::array< value_type, N > &arr) noexcept
static constexpr size_type extent
const element_type * const_pointer
constexpr span(const span &other) noexcept=default
typename std::remove_cv< ElementType >::type value_type
TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin() const noexcept
const element_type & const_reference
std::ptrdiff_t difference_type
TCB_SPAN_CONSTEXPR11 span< element_type, dynamic_extent > first(size_type count) const
TCB_SPAN_CONSTEXPR11 reference back() const
constexpr size_type size() const noexcept
TCB_SPAN_CONSTEXPR11 reference front() const
constexpr size_type size_bytes() const noexcept
TCB_SPAN_CONSTEXPR11 reference operator[](size_type idx) const
TCB_SPAN_CONSTEXPR11 subspan_return_t< Offset, Count > subspan() const
constexpr span(element_type(&arr)[N]) noexcept
TCB_SPAN_CONSTEXPR11 span< element_type, dynamic_extent > subspan(size_type offset, size_type count=dynamic_extent) const
constexpr pointer data() const noexcept
TCB_SPAN_CONSTEXPR11 span< element_type, dynamic_extent > last(size_type count) const
TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rend() const noexcept
constexpr span(const span< OtherElementType, OtherExtent > &other) noexcept
TCB_SPAN_NODISCARD constexpr bool empty() const noexcept
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
typename std::remove_pointer< T >::type remove_pointer_t
constexpr auto data(C &c) -> decltype(c.data())
span< byte,((Extent==dynamic_extent) ? dynamic_extent :sizeof(ElementType) *Extent)> as_writable_bytes(span< ElementType, Extent > s) noexcept
constexpr span< ElementType, Extent > make_span(span< ElementType, Extent > s) noexcept
span< const byte,((Extent==dynamic_extent) ? dynamic_extent :sizeof(ElementType) *Extent)> as_bytes(span< ElementType, Extent > s) noexcept
constexpr auto get(span< E, S > s) -> decltype(s[N])
TCB_SPAN_INLINE_VAR constexpr std::size_t dynamic_extent
#define TCB_SPAN_EXPECT(cond)
#define TCB_SPAN_INLINE_VAR
#define TCB_SPAN_NODISCARD
#define TCB_SPAN_ARRAY_CONSTEXPR
#define TCB_SPAN_CONSTEXPR_ASSIGN
#define TCB_SPAN_CONSTEXPR11
static constexpr bool value
constexpr span_storage() noexcept=default
constexpr span_storage() noexcept=default
static constexpr std::size_t size