7#ifdef TCB_SPAN_NAMESPACE_NAME
9#define TTG_TCB_SPAN_NAMESPACE_NAME_AT_TOP_OF_SPAN_H TCB_SPAN_NAMESPACE_NAME
10#undef TCB_SPAN_NAMESPACE_NAME
15#define TCB_SPAN_NAMESPACE_NAME ttg
34#ifndef TCB_SPAN_NO_EXCEPTIONS
36#if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND))
37#define TCB_SPAN_NO_EXCEPTIONS
41#ifndef TCB_SPAN_NO_EXCEPTIONS
48#ifndef TCB_SPAN_NAMESPACE_NAME
49#define TCB_SPAN_NAMESPACE_NAME tcb
52#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
53#define TCB_SPAN_HAVE_CPP17
56#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
57#define TCB_SPAN_HAVE_CPP14
63#if !defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION) && !defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) && \
64 !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
65#if defined(NDEBUG) || !defined(TCB_SPAN_HAVE_CPP14)
66#define TCB_SPAN_NO_CONTRACT_CHECKING
68#define TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION
72#if defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION)
73 struct contract_violation_error : std::logic_error {
74 explicit contract_violation_error(
const char* msg) : std::logic_error(msg) {}
77 inline void contract_violation(
const char* msg) {
throw contract_violation_error(msg); }
79#elif defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION)
80 [[noreturn]]
inline void contract_violation(
const char* ) { std::terminate(); }
83#if !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
84#define TCB_SPAN_STRINGIFY(cond) #cond
85#define TCB_SPAN_EXPECT(cond) cond ? (void)0 : contract_violation("Expected " TCB_SPAN_STRINGIFY(cond))
87#define TCB_SPAN_EXPECT(cond)
90#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_inline_variables)
91#define TCB_SPAN_INLINE_VAR inline
93#define TCB_SPAN_INLINE_VAR
96#if defined(TCB_SPAN_HAVE_CPP14) || (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
97#define TCB_SPAN_HAVE_CPP14_CONSTEXPR
100#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR)
101#define TCB_SPAN_CONSTEXPR14 constexpr
103#define TCB_SPAN_CONSTEXPR14
106#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR) && (!defined(_MSC_VER) || _MSC_VER > 1900)
107#define TCB_SPAN_CONSTEXPR_ASSIGN constexpr
109#define TCB_SPAN_CONSTEXPR_ASSIGN
112#if defined(TCB_SPAN_NO_CONTRACT_CHECKING)
113#define TCB_SPAN_CONSTEXPR11 constexpr
115#define TCB_SPAN_CONSTEXPR11 TCB_SPAN_CONSTEXPR14
118#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_deduction_guides)
119#define TCB_SPAN_HAVE_DEDUCTION_GUIDES
122#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_byte)
123#define TCB_SPAN_HAVE_STD_BYTE
126#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_array_constexpr)
127#define TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC
130#if defined(TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC)
131#define TCB_SPAN_ARRAY_CONSTEXPR constexpr
133#define TCB_SPAN_ARRAY_CONSTEXPR
136#ifdef TCB_SPAN_HAVE_STD_BYTE
137 using byte = std::byte;
142#if defined(TCB_SPAN_HAVE_CPP17)
143#define TCB_SPAN_NODISCARD [[nodiscard]]
145#define TCB_SPAN_NODISCARD
150 template <
typename ElementType, std::
size_t Extent = dynamic_extent>
155 template <
typename E, std::
size_t S>
162 static constexpr std::size_t
size = S;
165 template <
typename E>
169 constexpr
span_storage(E* p_ptr,
std::
size_t p_size) noexcept : ptr(p_ptr), size(p_size) {}
172 std::size_t size = 0;
176#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_nonmember_container_access)
181 constexpr auto size(
const C& c) ->
decltype(c.size()) {
185 template <
class T, std::
size_t N>
186 constexpr std::size_t size(
const T (&)[N])
noexcept {
191 constexpr auto data(C& c) ->
decltype(c.data()) {
196 constexpr auto data(
const C& c) ->
decltype(c.data()) {
200 template <
class T, std::
size_t N>
201 constexpr T*
data(T (&array)[N])
noexcept {
206 constexpr const E*
data(std::initializer_list<E> il)
noexcept {
211#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_void_t)
214 template <
typename...>
218 template <
typename T>
219 using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
224 template <
typename T, std::
size_t S>
230 template <
typename T, std::
size_t N>
233 template <
typename,
typename =
void>
236 template <
typename T>
238 T,
void_t<decltype(detail::size(std::declval<T>())), decltype(detail::data(std::declval<T>()))> >
241 template <
typename C,
typename U = uncvref_t<C> >
247 template <
typename T>
250 template <
typename,
typename,
typename =
void>
253 template <
typename T,
typename E>
256 typename
std::enable_if<
257 !std::is_same<typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type, void>::value>::type>
258 : std::is_convertible<remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[], E (*)[]> {};
260 template <
typename,
typename =
size_t>
263 template <
typename T>
268 template <
typename ElementType, std::
size_t Extent>
270 static_assert(std::is_object<ElementType>::value,
271 "A span's ElementType must be an object type (not a "
272 "reference type or void)");
274 "A span's ElementType must be a complete type (not a forward "
276 static_assert(!std::is_abstract<ElementType>::value,
"A span's ElementType cannot be an abstract class type");
283 using value_type =
typename std::remove_cv<ElementType>::type;
296 template <std::
size_t E = Extent,
typename std::enable_if<(E == dynamic_extent || E <= 0),
int>::type = 0>
297 constexpr span() noexcept {}
299 TCB_SPAN_CONSTEXPR11 span(po
inter ptr,
size_type count) : storage_(ptr, count) {
300 TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent);
303 TCB_SPAN_CONSTEXPR11 span(po
inter first_elem, po
inter last_elem) : storage_(first_elem, last_elem - first_elem) {
304 TCB_SPAN_EXPECT(extent == dynamic_extent || last_elem - first_elem == static_cast<std::ptrdiff_t>(extent));
307 template <std::
size_t N, std::
size_t E = Extent,
308 typename std::enable_if<(E == dynamic_extent || N == E) && detail::is_container_element_type_compatible<
309 element_type (&)[N], ElementType>::value,
313 template <std::size_t N, std::size_t E = Extent,
314 typename std::enable_if<
320 template <std::size_t N, std::size_t E = Extent,
327 template <
typename Container, std::size_t E = Extent,
328 typename std::enable_if<E == dynamic_extent && detail::is_container<Container>::value &&
331 constexpr span(Container& cont) : storage_(detail::
data(cont), detail::
size(cont)) {}
334 typename Container, std::size_t E = Extent,
335 typename std::enable_if<E == dynamic_extent && detail::is_container<Container>::value &&
338 constexpr span(
const Container& cont) : storage_(detail::
data(cont), detail::
size(cont)) {}
340 constexpr span(
const span& other)
noexcept =
default;
342 template <
typename OtherElementType, std::size_t OtherExtent,
343 typename std::enable_if<(Extent == OtherExtent || Extent ==
dynamic_extent) &&
344 std::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value,
353 template <
std::
size_t Count>
356 return {
data(), Count};
359 template <std::
size_t Count>
362 return {
data() + (
size() - Count), Count};
365 template <std::
size_t Offset, std::
size_t Count = dynamic_extent>
370 template <std::
size_t Offset, std::
size_t Count = dynamic_extent>
378 return {
data(), count};
383 return {
data() + (
size() - count), count};
387 size_type count = dynamic_extent)
const {
402 return *(
data() + idx);
427 storage_type storage_{};
430#ifdef TCB_SPAN_HAVE_DEDUCTION_GUIDES
433 template <
class T,
size_t N>
434 span(T (&)[N]) -> span<T, N>;
436 template <
class T,
size_t N>
437 span(std::array<T, N>&) -> span<T, N>;
439 template <
class T,
size_t N>
440 span(
const std::array<T, N>&) -> span<const T, N>;
442 template <
class Container>
443 span(Container&) -> span<typename Container::value_type>;
445 template <
class Container>
446 span(
const Container&) -> span<const typename Container::value_type>;
450 template <
typename ElementType, std::
size_t Extent>
455 template <
typename T, std::
size_t N>
460 template <
typename T, std::
size_t N>
465 template <
typename T, std::
size_t N>
470 template <
typename Container>
475 template <
typename Container>
480 template <
typename ElementType, std::
size_t Extent>
482 span<ElementType, Extent> s) noexcept {
483 return {reinterpret_cast<const
byte*>(s.data()), s.size_bytes()};
486 template <
class ElementType,
size_t Extent,
487 typename std::enable_if<!std::is_const<ElementType>::value,
int>::type = 0>
489 span<ElementType, Extent> s) noexcept {
490 return {reinterpret_cast<
byte*>(s.data()), s.size_bytes()};
493 template <std::
size_t N,
typename E, std::
size_t S>
502 template <
typename ElementType,
size_t Extent>
503 class tuple_size<
TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent> > :
public integral_constant<size_t, Extent> {};
505 template <
typename ElementType>
509 template <size_t I, typename ElementType, size_t Extent>
510 class tuple_element<I, TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent> > {
513 using type = ElementType;
519#ifdef TTG_TCB_SPAN_NAMESPACE_NAME_AT_TOP_OF_SPAN_H
521#undef TCB_SPAN_NAMESPACE_NAME
522#define TCB_SPAN_NAMESPACE_NAME TTG_TCB_SPAN_NAMESPACE_NAME_AT_TOP_OF_SPAN_H
523#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