12#ifndef NONSTD_SPAN_HPP_INCLUDED
13#define NONSTD_SPAN_HPP_INCLUDED
15#define span_lite_MAJOR 0
16#define span_lite_MINOR 10
17#define span_lite_PATCH 0
19#define span_lite_VERSION \
20 span_STRINGIFY(span_lite_MAJOR) "." span_STRINGIFY( \
21 span_lite_MINOR) "." span_STRINGIFY(span_lite_PATCH)
23#define span_STRINGIFY(x) span_STRINGIFY_(x)
24#define span_STRINGIFY_(x) #x
28#define span_SPAN_DEFAULT 0
29#define span_SPAN_NONSTD 1
30#define span_SPAN_STD 2
35#if __has_include(<nonstd/span.tweak.hpp>)
36#include <nonstd/span.tweak.hpp>
38#define span_HAVE_TWEAK_HEADER 1
40#define span_HAVE_TWEAK_HEADER 0
46#define span_HAVE(feature) (span_HAVE_##feature)
48#ifndef span_CONFIG_SELECT_SPAN
49#define span_CONFIG_SELECT_SPAN \
50 (span_HAVE_STD_SPAN ? span_SPAN_STD : span_SPAN_NONSTD)
53#ifndef span_CONFIG_EXTENT_TYPE
54#define span_CONFIG_EXTENT_TYPE std::size_t
57#ifndef span_CONFIG_SIZE_TYPE
58#define span_CONFIG_SIZE_TYPE std::size_t
61#ifdef span_CONFIG_INDEX_TYPE
62# error `span_CONFIG_INDEX_TYPE` is deprecated since v0.7.0; it is replaced by `span_CONFIG_SIZE_TYPE`.
67#ifndef span_FEATURE_WITH_CONTAINER
68#ifdef span_FEATURE_WITH_CONTAINER_TO_STD
69#define span_FEATURE_WITH_CONTAINER \
70 span_IN_STD(span_FEATURE_WITH_CONTAINER_TO_STD)
72#define span_FEATURE_WITH_CONTAINER 0
73#define span_FEATURE_WITH_CONTAINER_TO_STD 0
77#ifndef span_FEATURE_CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE
78#define span_FEATURE_CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE 0
81#ifndef span_FEATURE_MEMBER_AT
82#define span_FEATURE_MEMBER_AT 0
85#ifndef span_FEATURE_MEMBER_BACK_FRONT
86#define span_FEATURE_MEMBER_BACK_FRONT 1
89#ifndef span_FEATURE_MEMBER_CALL_OPERATOR
90#define span_FEATURE_MEMBER_CALL_OPERATOR 0
93#ifndef span_FEATURE_MEMBER_SWAP
94#define span_FEATURE_MEMBER_SWAP 0
97#ifndef span_FEATURE_NON_MEMBER_FIRST_LAST_SUB
98#define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB 0
99#elif span_FEATURE_NON_MEMBER_FIRST_LAST_SUB
100#define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_SPAN 1
101#define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_CONTAINER 1
104#ifndef span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_SPAN
105#define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_SPAN 0
108#ifndef span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_CONTAINER
109#define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_CONTAINER 0
112#ifndef span_FEATURE_COMPARISON
113#define span_FEATURE_COMPARISON 0
116#ifndef span_FEATURE_SAME
117#define span_FEATURE_SAME 0
120#if span_FEATURE_SAME && !span_FEATURE_COMPARISON
121#error `span_FEATURE_SAME` requires `span_FEATURE_COMPARISON`
124#ifndef span_FEATURE_MAKE_SPAN
125#ifdef span_FEATURE_MAKE_SPAN_TO_STD
126#define span_FEATURE_MAKE_SPAN span_IN_STD(span_FEATURE_MAKE_SPAN_TO_STD)
128#define span_FEATURE_MAKE_SPAN 0
129#define span_FEATURE_MAKE_SPAN_TO_STD 0
133#ifndef span_FEATURE_BYTE_SPAN
134#define span_FEATURE_BYTE_SPAN 0
139#ifndef span_CONFIG_NO_EXCEPTIONS
143#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
144#define span_CONFIG_NO_EXCEPTIONS 0
146#define span_CONFIG_NO_EXCEPTIONS 1
147#undef span_CONFIG_CONTRACT_VIOLATION_THROWS
148#undef span_CONFIG_CONTRACT_VIOLATION_TERMINATES
149#define span_CONFIG_CONTRACT_VIOLATION_THROWS 0
150#define span_CONFIG_CONTRACT_VIOLATION_TERMINATES 1
156#if defined(span_CONFIG_CONTRACT_LEVEL_ON)
157#define span_CONFIG_CONTRACT_LEVEL_MASK 0x11
158#elif defined(span_CONFIG_CONTRACT_LEVEL_OFF)
159#define span_CONFIG_CONTRACT_LEVEL_MASK 0x00
160#elif defined(span_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY)
161#define span_CONFIG_CONTRACT_LEVEL_MASK 0x01
162#elif defined(span_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY)
163#define span_CONFIG_CONTRACT_LEVEL_MASK 0x10
165#define span_CONFIG_CONTRACT_LEVEL_MASK 0x11
168#if defined(span_CONFIG_CONTRACT_VIOLATION_THROWS)
169#define span_CONFIG_CONTRACT_VIOLATION_THROWS_V \
170 span_CONFIG_CONTRACT_VIOLATION_THROWS
172#define span_CONFIG_CONTRACT_VIOLATION_THROWS_V 0
175#if defined(span_CONFIG_CONTRACT_VIOLATION_THROWS) && \
176 span_CONFIG_CONTRACT_VIOLATION_THROWS && \
177 defined(span_CONFIG_CONTRACT_VIOLATION_TERMINATES) && \
178 span_CONFIG_CONTRACT_VIOLATION_TERMINATES
179# error Please define none or one of span_CONFIG_CONTRACT_VIOLATION_THROWS and span_CONFIG_CONTRACT_VIOLATION_TERMINATES to 1, but not both.
185#ifndef span_CPLUSPLUS
186#if defined(_MSVC_LANG) && !defined(__clang__)
187#define span_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
189#define span_CPLUSPLUS __cplusplus
193#define span_CPP98_OR_GREATER (span_CPLUSPLUS >= 199711L)
194#define span_CPP11_OR_GREATER (span_CPLUSPLUS >= 201103L)
195#define span_CPP14_OR_GREATER (span_CPLUSPLUS >= 201402L)
196#define span_CPP17_OR_GREATER (span_CPLUSPLUS >= 201703L)
197#define span_CPP20_OR_GREATER (span_CPLUSPLUS >= 202000L)
201#define span_CPLUSPLUS_V \
202 (span_CPLUSPLUS / 100 - (span_CPLUSPLUS > 200000 ? 2000 : 1994))
204#define span_IN_STD(v) (((v) == 98 ? 3 : (v)) >= span_CPLUSPLUS_V)
206#define span_CONFIG(feature) (span_CONFIG_##feature)
207#define span_FEATURE(feature) (span_FEATURE_##feature)
208#define span_FEATURE_TO_STD(feature) \
209 (span_IN_STD(span_FEATURE(feature##_TO_STD)))
213#if span_CPP20_OR_GREATER && defined(__has_include)
214#if __has_include(<span> )
215#define span_HAVE_STD_SPAN 1
217#define span_HAVE_STD_SPAN 0
220#define span_HAVE_STD_SPAN 0
223#define span_USES_STD_SPAN \
224 ((span_CONFIG_SELECT_SPAN == span_SPAN_STD) || \
225 ((span_CONFIG_SELECT_SPAN == span_SPAN_DEFAULT) && span_HAVE_STD_SPAN))
231#if span_USES_STD_SPAN
269#if defined(_MSC_VER) && !defined(__clang__)
270#define span_COMPILER_MSVC_VER (_MSC_VER)
271#define span_COMPILER_MSVC_VERSION \
272 (_MSC_VER / 10 - 10 * (5 + (_MSC_VER < 1900)))
274#define span_COMPILER_MSVC_VER 0
275#define span_COMPILER_MSVC_VERSION 0
278#define span_COMPILER_VERSION(major, minor, patch) \
279 (10 * (10 * (major) + (minor)) + (patch))
281#if defined(__clang__)
282#define span_COMPILER_CLANG_VERSION \
283 span_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
285#define span_COMPILER_CLANG_VERSION 0
288#if defined(__GNUC__) && !defined(__clang__)
289#define span_COMPILER_GNUC_VERSION \
290 span_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
292#define span_COMPILER_GNUC_VERSION 0
296#define span_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi))
300#if defined(__clang__)
301#pragma clang diagnostic push
302#pragma clang diagnostic ignored "-Wundef"
303#pragma clang diagnostic ignored "-Wmismatched-tags"
304#define span_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
306#elif defined __GNUC__
307#pragma GCC diagnostic push
308#pragma GCC diagnostic ignored "-Wundef"
309#define span_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
311#elif span_COMPILER_MSVC_VER >= 1900
312#define span_DISABLE_MSVC_WARNINGS(codes) \
313 __pragma(warning(push)) __pragma(warning(disable : codes))
314#define span_RESTORE_WARNINGS() __pragma(warning(pop))
327span_DISABLE_MSVC_WARNINGS(26439 26440 26472 26473 26481 26490)
330#define span_RESTORE_WARNINGS()
336#define span_HAS_CPP0X _HAS_CPP0X
338#define span_HAS_CPP0X 0
341#define span_CPP11_80 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1400)
342#define span_CPP11_90 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1500)
343#define span_CPP11_100 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1600)
344#define span_CPP11_110 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1700)
345#define span_CPP11_120 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1800)
346#define span_CPP11_140 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1900)
348#define span_CPP14_000 (span_CPP14_OR_GREATER)
349#define span_CPP14_120 (span_CPP14_OR_GREATER || span_COMPILER_MSVC_VER >= 1800)
350#define span_CPP14_140 (span_CPP14_OR_GREATER || span_COMPILER_MSVC_VER >= 1900)
352#define span_CPP17_000 (span_CPP17_OR_GREATER)
356#define span_HAVE_ALIAS_TEMPLATE span_CPP11_140
357#define span_HAVE_AUTO span_CPP11_100
358#define span_HAVE_CONSTEXPR_11 span_CPP11_140
359#define span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG span_CPP11_120
360#define span_HAVE_EXPLICIT_CONVERSION span_CPP11_140
361#define span_HAVE_INITIALIZER_LIST span_CPP11_120
362#define span_HAVE_IS_DEFAULT span_CPP11_140
363#define span_HAVE_IS_DELETE span_CPP11_140
364#define span_HAVE_NOEXCEPT span_CPP11_140
365#define span_HAVE_NULLPTR span_CPP11_100
366#define span_HAVE_STATIC_ASSERT span_CPP11_100
370#define span_HAVE_CONSTEXPR_14 span_CPP14_000
374#define span_HAVE_DEPRECATED span_CPP17_000
375#define span_HAVE_NODISCARD span_CPP17_000
376#define span_HAVE_NORETURN span_CPP17_000
380#if defined(__cpp_deduction_guides)
381#define span_HAVE_DEDUCTION_GUIDES 1
383#define span_HAVE_DEDUCTION_GUIDES \
384 (span_CPP17_OR_GREATER && !span_BETWEEN(span_COMPILER_MSVC_VER, 1, 1913))
389#define span_HAVE_ADDRESSOF span_CPP17_000
390#define span_HAVE_ARRAY span_CPP11_110
391#define span_HAVE_BYTE span_CPP17_000
392#define span_HAVE_CONDITIONAL span_CPP11_120
393#define span_HAVE_CONTAINER_DATA_METHOD \
394 (span_CPP11_140 || (span_COMPILER_MSVC_VER >= 1500 && span_HAS_CPP0X))
395#define span_HAVE_DATA span_CPP17_000
396#define span_HAVE_LONGLONG span_CPP11_80
397#define span_HAVE_REMOVE_CONST span_CPP11_110
398#define span_HAVE_SNPRINTF span_CPP11_140
399#define span_HAVE_STRUCT_BINDING span_CPP11_120
400#define span_HAVE_TYPE_TRAITS span_CPP11_90
404#ifdef NONSTD_BYTE_LITE_HPP
405#define span_HAVE_NONSTD_BYTE 1
407#define span_HAVE_NONSTD_BYTE 0
412#if span_HAVE_ADDRESSOF
413#define span_ADDRESSOF(x) std::addressof(x)
415#define span_ADDRESSOF(x) (&x)
418#if span_HAVE_CONSTEXPR_11
419#define span_constexpr constexpr
421#define span_constexpr
424#if span_HAVE_CONSTEXPR_14
425#define span_constexpr14 constexpr
427#define span_constexpr14
430#if span_HAVE_EXPLICIT_CONVERSION
431#define span_explicit explicit
436#if span_HAVE_IS_DELETE
437#define span_is_delete = delete
439#define span_is_delete
442#if span_HAVE_IS_DELETE
443#define span_is_delete_access public
445#define span_is_delete_access private
448#if span_HAVE_NOEXCEPT && !span_CONFIG_CONTRACT_VIOLATION_THROWS_V
449#define span_noexcept noexcept
455#define span_nullptr nullptr
457#define span_nullptr NULL
460#if span_HAVE_DEPRECATED
461#define span_deprecated(msg) [[deprecated(msg)]]
463#define span_deprecated(msg)
466#if span_HAVE_NODISCARD
467#define span_nodiscard [[nodiscard]]
469#define span_nodiscard
472#if span_HAVE_NORETURN
473#define span_noreturn [[noreturn]]
480#define span_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR \
481 span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
482#define span_HAVE_ITERATOR_CTOR span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
486#if span_HAVE(ADDRESSOF)
502#if span_HAVE(TYPE_TRAITS)
503#include <type_traits>
506#if !span_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR)
510#if span_FEATURE(MEMBER_AT) > 1
514#if !span_CONFIG(NO_EXCEPTIONS)
520#define span_ELIDE_CONTRACT_EXPECTS \
521 (0 == (span_CONFIG_CONTRACT_LEVEL_MASK & 0x01))
522#define span_ELIDE_CONTRACT_ENSURES \
523 (0 == (span_CONFIG_CONTRACT_LEVEL_MASK & 0x10))
525#if span_ELIDE_CONTRACT_EXPECTS
526#define span_constexpr_exp span_constexpr
527#define span_EXPECTS(cond)
529#define span_constexpr_exp span_constexpr14
530#define span_EXPECTS(cond) span_CONTRACT_CHECK("Precondition", cond)
533#if span_ELIDE_CONTRACT_ENSURES
534#define span_constexpr_ens span_constexpr
535#define span_ENSURES(cond)
537#define span_constexpr_ens span_constexpr14
538#define span_ENSURES(cond) span_CONTRACT_CHECK("Postcondition", cond)
541#define span_CONTRACT_CHECK(type, cond) \
542 cond ? static_cast<void>(0) \
543 : nonstd::span_lite::detail::report_contract_violation( \
544 span_LOCATION(__FILE__, __LINE__) ": " type " violation.")
547#define span_LOCATION(file, line) file ":" span_STRINGIFY(line)
549#define span_LOCATION(file, line) file "(" span_STRINGIFY(line) ")"
554#if span_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG)
556#define span_REQUIRES_0(VA) \
557 template <bool B = (VA), typename std::enable_if<B, int>::type = 0>
559#if span_BETWEEN(span_COMPILER_MSVC_VERSION, 1, 140)
562#define span_REQUIRES_T(VA) \
564 typename std::enable_if<(VA), \
565 nonstd::span_lite::detail::enabler>::type
567#define span_REQUIRES_T(VA) , typename std::enable_if<(VA), int>::type = 0
570#define span_REQUIRES_R(R, VA) typename std::enable_if<(VA), R>::type
572#define span_REQUIRES_A(VA) \
573 , typename std::enable_if<(VA), void*>::type = nullptr
577#define span_REQUIRES_0(VA)
578#define span_REQUIRES_T(VA)
579#define span_REQUIRES_R(R, VA) R
580#define span_REQUIRES_A(VA)
590using size_t = std::size_t;
594template <
class T, extent_t Extent = dynamic_extent>
610#if span_HAVE(REMOVE_CONST)
612using std::remove_const;
614using std::remove_volatile;
644#if span_HAVE(TYPE_TRAITS)
646using std::false_type;
647using std::integral_constant;
650using std::remove_reference;
655template <
class T, T v>
662template <
class T,
class U>
699#elif span_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR)
701template <
typename T, std::
size_t N>
702inline span_constexpr
auto size(
const T (&)[N]) span_noexcept ->
size_t {
707inline span_constexpr
auto size(C
const& cont) ->
decltype(cont.size()) {
711template <
typename T, std::
size_t N>
712inline span_constexpr
auto data(T (&arr)[N]) span_noexcept -> T* {
717inline span_constexpr
auto data(C& cont) ->
decltype(cont.data()) {
722inline span_constexpr
auto data(C
const& cont) ->
decltype(cont.data()) {
727inline span_constexpr
auto data(std::initializer_list<E> il) span_noexcept
736#elif span_HAVE(NONSTD_BYTE)
746#if span_HAVE(DEDUCTION_GUIDES)
748using iter_reference_t =
decltype(*std::declval<T &>());
760bool is_positive(T x) {
764#if span_HAVE(TYPE_TRAITS)
767struct is_span_oracle : std::false_type {};
769template <
class T, span_CONFIG_EXTENT_TYPE Extent>
770struct is_span_oracle<span<T, Extent> > : std::true_type {};
773struct is_span : is_span_oracle<typename std::remove_cv<Q>::type> {};
776struct is_std_array_oracle : std::false_type {};
780template <
class T, std::
size_t Extent>
781struct is_std_array_oracle<std::array<T, Extent> > : std::true_type {};
786struct is_std_array : is_std_array_oracle<typename std::remove_cv<Q>::type> {};
789struct is_array : std::false_type {};
793struct is_array<T[]> : std::true_type {};
795template <
class T, std::
size_t N>
797struct is_array<T[N]> : std::true_type {};
799#if span_CPP11_140 && !span_BETWEEN(span_COMPILER_GNUC_VERSION, 1, 500)
801template <
class,
class =
void>
802struct has_size_and_data : std::false_type {};
805struct has_size_and_data<
806 C, std17::void_t<decltype(std17::size(std::declval<C>())),
807 decltype(std17::data(std::declval<C>()))> >
810template <
class,
class,
class =
void>
811struct is_compatible_element : std::false_type {};
813template <
class C,
class E>
814struct is_compatible_element<
815 C, E, std17::void_t<decltype(std17::data(std::declval<C>()))> >
816 : std::is_convertible<typename std::remove_pointer<decltype(
817 std17::data(std::declval<C &>()))>::type (*)[],
822 : std17::bool_constant<!is_span<C>::value && !is_array<C>::value &&
823 !is_std_array<C>::value &&
824 has_size_and_data<C>::value> {};
826template <
class C,
class E>
827struct is_compatible_container
828 : std17::bool_constant<is_container<C>::value &&
829 is_compatible_element<C, E>::value> {};
835 class E span_REQUIRES_T((
836 !is_span<C>::value && !is_array<C>::value && !is_std_array<C>::value &&
837 (std::is_convertible<
typename std::remove_pointer<
decltype(
838 std17::data(std::declval<C &>()))>::type (*)[],
842 class =
decltype(std17::size(std::declval<C>())),
843 class =
decltype(std17::data(std::declval<C>()))>
844struct is_compatible_container : std::true_type {};
850#if !span_CONFIG(NO_EXCEPTIONS)
851#if span_FEATURE(MEMBER_AT) > 1
855#if defined(__clang__)
856#pragma clang diagnostic ignored "-Wlong-long"
857#elif defined __GNUC__
858#pragma GCC diagnostic ignored "-Wformat=ll"
859#pragma GCC diagnostic ignored "-Wlong-long"
862inline void throw_out_of_range(
size_t idx,
size_t size) {
863 const char fmt[] =
"span::at(): index '%lli' is out of range [0..%lli)";
864 char buffer[2 * 20 +
sizeof fmt];
865 sprintf(buffer, fmt,
static_cast<long long>(idx),
866 static_cast<long long>(
size));
868 throw std::out_of_range(buffer);
873inline void throw_out_of_range(
size_t ,
size_t ) {
874 throw std::out_of_range(
"span::at(): index outside span");
879#if span_CONFIG(CONTRACT_VIOLATION_THROWS_V)
881struct contract_violation : std::logic_error {
882 explicit contract_violation(
char const *
const message)
883 : std::logic_error(message) {}
886inline void report_contract_violation(
char const *msg) {
887 throw contract_violation(msg);
892span_noreturn
inline void report_contract_violation(
char const* )
903#define span_sizeof(T) static_cast<extent_t>(sizeof(T))
907 return static_cast<size_t>(
size);
943 span() span_noexcept :
data_(span_nullptr),
949#if span_HAVE(ITERATOR_CTOR)
952 span_constexpr_exp
span(std::nullptr_t, size_type count)
954 span_EXPECTS(
data_ == span_nullptr && count == 0);
957 template <
typename It span_REQUIRES_T(
958 (std::is_convertible<
decltype(*std::declval<It &>()),
960 span_constexpr_exp
span(It
first, size_type count)
962 span_EXPECTS((
data_ == span_nullptr && count == 0) ||
963 (
data_ != span_nullptr && detail::is_positive(count)));
968 span_EXPECTS((ptr == span_nullptr && count == 0) ||
969 (ptr != span_nullptr && detail::is_positive(count)));
973#if span_HAVE(ITERATOR_CTOR)
974 template <
typename It,
975 typename End span_REQUIRES_T(
976 (std::is_convertible<
decltype(*std::declval<It &>()),
978 !std::is_convertible<End, std::size_t>::value))>
990 template <std::size_t N span_REQUIRES_T(
995 :
data_(span_ADDRESSOF(arr[0])),
1000 template <std::size_t N span_REQUIRES_T(
1002 Extent ==
static_cast<extent_t>(N)) &&
1005#if span_FEATURE(CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE)
1006 span_constexpr
span(std::array<element_type, N> &arr) span_noexcept
1008 span_constexpr
span(std::array<value_type, N> &arr) span_noexcept
1010 :
data_(arr.data()),
1014 template <std::size_t N
1015#if span_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG)
1018 Extent ==
static_cast<extent_t>(N)) &&
1023 span_constexpr
span(std::array<value_type, N>
const &arr)
1024 span_noexcept :
data_(arr.data()),
1030#if span_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR)
1031 template <
class Container span_REQUIRES_T(
1032 (detail::is_compatible_container<Container, element_type>::value))>
1033 span_constexpr
span(Container &cont)
1036 template <
class Container span_REQUIRES_T(
1037 (std::is_const<element_type>::value &&
1038 detail::is_compatible_container<Container, element_type>::value))>
1039 span_constexpr
span(Container
const &cont)
1044#if span_FEATURE(WITH_CONTAINER)
1046 template <
class Container>
1047 span_constexpr
span(with_container_t, Container &cont)
1048 :
data_(cont.
size() == 0 ? span_nullptr : span_ADDRESSOF(cont[0])),
1051 template <
class Container>
1052 span_constexpr
span(with_container_t, Container
const &cont)
1054 : const_cast<
pointer>(span_ADDRESSOF(cont[0]))),
1058#if span_HAVE(IS_DEFAULT)
1059 span_constexpr
span(
span const &other) span_noexcept =
default;
1061 ~span() span_noexcept = default;
1063 span_constexpr14
span &operator=(
span const &other) span_noexcept = default;
1066 size_(other.size_) {}
1071 data_ = other.data_;
1072 size_ = other.size_;
1078 template <
class OtherElementType,
1081 std::is_convertible<OtherElementType (*)[],
1086 size_(other.size()) {
1088 other.size() ==
to_size(OtherExtent));
1093 template <extent_type Count>
1095 span_EXPECTS(detail::is_positive(Count) && Count <=
size());
1100 template <extent_type Count>
1102 span_EXPECTS(detail::is_positive(Count) && Count <=
size());
1107#if span_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG)
1108 template <
size_type Offset, extent_type Count = dynamic_extent>
1113 span_EXPECTS((detail::is_positive(Offset) && Offset <=
size()) &&
1115 (detail::is_positive(Count) && Count + Offset <=
size())));
1127 span_EXPECTS(detail::is_positive(count) && count <=
size());
1135 span_EXPECTS(detail::is_positive(count) && count <=
size());
1144 span_EXPECTS(((detail::is_positive(offset) && offset <=
size())) &&
1146 (detail::is_positive(count) && offset + count <=
size())));
1160 span_constexpr std::ptrdiff_t
ssize() const span_noexcept {
1161 return static_cast<std::ptrdiff_t
>(
size_);
1170 span_nodiscard span_constexpr
bool empty() const span_noexcept {
1178 span_EXPECTS(detail::is_positive(idx) && idx <
size());
1180 return *(
data() + idx);
1183#if span_FEATURE(MEMBER_CALL_OPERATOR)
1184 span_deprecated(
"replace operator() with operator[]")
1187 operator()(size_type idx)
const {
1188 span_EXPECTS(detail::is_positive(idx) && idx <
size());
1190 return *(
data() + idx);
1194#if span_FEATURE(MEMBER_AT)
1195 span_constexpr14
reference at(size_type idx)
const {
1196#if span_CONFIG(NO_EXCEPTIONS)
1199 if (!detail::is_positive(idx) ||
size() <= idx) {
1200 detail::throw_out_of_range(idx,
size());
1202 return *(
data() + idx);
1210#if span_FEATURE(MEMBER_BACK_FRONT)
1214 span_EXPECTS(!
empty());
1221 span_EXPECTS(!
empty());
1230#if span_FEATURE(MEMBER_SWAP)
1232 span_constexpr14
void swap(
span &other) span_noexcept {
1234 swap(
data_, other.data_);
1235 swap(
size_, other.size_);
1243#if span_CPP11_OR_GREATER
1252#if span_CPP11_OR_GREATER
1261#if span_CPP11_OR_GREATER
1270#if span_CPP11_OR_GREATER
1300#if span_HAVE(ITERATOR_CTOR)
1301 static inline span_constexpr
pointer to_address(std::nullptr_t)
1306 template <
typename U>
1307 static inline span_constexpr U *to_address(U *p) span_noexcept {
1311 template <
typename Ptr span_REQUIRES_T((!std::is_po
inter<Ptr>::value))>
1312 static inline span_constexpr
pointer to_address(Ptr
const &it) span_noexcept {
1313 return to_address(it.operator->());
1325#if span_HAVE(DEDUCTION_GUIDES)
1327template <
class T,
size_t N>
1330template <
class T,
size_t N>
1333template <
class T,
size_t N>
1336#if span_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR)
1338template <
class Container>
1341template <
class Container>
1348template <
class It,
class EndOrSize>
1349span(It, EndOrSize) ->
span<
typename std11::remove_reference<
1350 typename std20::iter_reference_t<It> >::type>;
1356#if span_FEATURE(COMPARISON)
1357#if span_FEATURE(SAME)
1359template <
class T1, extent_t E1,
class T2, extent_t E2>
1363 static_cast<void const *
>(l.data()) == r.data();
1368template <
class T1, extent_t E1,
class T2, extent_t E2>
1369inline span_constexpr
bool operator==(
span<T1, E1> const &l,
1372#if span_FEATURE(SAME)
1378template <
class T1, extent_t E1,
class T2, extent_t E2>
1379inline span_constexpr
bool operator<(span<T1, E1>
const &l,
1380 span<T2, E2>
const &r) {
1381 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
1384template <
class T1, extent_t E1,
class T2, extent_t E2>
1385inline span_constexpr
bool operator!=(span<T1, E1>
const &l,
1386 span<T2, E2>
const &r) {
1390template <
class T1, extent_t E1,
class T2, extent_t E2>
1391inline span_constexpr
bool operator<=(span<T1, E1>
const &l,
1392 span<T2, E2>
const &r) {
1396template <
class T1, extent_t E1,
class T2, extent_t E2>
1397inline span_constexpr
bool operator>(span<T1, E1>
const &l,
1398 span<T2, E2>
const &r) {
1402template <
class T1, extent_t E1,
class T2, extent_t E2>
1403inline span_constexpr
bool operator>=(span<T1, E1>
const &l,
1404 span<T2, E2>
const &r) {
1412#if span_HAVE(BYTE) || span_HAVE(NONSTD_BYTE)
1417template <
typename T, extent_t Extent>
1419#if span_CPP11_OR_GREATER
1420 enum ET :
extent_t { value = span_sizeof(T) * Extent };
1422 enum ET { value = span_sizeof(T) * Extent };
1426template <
typename T>
1428#if span_CPP11_OR_GREATER
1435template <
class T, extent_t Extent>
1436inline span_constexpr span<const std17::byte, BytesExtent<T, Extent>::value>
1437as_bytes(span<T, Extent> spn) span_noexcept {
1439 return {
reinterpret_cast< std17::byte
const *
>( spn.data() ), spn.size_bytes() };
1441 return span<const std17::byte, BytesExtent<T, Extent>::value>(
1442 reinterpret_cast<std17::byte
const *
>(spn.data()),
1447template <
class T, extent_t Extent>
1448inline span_constexpr span<std17::byte, BytesExtent<T, Extent>::value>
1449as_writable_bytes(span<T, Extent> spn) span_noexcept {
1451 return {
reinterpret_cast< std17::byte *
>( spn.data() ), spn.size_bytes() };
1453 return span<std17::byte, BytesExtent<T, Extent>::value>(
1454 reinterpret_cast<std17::byte *
>(spn.data()), spn.size_bytes());
1462template <
class T,
extent_t Extent >
1464 return static_cast<std::size_t
>(spn.
size());
1467template <
class T,
extent_t Extent >
1469 return static_cast<std::ptrdiff_t
>(spn.
size());
1481using span_lite::span;
1485#if span_FEATURE(COMPARISON)
1486#if span_FEATURE(SAME)
1487using span_lite::same;
1490using span_lite::operator==;
1491using span_lite::operator!=;
1492using span_lite::operator<;
1493using span_lite::operator<=;
1494using span_lite::operator>;
1495using span_lite::operator>=;
1499using span_lite::as_bytes;
1500using span_lite::as_writable_bytes;
1512#if span_FEATURE(MAKE_SPAN) || span_FEATURE(NON_MEMBER_FIRST_LAST_SUB_SPAN) || \
1513 span_FEATURE(NON_MEMBER_FIRST_LAST_SUB_CONTAINER)
1515#if span_USES_STD_SPAN
1516#define span_constexpr constexpr
1517#define span_noexcept noexcept
1518#define span_nullptr nullptr
1519#ifndef span_CONFIG_EXTENT_TYPE
1520#define span_CONFIG_EXTENT_TYPE std::size_t
1522using extent_t = span_CONFIG_EXTENT_TYPE;
1526namespace span_lite {
1529inline span_constexpr span<T> make_span(T* ptr,
size_t count) span_noexcept {
1530 return span<T>(ptr, count);
1534inline span_constexpr span<T> make_span(T* first, T* last) span_noexcept {
1535 return span<T>(first, last);
1538template <
class T, std::
size_t N>
1539inline span_constexpr span<T, static_cast<extent_t>(N)> make_span(T (&arr)[N])
1541 return span<T, static_cast<extent_t>(N)>(&arr[0], N);
1544#if span_USES_STD_SPAN || span_HAVE(ARRAY)
1546template <
class T, std::
size_t N>
1547inline span_constexpr span<T, static_cast<extent_t>(N)> make_span(
1548 std::array<T, N>& arr) span_noexcept {
1549 return span<T, static_cast<extent_t>(N)>(arr);
1552template <
class T, std::
size_t N>
1553inline span_constexpr span<const T, static_cast<extent_t>(N)> make_span(
1554 std::array<T, N>
const& arr) span_noexcept {
1555 return span<const T, static_cast<extent_t>(N)>(arr);
1560#if span_USES_STD_SPAN
1562template <
class Container,
1563 class EP =
decltype(std::data(std::declval<Container&>()))>
1564inline span_constexpr
auto make_span(Container& cont) span_noexcept
1565 -> span<typename std::remove_pointer<EP>::type> {
1566 return span<typename std::remove_pointer<EP>::type>(cont);
1569template <
class Container,
1570 class EP =
decltype(std::data(std::declval<Container&>()))>
1571inline span_constexpr
auto make_span(Container
const& cont) span_noexcept
1572 -> span<const typename std::remove_pointer<EP>::type> {
1573 return span<const typename std::remove_pointer<EP>::type>(cont);
1576#elif span_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR) && span_HAVE(AUTO)
1578template <
class Container,
1579 class EP =
decltype(std17::data(std::declval<Container&>()))>
1580inline span_constexpr
auto make_span(Container& cont) span_noexcept
1581 -> span<typename std::remove_pointer<EP>::type> {
1582 return span<typename std::remove_pointer<EP>::type>(cont);
1585template <
class Container,
1586 class EP =
decltype(std17::data(std::declval<Container&>()))>
1587inline span_constexpr
auto make_span(Container
const& cont) span_noexcept
1588 -> span<const typename std::remove_pointer<EP>::type> {
1589 return span<const typename std::remove_pointer<EP>::type>(cont);
1595inline span_constexpr span<T> make_span(span<T> spn) span_noexcept {
1599template <
class T,
class Allocator>
1600inline span_constexpr span<T> make_span(std::vector<T, Allocator>& cont)
1605template <
class T,
class Allocator>
1606inline span_constexpr span<const T> make_span(
1607 std::vector<T, Allocator>
const& cont) span_noexcept {
1613#if !span_USES_STD_SPAN && span_FEATURE(WITH_CONTAINER)
1615template <
class Container>
1616inline span_constexpr span<typename Container::value_type> make_span(
1617 with_container_t, Container& cont) span_noexcept {
1618 return span<typename Container::value_type>(
with_container, cont);
1621template <
class Container>
1622inline span_constexpr span<const typename Container::value_type> make_span(
1623 with_container_t, Container
const& cont) span_noexcept {
1624 return span<const typename Container::value_type>(
with_container, cont);
1632#if span_FEATURE(NON_MEMBER_FIRST_LAST_SUB_SPAN)
1634template <extent_t Count,
class T, extent_t Extent>
1635span_constexpr span<T, Count> first(span<T, Extent> spn) {
1636 return spn.template first<Count>();
1639template <
class T, extent_t Extent>
1640span_constexpr span<T> first(span<T, Extent> spn,
size_t count) {
1641 return spn.first(count);
1644template <extent_t Count,
class T, extent_t Extent>
1645span_constexpr span<T, Count> last(span<T, Extent> spn) {
1646 return spn.template last<Count>();
1649template <
class T, extent_t Extent>
1650span_constexpr span<T> last(span<T, Extent> spn,
size_t count) {
1651 return spn.last(count);
1654template <
size_t Offset, extent_t Count,
class T, extent_t Extent>
1655span_constexpr span<T, Count> subspan(span<T, Extent> spn) {
1656 return spn.template subspan<Offset, Count>();
1659template <
class T, extent_t Extent>
1660span_constexpr span<T> subspan(span<T, Extent> spn,
size_t offset,
1662 return spn.subspan(offset, count);
1667#if span_FEATURE(NON_MEMBER_FIRST_LAST_SUB_CONTAINER) && span_CPP11_120
1669template <extent_t Count,
class T>
1670span_constexpr
auto first(T& t)
1671 ->
decltype(make_span(t).template first<Count>()) {
1672 return make_span(t).template first<Count>();
1676span_constexpr
auto first(T& t,
size_t count)
1677 ->
decltype(make_span(t).first(count)) {
1678 return make_span(t).first(count);
1681template <extent_t Count,
class T>
1682span_constexpr
auto last(T& t)
1683 ->
decltype(make_span(t).template last<Count>()) {
1684 return make_span(t).template last<Count>();
1688span_constexpr
auto last(T& t,
extent_t count)
1689 ->
decltype(make_span(t).last(count)) {
1690 return make_span(t).last(count);
1693template <
size_t Offset, extent_t Count = dynamic_extent,
class T>
1694span_constexpr
auto subspan(T& t)
1695 ->
decltype(make_span(t).template subspan<Offset, Count>()) {
1696 return make_span(t).template subspan<Offset, Count>();
1700span_constexpr
auto subspan(T& t,
size_t offset,
1702 ->
decltype(make_span(t).subspan(offset, count)) {
1703 return make_span(t).subspan(offset, count);
1714using span_lite::make_span;
1716#if span_FEATURE(NON_MEMBER_FIRST_LAST_SUB_SPAN) || \
1717 (span_FEATURE(NON_MEMBER_FIRST_LAST_SUB_CONTAINER) && span_CPP11_120)
1719using span_lite::first;
1720using span_lite::last;
1721using span_lite::subspan;
1729#if span_CPP11_OR_GREATER && span_FEATURE(BYTE_SPAN) && \
1730 (span_HAVE(BYTE) || span_HAVE(NONSTD_BYTE))
1733namespace span_lite {
1736inline span_constexpr
auto byte_span(T& t) span_noexcept
1737 -> span<std17::byte, span_sizeof(T)> {
1738 return span<std17::byte, span_sizeof(t)>(
reinterpret_cast<std17::byte*
>(&t),
1743inline span_constexpr
auto byte_span(T
const& t) span_noexcept
1744 -> span<
const std17::byte, span_sizeof(T)> {
1745 return span<const std17::byte, span_sizeof(t)>(
1746 reinterpret_cast<std17::byte const*
>(&t), span_sizeof(T));
1755using span_lite::byte_span;
1760#if span_HAVE(STRUCT_BINDING)
1762#if span_CPP14_OR_GREATER
1764#elif span_CPP11_OR_GREATER
1767template <std::
size_t I,
typename T>
1768using tuple_element_t =
typename tuple_element<I, T>::type;
1772template <
typename T>
1775template <std::
size_t I,
typename T>
1787template <
typename ElementType, nonstd::span_lite::extent_t Extent>
1788class tuple_size<
nonstd::span<ElementType, Extent> >
1789 :
public integral_constant<size_t, static_cast<size_t>(Extent)> {};
1793template <
typename ElementType>
1794class tuple_size<
nonstd::span<ElementType, nonstd::dynamic_extent> >;
1798template <size_t I, typename ElementType, nonstd::span_lite::extent_t Extent>
1799class tuple_element<I, nonstd::span<ElementType, Extent> > {
1801#if span_HAVE(STATIC_ASSERT)
1802 static_assert(Extent != nonstd::dynamic_extent && I < Extent,
1803 "tuple_element<I,span>: dynamic extent or index out of range");
1805 using type = ElementType;
1810template <
size_t I,
typename ElementType, nonstd::span_lite::extent_t Extent>
1813#if span_HAVE(STATIC_ASSERT)
1814 static_assert(Extent != nonstd::dynamic_extent && I < Extent,
1815 "get<>(span): dynamic extent or index out of range");
1820template <
size_t I,
typename ElementType, nonstd::span_lite::extent_t Extent>
1821span_constexpr ElementType
const& get(
1823#if span_HAVE(STATIC_ASSERT)
1824 static_assert(Extent != nonstd::dynamic_extent && I < Extent,
1825 "get<>(span): dynamic extent or index out of range");
1834#if !span_USES_STD_SPAN
1835span_RESTORE_WARNINGS()
span_constexpr_exp span< element_type, Count > subspan() const
span_constexpr std::ptrdiff_t ssize() const span_noexcept
span_constexpr size_type size_bytes() const span_noexcept
std::reverse_iterator< const_iterator > const_reverse_iterator
span_constexpr const_iterator cbegin() const span_noexcept
span_constexpr reverse_iterator rend() const span_noexcept
span_REQUIRES_0((Extent==0)||(Extent==dynamic_extent)) span_constexpr span() span_noexcept
span_constexpr_exp span(pointer ptr, size_type count)
span_constexpr_exp span< element_type, dynamic_extent > last(size_type count) const
span_nodiscard span_constexpr bool empty() const span_noexcept
span_constexpr_exp span< element_type, Count > first() const
span_constexpr reverse_iterator rbegin() const span_noexcept
span_constexpr_exp span(pointer first, pointer last)
std::reverse_iterator< iterator > reverse_iterator
span_constexpr const_iterator cend() const span_noexcept
span_constexpr size_type size() const span_noexcept
span_constexpr_exp span< element_type, Count > last() const
span_constexpr iterator begin() const span_noexcept
span_constexpr iterator end() const span_noexcept
span_constexpr const_reverse_iterator crend() const span_noexcept
span_constexpr_exp reference operator[](size_type idx) const
span_constexpr span(element_type(&arr)[N]) span_noexcept
span_constexpr pointer data() const span_noexcept
span_constexpr span(span const &other) span_noexcept
span_constexpr_exp span< element_type, dynamic_extent > subspan(size_type offset, size_type count=static_cast< size_type >(dynamic_extent)) const
span_constexpr const_reverse_iterator crbegin() const span_noexcept
span_constexpr_exp reference front() const span_noexcept
span_constexpr_exp span(span< OtherElementType, OtherExtent > const &other) span_noexcept
typename std11::remove_cv< T >::type value_type
span_constexpr_exp span< element_type, dynamic_extent > first(size_type count) const
T const & const_reference
std::ptrdiff_t difference_type
span_constexpr14 span & operator=(span const &other) span_noexcept
span_constexpr_exp reference back() const span_noexcept
const_pointer const_iterator
integral_constant< bool, false > false_type
integral_constant< bool, true > true_type
span_CONFIG_EXTENT_TYPE extent_t
const span_constexpr with_container_t with_container
span_constexpr const extent_t dynamic_extent
span_constexpr std::size_t size(span< T, Extent > const &spn)
span_constexpr std::ptrdiff_t ssize(span< T, Extent > const &spn)
span_constexpr size_t to_size(T size)
std11::remove_volatile< typenamestd11::remove_const< T >::type >::type type
span_constexpr with_container_t() span_noexcept