Normalize C/C++ include guards
[babeltrace.git] / src / cpp-common / vendor / span-lite / span.hpp
CommitLineData
30586bf0
PP
1//
2// span for C++98 and later.
3// Based on http://wg21.link/p0122r7
4// For more information see https://github.com/martinmoene/span-lite
5//
6// Copyright 2018-2021 Martin Moene
7//
8// Distributed under the Boost Software License, Version 1.0.
9// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10
11#ifndef NONSTD_SPAN_HPP_INCLUDED
12#define NONSTD_SPAN_HPP_INCLUDED
13
14#define span_lite_MAJOR 0
15#define span_lite_MINOR 11
16#define span_lite_PATCH 0
17
18#define span_lite_VERSION span_STRINGIFY(span_lite_MAJOR) "." span_STRINGIFY(span_lite_MINOR) "." span_STRINGIFY(span_lite_PATCH)
19
20#define span_STRINGIFY( x ) span_STRINGIFY_( x )
21#define span_STRINGIFY_( x ) #x
22
23// span configuration:
24
25#define span_SPAN_DEFAULT 0
26#define span_SPAN_NONSTD 1
27#define span_SPAN_STD 2
28
29// tweak header support:
30
31#ifdef __has_include
32# if __has_include(<nonstd/span.tweak.hpp>)
33# include <nonstd/span.tweak.hpp>
34# endif
35#define span_HAVE_TWEAK_HEADER 1
36#else
37#define span_HAVE_TWEAK_HEADER 0
38//# pragma message("span.hpp: Note: Tweak header not supported.")
39#endif
40
41// span selection and configuration:
42
43#define span_HAVE( feature ) ( span_HAVE_##feature )
44
45#ifndef span_CONFIG_SELECT_SPAN
46# define span_CONFIG_SELECT_SPAN ( span_HAVE_STD_SPAN ? span_SPAN_STD : span_SPAN_NONSTD )
47#endif
48
49#ifndef span_CONFIG_EXTENT_TYPE
50# define span_CONFIG_EXTENT_TYPE std::size_t
51#endif
52
53#ifndef span_CONFIG_SIZE_TYPE
54# define span_CONFIG_SIZE_TYPE std::size_t
55#endif
56
57#ifdef span_CONFIG_INDEX_TYPE
58# error `span_CONFIG_INDEX_TYPE` is deprecated since v0.7.0; it is replaced by `span_CONFIG_SIZE_TYPE`.
59#endif
60
61// span configuration (features):
62
63#ifndef span_FEATURE_WITH_INITIALIZER_LIST_P2447
64# define span_FEATURE_WITH_INITIALIZER_LIST_P2447 0
65#endif
66
67#ifndef span_FEATURE_WITH_CONTAINER
68#ifdef span_FEATURE_WITH_CONTAINER_TO_STD
69# define span_FEATURE_WITH_CONTAINER span_IN_STD( span_FEATURE_WITH_CONTAINER_TO_STD )
70#else
71# define span_FEATURE_WITH_CONTAINER 0
72# define span_FEATURE_WITH_CONTAINER_TO_STD 0
73#endif
74#endif
75
76#ifndef span_FEATURE_CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE
77# define span_FEATURE_CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE 0
78#endif
79
80#ifndef span_FEATURE_MEMBER_AT
81# define span_FEATURE_MEMBER_AT 0
82#endif
83
84#ifndef span_FEATURE_MEMBER_BACK_FRONT
85# define span_FEATURE_MEMBER_BACK_FRONT 1
86#endif
87
88#ifndef span_FEATURE_MEMBER_CALL_OPERATOR
89# define span_FEATURE_MEMBER_CALL_OPERATOR 0
90#endif
91
92#ifndef span_FEATURE_MEMBER_SWAP
93# define span_FEATURE_MEMBER_SWAP 0
94#endif
95
96#ifndef span_FEATURE_NON_MEMBER_FIRST_LAST_SUB
97# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB 0
98#elif span_FEATURE_NON_MEMBER_FIRST_LAST_SUB
99# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_SPAN 1
100# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_CONTAINER 1
101#endif
102
103#ifndef span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_SPAN
104# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_SPAN 0
105#endif
106
107#ifndef span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_CONTAINER
108# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_CONTAINER 0
109#endif
110
111#ifndef span_FEATURE_COMPARISON
112# define span_FEATURE_COMPARISON 0 // Note: C++20 does not provide comparison
113#endif
114
115#ifndef span_FEATURE_SAME
116# define span_FEATURE_SAME 0
117#endif
118
119#if span_FEATURE_SAME && !span_FEATURE_COMPARISON
120# error `span_FEATURE_SAME` requires `span_FEATURE_COMPARISON`
121#endif
122
123#ifndef span_FEATURE_MAKE_SPAN
124#ifdef span_FEATURE_MAKE_SPAN_TO_STD
125# define span_FEATURE_MAKE_SPAN span_IN_STD( span_FEATURE_MAKE_SPAN_TO_STD )
126#else
127# define span_FEATURE_MAKE_SPAN 0
128# define span_FEATURE_MAKE_SPAN_TO_STD 0
129#endif
130#endif
131
132#ifndef span_FEATURE_BYTE_SPAN
133# define span_FEATURE_BYTE_SPAN 0
134#endif
135
136// Control presence of exception handling (try and auto discover):
137
138#ifndef span_CONFIG_NO_EXCEPTIONS
139# if defined(_MSC_VER)
140# include <cstddef> // for _HAS_EXCEPTIONS
141# endif
142# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
143# define span_CONFIG_NO_EXCEPTIONS 0
144# else
145# define span_CONFIG_NO_EXCEPTIONS 1
146# undef span_CONFIG_CONTRACT_VIOLATION_THROWS
147# undef span_CONFIG_CONTRACT_VIOLATION_TERMINATES
148# define span_CONFIG_CONTRACT_VIOLATION_THROWS 0
149# define span_CONFIG_CONTRACT_VIOLATION_TERMINATES 1
150# endif
151#endif
152
153// Control pre- and postcondition violation behaviour:
154
155#if defined( span_CONFIG_CONTRACT_LEVEL_ON )
156# define span_CONFIG_CONTRACT_LEVEL_MASK 0x11
157#elif defined( span_CONFIG_CONTRACT_LEVEL_OFF )
158# define span_CONFIG_CONTRACT_LEVEL_MASK 0x00
159#elif defined( span_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY )
160# define span_CONFIG_CONTRACT_LEVEL_MASK 0x01
161#elif defined( span_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY )
162# define span_CONFIG_CONTRACT_LEVEL_MASK 0x10
163#else
164# define span_CONFIG_CONTRACT_LEVEL_MASK 0x11
165#endif
166
167#if defined( span_CONFIG_CONTRACT_VIOLATION_THROWS )
168# define span_CONFIG_CONTRACT_VIOLATION_THROWS_V span_CONFIG_CONTRACT_VIOLATION_THROWS
169#else
170# define span_CONFIG_CONTRACT_VIOLATION_THROWS_V 0
171#endif
172
173#if defined( span_CONFIG_CONTRACT_VIOLATION_THROWS ) && span_CONFIG_CONTRACT_VIOLATION_THROWS && \
174 defined( span_CONFIG_CONTRACT_VIOLATION_TERMINATES ) && span_CONFIG_CONTRACT_VIOLATION_TERMINATES
175# error Please define none or one of span_CONFIG_CONTRACT_VIOLATION_THROWS and span_CONFIG_CONTRACT_VIOLATION_TERMINATES to 1, but not both.
176#endif
177
178// C++ language version detection (C++23 is speculative):
179// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
180
181#ifndef span_CPLUSPLUS
182# if defined(_MSVC_LANG ) && !defined(__clang__)
183# define span_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
184# else
185# define span_CPLUSPLUS __cplusplus
186# endif
187#endif
188
189#define span_CPP98_OR_GREATER ( span_CPLUSPLUS >= 199711L )
190#define span_CPP11_OR_GREATER ( span_CPLUSPLUS >= 201103L )
191#define span_CPP14_OR_GREATER ( span_CPLUSPLUS >= 201402L )
192#define span_CPP17_OR_GREATER ( span_CPLUSPLUS >= 201703L )
193#define span_CPP20_OR_GREATER ( span_CPLUSPLUS >= 202002L )
194#define span_CPP23_OR_GREATER ( span_CPLUSPLUS >= 202300L )
195
196// C++ language version (represent 98 as 3):
197
198#define span_CPLUSPLUS_V ( span_CPLUSPLUS / 100 - (span_CPLUSPLUS > 200000 ? 2000 : 1994) )
199
200#define span_IN_STD( v ) ( ((v) == 98 ? 3 : (v)) >= span_CPLUSPLUS_V )
201
202#define span_CONFIG( feature ) ( span_CONFIG_##feature )
203#define span_FEATURE( feature ) ( span_FEATURE_##feature )
204#define span_FEATURE_TO_STD( feature ) ( span_IN_STD( span_FEATURE( feature##_TO_STD ) ) )
205
206// Use C++20 std::span if available and requested:
207
208#if span_CPP20_OR_GREATER && defined(__has_include )
209# if __has_include( <span> )
210# define span_HAVE_STD_SPAN 1
211# else
212# define span_HAVE_STD_SPAN 0
213# endif
214#else
215# define span_HAVE_STD_SPAN 0
216#endif
217
218#define span_USES_STD_SPAN ( (span_CONFIG_SELECT_SPAN == span_SPAN_STD) || ((span_CONFIG_SELECT_SPAN == span_SPAN_DEFAULT) && span_HAVE_STD_SPAN) )
219
220//
221// Use C++20 std::span:
222//
223
224#if span_USES_STD_SPAN
225
226#include <span>
227
228namespace nonstd {
229
230using std::span;
231using std::dynamic_extent;
232
233// Note: C++20 does not provide comparison
234// using std::operator==;
235// using std::operator!=;
236// using std::operator<;
237// using std::operator<=;
238// using std::operator>;
239// using std::operator>=;
240} // namespace nonstd
241
242#else // span_USES_STD_SPAN
243
244#include <algorithm>
245
246// Compiler versions:
247//
248// MSVC++ 6.0 _MSC_VER == 1200 span_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
249// MSVC++ 7.0 _MSC_VER == 1300 span_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
250// MSVC++ 7.1 _MSC_VER == 1310 span_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
251// MSVC++ 8.0 _MSC_VER == 1400 span_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
252// MSVC++ 9.0 _MSC_VER == 1500 span_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
253// MSVC++ 10.0 _MSC_VER == 1600 span_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
254// MSVC++ 11.0 _MSC_VER == 1700 span_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
255// MSVC++ 12.0 _MSC_VER == 1800 span_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
256// MSVC++ 14.0 _MSC_VER == 1900 span_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
257// MSVC++ 14.1 _MSC_VER >= 1910 span_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
258// MSVC++ 14.2 _MSC_VER >= 1920 span_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
259
260#if defined(_MSC_VER ) && !defined(__clang__)
261# define span_COMPILER_MSVC_VER (_MSC_VER )
262# define span_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
263#else
264# define span_COMPILER_MSVC_VER 0
265# define span_COMPILER_MSVC_VERSION 0
266#endif
267
268#define span_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
269
270#if defined(__clang__)
271# define span_COMPILER_CLANG_VERSION span_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
272#else
273# define span_COMPILER_CLANG_VERSION 0
274#endif
275
276#if defined(__GNUC__) && !defined(__clang__)
277# define span_COMPILER_GNUC_VERSION span_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
278#else
279# define span_COMPILER_GNUC_VERSION 0
280#endif
281
282// half-open range [lo..hi):
283#define span_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
284
285// Compiler warning suppression:
286
287#if defined(__clang__)
288# pragma clang diagnostic push
289# pragma clang diagnostic ignored "-Wundef"
290# pragma clang diagnostic ignored "-Wmismatched-tags"
291# define span_RESTORE_WARNINGS() _Pragma( "clang diagnostic pop" )
292
293#elif defined __GNUC__
294# pragma GCC diagnostic push
295# pragma GCC diagnostic ignored "-Wundef"
296# define span_RESTORE_WARNINGS() _Pragma( "GCC diagnostic pop" )
297
298#elif span_COMPILER_MSVC_VER >= 1900
299# define span_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes))
300# define span_RESTORE_WARNINGS() __pragma(warning(pop ))
301
302// Suppress the following MSVC GSL warnings:
303// - C26439, gsl::f.6 : special function 'function' can be declared 'noexcept'
304// - C26440, gsl::f.6 : function 'function' can be declared 'noexcept'
305// - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
306// use brace initialization, gsl::narrow_cast or gsl::narrow
307// - C26473: gsl::t.1 : don't cast between pointer types where the source type and the target type are the same
308// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
309// - C26490: gsl::t.1 : don't use reinterpret_cast
310
311span_DISABLE_MSVC_WARNINGS( 26439 26440 26472 26473 26481 26490 )
312
313#else
314# define span_RESTORE_WARNINGS() /*empty*/
315#endif
316
317// Presence of language and library features:
318
319#ifdef _HAS_CPP0X
320# define span_HAS_CPP0X _HAS_CPP0X
321#else
322# define span_HAS_CPP0X 0
323#endif
324
325#define span_CPP11_80 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1400)
326#define span_CPP11_90 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1500)
327#define span_CPP11_100 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1600)
328#define span_CPP11_110 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1700)
329#define span_CPP11_120 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1800)
330#define span_CPP11_140 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1900)
331
332#define span_CPP14_000 (span_CPP14_OR_GREATER)
333#define span_CPP14_120 (span_CPP14_OR_GREATER || span_COMPILER_MSVC_VER >= 1800)
334#define span_CPP14_140 (span_CPP14_OR_GREATER || span_COMPILER_MSVC_VER >= 1900)
335
336#define span_CPP17_000 (span_CPP17_OR_GREATER)
337
338// Presence of C++11 language features:
339
340#define span_HAVE_ALIAS_TEMPLATE span_CPP11_140
341#define span_HAVE_AUTO span_CPP11_100
342#define span_HAVE_CONSTEXPR_11 span_CPP11_140
343#define span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG span_CPP11_120
344#define span_HAVE_EXPLICIT_CONVERSION span_CPP11_140
345#define span_HAVE_INITIALIZER_LIST span_CPP11_120
346#define span_HAVE_IS_DEFAULT span_CPP11_140
347#define span_HAVE_IS_DELETE span_CPP11_140
348#define span_HAVE_NOEXCEPT span_CPP11_140
349#define span_HAVE_NORETURN ( span_CPP11_140 && ! span_BETWEEN( span_COMPILER_GNUC_VERSION, 1, 480 ) )
350#define span_HAVE_NULLPTR span_CPP11_100
351#define span_HAVE_STATIC_ASSERT span_CPP11_100
352
353// Presence of C++14 language features:
354
355#define span_HAVE_CONSTEXPR_14 span_CPP14_000
356
357// Presence of C++17 language features:
358
359#define span_HAVE_DEPRECATED span_CPP17_000
360#define span_HAVE_NODISCARD span_CPP17_000
361
362// MSVC: template parameter deduction guides since Visual Studio 2017 v15.7
363
364#if defined(__cpp_deduction_guides)
365# define span_HAVE_DEDUCTION_GUIDES 1
366#else
367# define span_HAVE_DEDUCTION_GUIDES (span_CPP17_OR_GREATER && ! span_BETWEEN( span_COMPILER_MSVC_VER, 1, 1913 ))
368#endif
369
370// Presence of C++ library features:
371
372#define span_HAVE_ADDRESSOF span_CPP17_000
373#define span_HAVE_ARRAY span_CPP11_110
374#define span_HAVE_BYTE span_CPP17_000
375#define span_HAVE_CONDITIONAL span_CPP11_120
376#define span_HAVE_CONTAINER_DATA_METHOD (span_CPP11_140 || ( span_COMPILER_MSVC_VER >= 1500 && span_HAS_CPP0X ))
377#define span_HAVE_DATA span_CPP17_000
378#define span_HAVE_LONGLONG span_CPP11_80
379#define span_HAVE_REMOVE_CONST span_CPP11_110
380#define span_HAVE_SNPRINTF span_CPP11_140
381#define span_HAVE_STRUCT_BINDING span_CPP11_120
382#define span_HAVE_TYPE_TRAITS span_CPP11_90
383
384// Presence of byte-lite:
385
386#ifdef NONSTD_BYTE_LITE_HPP
387# define span_HAVE_NONSTD_BYTE 1
388#else
389# define span_HAVE_NONSTD_BYTE 0
390#endif
391
392// C++ feature usage:
393
394#if span_HAVE_ADDRESSOF
395# define span_ADDRESSOF(x) std::addressof(x)
396#else
397# define span_ADDRESSOF(x) (&x)
398#endif
399
400#if span_HAVE_CONSTEXPR_11
401# define span_constexpr constexpr
402#else
403# define span_constexpr /*span_constexpr*/
404#endif
405
406#if span_HAVE_CONSTEXPR_14
407# define span_constexpr14 constexpr
408#else
409# define span_constexpr14 /*span_constexpr*/
410#endif
411
412#if span_HAVE_EXPLICIT_CONVERSION
413# define span_explicit explicit
414#else
415# define span_explicit /*explicit*/
416#endif
417
418#if span_HAVE_IS_DELETE
419# define span_is_delete = delete
420#else
421# define span_is_delete
422#endif
423
424#if span_HAVE_IS_DELETE
425# define span_is_delete_access public
426#else
427# define span_is_delete_access private
428#endif
429
430#if span_HAVE_NOEXCEPT && ! span_CONFIG_CONTRACT_VIOLATION_THROWS_V
431# define span_noexcept noexcept
432#else
433# define span_noexcept /*noexcept*/
434#endif
435
436#if span_HAVE_NULLPTR
437# define span_nullptr nullptr
438#else
439# define span_nullptr NULL
440#endif
441
442#if span_HAVE_DEPRECATED
443# define span_deprecated(msg) [[deprecated(msg)]]
444#else
445# define span_deprecated(msg) /*[[deprecated]]*/
446#endif
447
448#if span_HAVE_NODISCARD
449# define span_nodiscard [[nodiscard]]
450#else
451# define span_nodiscard /*[[nodiscard]]*/
452#endif
453
454#if span_HAVE_NORETURN
455# define span_noreturn [[noreturn]]
456#else
457# define span_noreturn /*[[noreturn]]*/
458#endif
459
460// Other features:
461
462#define span_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
463#define span_HAVE_ITERATOR_CTOR span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
464
465// Additional includes:
466
467#if span_HAVE( ADDRESSOF )
468# include <memory>
469#endif
470
471#if span_HAVE( ARRAY )
472# include <array>
473#endif
474
475#if span_HAVE( BYTE )
476# include <cstddef>
477#endif
478
479#if span_HAVE( DATA )
480# include <iterator> // for std::data(), std::size()
481#endif
482
483#if span_HAVE( TYPE_TRAITS )
484# include <type_traits>
485#endif
486
487#if ! span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
488# include <vector>
489#endif
490
491#if span_FEATURE( MEMBER_AT ) > 1
492# include <cstdio>
493#endif
494
495#if ! span_CONFIG( NO_EXCEPTIONS )
496# include <stdexcept>
497#endif
498
499// Contract violation
500
501#define span_ELIDE_CONTRACT_EXPECTS ( 0 == ( span_CONFIG_CONTRACT_LEVEL_MASK & 0x01 ) )
502#define span_ELIDE_CONTRACT_ENSURES ( 0 == ( span_CONFIG_CONTRACT_LEVEL_MASK & 0x10 ) )
503
504#if span_ELIDE_CONTRACT_EXPECTS
505# define span_constexpr_exp span_constexpr
506# define span_EXPECTS( cond ) /* Expect elided */
507#else
508# define span_constexpr_exp span_constexpr14
509# define span_EXPECTS( cond ) span_CONTRACT_CHECK( "Precondition", cond )
510#endif
511
512#if span_ELIDE_CONTRACT_ENSURES
513# define span_constexpr_ens span_constexpr
514# define span_ENSURES( cond ) /* Ensures elided */
515#else
516# define span_constexpr_ens span_constexpr14
517# define span_ENSURES( cond ) span_CONTRACT_CHECK( "Postcondition", cond )
518#endif
519
520#define span_CONTRACT_CHECK( type, cond ) \
521 cond ? static_cast< void >( 0 ) \
522 : nonstd::span_lite::detail::report_contract_violation( span_LOCATION( __FILE__, __LINE__ ) ": " type " violation." )
523
524#ifdef __GNUG__
525# define span_LOCATION( file, line ) file ":" span_STRINGIFY( line )
526#else
527# define span_LOCATION( file, line ) file "(" span_STRINGIFY( line ) ")"
528#endif
529
530// Method enabling
531
532#if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
533
534#define span_REQUIRES_0(VA) \
535 template< bool B = (VA), typename std::enable_if<B, int>::type = 0 >
536
537# if span_BETWEEN( span_COMPILER_MSVC_VERSION, 1, 140 )
538// VS 2013 and earlier seem to have trouble with SFINAE for default non-type arguments
539# define span_REQUIRES_T(VA) \
540 , typename = typename std::enable_if< ( VA ), nonstd::span_lite::detail::enabler >::type
541# else
542# define span_REQUIRES_T(VA) \
543 , typename std::enable_if< (VA), int >::type = 0
544# endif
545
546#define span_REQUIRES_R(R, VA) \
547 typename std::enable_if< (VA), R>::type
548
549#define span_REQUIRES_A(VA) \
550 , typename std::enable_if< (VA), void*>::type = nullptr
551
552#else
553
554# define span_REQUIRES_0(VA) /*empty*/
555# define span_REQUIRES_T(VA) /*empty*/
556# define span_REQUIRES_R(R, VA) R
557# define span_REQUIRES_A(VA) /*empty*/
558
559#endif
560
561namespace nonstd {
562namespace span_lite {
563
564// [views.constants], constants
565
566typedef span_CONFIG_EXTENT_TYPE extent_t;
567typedef span_CONFIG_SIZE_TYPE size_t;
568
569span_constexpr const extent_t dynamic_extent = static_cast<extent_t>( -1 );
570
571template< class T, extent_t Extent = dynamic_extent >
572class span;
573
574// Tag to select span constructor taking a container (prevent ms-gsl warning C26426):
575
576struct with_container_t { span_constexpr with_container_t() span_noexcept {} };
577const span_constexpr with_container_t with_container;
578
579// C++11 emulation:
580
581namespace std11 {
582
583#if span_HAVE( REMOVE_CONST )
584
585using std::remove_cv;
586using std::remove_const;
587using std::remove_volatile;
588
589#else
590
591template< class T > struct remove_const { typedef T type; };
592template< class T > struct remove_const< T const > { typedef T type; };
593
594template< class T > struct remove_volatile { typedef T type; };
595template< class T > struct remove_volatile< T volatile > { typedef T type; };
596
597template< class T >
598struct remove_cv
599{
600 typedef typename std11::remove_volatile< typename std11::remove_const< T >::type >::type type;
601};
602
603#endif // span_HAVE( REMOVE_CONST )
604
605#if span_HAVE( TYPE_TRAITS )
606
607using std::is_same;
608using std::is_signed;
609using std::integral_constant;
610using std::true_type;
611using std::false_type;
612using std::remove_reference;
613
614#else
615
616template< class T, T v > struct integral_constant { enum { value = v }; };
617typedef integral_constant< bool, true > true_type;
618typedef integral_constant< bool, false > false_type;
619
620template< class T, class U > struct is_same : false_type{};
621template< class T > struct is_same<T, T> : true_type{};
622
623template< typename T > struct is_signed : false_type {};
624template<> struct is_signed<signed char> : true_type {};
625template<> struct is_signed<signed int > : true_type {};
626template<> struct is_signed<signed long> : true_type {};
627
628#endif
629
630} // namespace std11
631
632// C++17 emulation:
633
634namespace std17 {
635
636template< bool v > struct bool_constant : std11::integral_constant<bool, v>{};
637
638#if span_CPP11_120
639
640template< class...>
641using void_t = void;
642
643#endif
644
645#if span_HAVE( DATA )
646
647using std::data;
648using std::size;
649
650#elif span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
651
652template< typename T, std::size_t N >
653inline span_constexpr auto size( const T(&)[N] ) span_noexcept -> size_t
654{
655 return N;
656}
657
658template< typename C >
659inline span_constexpr auto size( C const & cont ) -> decltype( cont.size() )
660{
661 return cont.size();
662}
663
664template< typename T, std::size_t N >
665inline span_constexpr auto data( T(&arr)[N] ) span_noexcept -> T*
666{
667 return &arr[0];
668}
669
670template< typename C >
671inline span_constexpr auto data( C & cont ) -> decltype( cont.data() )
672{
673 return cont.data();
674}
675
676template< typename C >
677inline span_constexpr auto data( C const & cont ) -> decltype( cont.data() )
678{
679 return cont.data();
680}
681
682template< typename E >
683inline span_constexpr auto data( std::initializer_list<E> il ) span_noexcept -> E const *
684{
685 return il.begin();
686}
687
688#endif // span_HAVE( DATA )
689
690#if span_HAVE( BYTE )
691using std::byte;
692#elif span_HAVE( NONSTD_BYTE )
693using nonstd::byte;
694#endif
695
696} // namespace std17
697
698// C++20 emulation:
699
700namespace std20 {
701
702#if span_HAVE( DEDUCTION_GUIDES )
703template< class T >
704using iter_reference_t = decltype( *std::declval<T&>() );
705#endif
706
707} // namespace std20
708
709// Implementation details:
710
711namespace detail {
712
713/*enum*/ struct enabler{};
714
715template< typename T >
716span_constexpr bool is_positive( T x )
717{
718 return std11::is_signed<T>::value ? x >= 0 : true;
719}
720
721#if span_HAVE( TYPE_TRAITS )
722
723template< class Q >
724struct is_span_oracle : std::false_type{};
725
726template< class T, span_CONFIG_EXTENT_TYPE Extent >
727struct is_span_oracle< span<T, Extent> > : std::true_type{};
728
729template< class Q >
730struct is_span : is_span_oracle< typename std::remove_cv<Q>::type >{};
731
732template< class Q >
733struct is_std_array_oracle : std::false_type{};
734
735#if span_HAVE( ARRAY )
736
737template< class T, std::size_t Extent >
738struct is_std_array_oracle< std::array<T, Extent> > : std::true_type{};
739
740#endif
741
742template< class Q >
743struct is_std_array : is_std_array_oracle< typename std::remove_cv<Q>::type >{};
744
745template< class Q >
746struct is_array : std::false_type {};
747
748template< class T >
749struct is_array<T[]> : std::true_type {};
750
751template< class T, std::size_t N >
752struct is_array<T[N]> : std::true_type {};
753
754#if span_CPP11_140 && ! span_BETWEEN( span_COMPILER_GNUC_VERSION, 1, 500 )
755
756template< class, class = void >
757struct has_size_and_data : std::false_type{};
758
759template< class C >
760struct has_size_and_data
761<
762 C, std17::void_t<
763 decltype( std17::size(std::declval<C>()) ),
764 decltype( std17::data(std::declval<C>()) ) >
765> : std::true_type{};
766
767template< class, class, class = void >
768struct is_compatible_element : std::false_type {};
769
770template< class C, class E >
771struct is_compatible_element
772<
773 C, E, std17::void_t<
774 decltype( std17::data(std::declval<C>()) ) >
775> : std::is_convertible< typename std::remove_pointer<decltype( std17::data( std::declval<C&>() ) )>::type(*)[], E(*)[] >{};
776
777template< class C >
778struct is_container : std17::bool_constant
779<
780 ! is_span< C >::value
781 && ! is_array< C >::value
782 && ! is_std_array< C >::value
783 && has_size_and_data< C >::value
784>{};
785
786template< class C, class E >
787struct is_compatible_container : std17::bool_constant
788<
789 is_container<C>::value
790 && is_compatible_element<C,E>::value
791>{};
792
793#else // span_CPP11_140
794
795template<
796 class C, class E
797 span_REQUIRES_T((
798 ! is_span< C >::value
799 && ! is_array< C >::value
800 && ! is_std_array< C >::value
801 && ( std::is_convertible< typename std::remove_pointer<decltype( std17::data( std::declval<C&>() ) )>::type(*)[], E(*)[] >::value)
802 // && has_size_and_data< C >::value
803 ))
804 , class = decltype( std17::size(std::declval<C>()) )
805 , class = decltype( std17::data(std::declval<C>()) )
806>
807struct is_compatible_container : std::true_type{};
808
809#endif // span_CPP11_140
810
811#endif // span_HAVE( TYPE_TRAITS )
812
813#if ! span_CONFIG( NO_EXCEPTIONS )
814#if span_FEATURE( MEMBER_AT ) > 1
815
816// format index and size:
817
818#if defined(__clang__)
819# pragma clang diagnostic ignored "-Wlong-long"
820#elif defined __GNUC__
821# pragma GCC diagnostic ignored "-Wformat=ll"
822# pragma GCC diagnostic ignored "-Wlong-long"
823#endif
824
825span_noreturn inline void throw_out_of_range( size_t idx, size_t size )
826{
827 const char fmt[] = "span::at(): index '%lli' is out of range [0..%lli)";
828 char buffer[ 2 * 20 + sizeof fmt ];
829 sprintf( buffer, fmt, static_cast<long long>(idx), static_cast<long long>(size) );
830
831 throw std::out_of_range( buffer );
832}
833
834#else // MEMBER_AT
835
836span_noreturn inline void throw_out_of_range( size_t /*idx*/, size_t /*size*/ )
837{
838 throw std::out_of_range( "span::at(): index outside span" );
839}
840#endif // MEMBER_AT
841#endif // NO_EXCEPTIONS
842
843#if span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
844
845struct contract_violation : std::logic_error
846{
847 explicit contract_violation( char const * const message )
848 : std::logic_error( message )
849 {}
850};
851
852inline void report_contract_violation( char const * msg )
853{
854 throw contract_violation( msg );
855}
856
857#else // span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
858
859span_noreturn inline void report_contract_violation( char const * /*msg*/ ) span_noexcept
860{
861 std::terminate();
862}
863
864#endif // span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
865
866} // namespace detail
867
868// Prevent signed-unsigned mismatch:
869
870#define span_sizeof(T) static_cast<extent_t>( sizeof(T) )
871
872template< class T >
873inline span_constexpr size_t to_size( T size )
874{
875 return static_cast<size_t>( size );
876}
877
878//
879// [views.span] - A view over a contiguous, single-dimension sequence of objects
880//
881template< class T, extent_t Extent /*= dynamic_extent*/ >
882class span
883{
884public:
885 // constants and types
886
887 typedef T element_type;
888 typedef typename std11::remove_cv< T >::type value_type;
889
890 typedef T & reference;
891 typedef T * pointer;
892 typedef T const * const_pointer;
893 typedef T const & const_reference;
894
895 typedef size_t size_type;
896 typedef extent_t extent_type;
897
898 typedef pointer iterator;
899 typedef const_pointer const_iterator;
900
901 typedef std::ptrdiff_t difference_type;
902
903 typedef std::reverse_iterator< iterator > reverse_iterator;
904 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
905
906// static constexpr extent_type extent = Extent;
907 enum { extent = Extent };
908
909 // 26.7.3.2 Constructors, copy, and assignment [span.cons]
910
911 span_REQUIRES_0(
912 ( Extent == 0 ) ||
913 ( Extent == dynamic_extent )
914 )
915 span_constexpr span() span_noexcept
916 : data_( span_nullptr )
917 , size_( 0 )
918 {
919 // span_EXPECTS( data() == span_nullptr );
920 // span_EXPECTS( size() == 0 );
921 }
922
923#if span_HAVE( ITERATOR_CTOR )
924 // Didn't yet succeed in combining the next two constructors:
925
926 span_constexpr_exp span( std::nullptr_t, size_type count )
927 : data_( span_nullptr )
928 , size_( count )
929 {
930 span_EXPECTS( data_ == span_nullptr && count == 0 );
931 }
932
933 template< typename It
934 span_REQUIRES_T((
935 std::is_convertible<decltype(*std::declval<It&>()), element_type &>::value
936 ))
937 >
938 span_constexpr_exp span( It first, size_type count )
939 : data_( to_address( first ) )
940 , size_( count )
941 {
942 span_EXPECTS(
943 ( data_ == span_nullptr && count == 0 ) ||
944 ( data_ != span_nullptr && detail::is_positive( count ) )
945 );
946 }
947#else
948 span_constexpr_exp span( pointer ptr, size_type count )
949 : data_( ptr )
950 , size_( count )
951 {
952 span_EXPECTS(
953 ( ptr == span_nullptr && count == 0 ) ||
954 ( ptr != span_nullptr && detail::is_positive( count ) )
955 );
956 }
957#endif
958
959#if span_HAVE( ITERATOR_CTOR )
960 template< typename It, typename End
961 span_REQUIRES_T((
962 std::is_convertible<decltype(&*std::declval<It&>()), element_type *>::value
963 && ! std::is_convertible<End, std::size_t>::value
964 ))
965 >
966 span_constexpr_exp span( It first, End last )
967 : data_( to_address( first ) )
968 , size_( to_size( last - first ) )
969 {
970 span_EXPECTS(
971 last - first >= 0
972 );
973 }
974#else
975 span_constexpr_exp span( pointer first, pointer last )
976 : data_( first )
977 , size_( to_size( last - first ) )
978 {
979 span_EXPECTS(
980 last - first >= 0
981 );
982 }
983#endif
984
985 template< std::size_t N
986 span_REQUIRES_T((
987 (Extent == dynamic_extent || Extent == static_cast<extent_t>(N))
988 && std::is_convertible< value_type(*)[], element_type(*)[] >::value
989 ))
990 >
991 span_constexpr span( element_type ( &arr )[ N ] ) span_noexcept
992 : data_( span_ADDRESSOF( arr[0] ) )
993 , size_( N )
994 {}
995
996#if span_HAVE( ARRAY )
997
998 template< std::size_t N
999 span_REQUIRES_T((
1000 (Extent == dynamic_extent || Extent == static_cast<extent_t>(N))
1001 && std::is_convertible< value_type(*)[], element_type(*)[] >::value
1002 ))
1003 >
1004# if span_FEATURE( CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE )
1005 span_constexpr span( std::array< element_type, N > & arr ) span_noexcept
1006# else
1007 span_constexpr span( std::array< value_type, N > & arr ) span_noexcept
1008# endif
1009 : data_( arr.data() )
1010 , size_( to_size( arr.size() ) )
1011 {}
1012
1013 template< std::size_t N
1014# if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
1015 span_REQUIRES_T((
1016 (Extent == dynamic_extent || Extent == static_cast<extent_t>(N))
1017 && std::is_convertible< value_type(*)[], element_type(*)[] >::value
1018 ))
1019# endif
1020 >
1021 span_constexpr span( std::array< value_type, N> const & arr ) span_noexcept
1022 : data_( arr.data() )
1023 , size_( to_size( arr.size() ) )
1024 {}
1025
1026#endif // span_HAVE( ARRAY )
1027
1028#if span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
1029 template< class Container
1030 span_REQUIRES_T((
1031 detail::is_compatible_container< Container, element_type >::value
1032 ))
1033 >
1034 span_constexpr span( Container & cont )
1035 : data_( std17::data( cont ) )
1036 , size_( to_size( std17::size( cont ) ) )
1037 {}
1038
1039 template< class Container
1040 span_REQUIRES_T((
1041 std::is_const< element_type >::value
1042 && detail::is_compatible_container< Container, element_type >::value
1043 ))
1044 >
1045 span_constexpr span( Container const & cont )
1046 : data_( std17::data( cont ) )
1047 , size_( to_size( std17::size( cont ) ) )
1048 {}
1049
1050#endif // span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
1051
1052#if span_FEATURE( WITH_CONTAINER )
1053
1054 template< class Container >
1055 span_constexpr span( with_container_t, Container & cont )
1056 : data_( cont.size() == 0 ? span_nullptr : span_ADDRESSOF( cont[0] ) )
1057 , size_( to_size( cont.size() ) )
1058 {}
1059
1060 template< class Container >
1061 span_constexpr span( with_container_t, Container const & cont )
1062 : data_( cont.size() == 0 ? span_nullptr : const_cast<pointer>( span_ADDRESSOF( cont[0] ) ) )
1063 , size_( to_size( cont.size() ) )
1064 {}
1065#endif
1066
1067#if span_FEATURE( WITH_INITIALIZER_LIST_P2447 ) && span_HAVE( INITIALIZER_LIST )
1068
1069 // constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il) noexcept;
1070
1071#if !span_BETWEEN( span_COMPILER_MSVC_VERSION, 120, 130 )
1072
1073 template< extent_t U = Extent
1074 span_REQUIRES_T((
1075 U != dynamic_extent
1076 ))
1077 >
1078#if span_COMPILER_GNUC_VERSION >= 900 // prevent GCC's "-Winit-list-lifetime"
1079 span_constexpr14 explicit span( std::initializer_list<value_type> il ) span_noexcept
1080 {
1081 data_ = il.begin();
1082 size_ = il.size();
1083 }
1084#else
1085 span_constexpr explicit span( std::initializer_list<value_type> il ) span_noexcept
1086 : data_( il.begin() )
1087 , size_( il.size() )
1088 {}
1089#endif
1090
1091#endif // MSVC 120 (VS2013)
1092
1093 template< extent_t U = Extent
1094 span_REQUIRES_T((
1095 U == dynamic_extent
1096 ))
1097 >
1098#if span_COMPILER_GNUC_VERSION >= 900 // prevent GCC's "-Winit-list-lifetime"
1099 span_constexpr14 /*explicit*/ span( std::initializer_list<value_type> il ) span_noexcept
1100 {
1101 data_ = il.begin();
1102 size_ = il.size();
1103 }
1104#else
1105 span_constexpr /*explicit*/ span( std::initializer_list<value_type> il ) span_noexcept
1106 : data_( il.begin() )
1107 , size_( il.size() )
1108 {}
1109#endif
1110
1111#endif // P2447
1112
1113#if span_HAVE( IS_DEFAULT )
1114 span_constexpr span( span const & other ) span_noexcept = default;
1115
1116 ~span() span_noexcept = default;
1117
1118 span_constexpr14 span & operator=( span const & other ) span_noexcept = default;
1119#else
1120 span_constexpr span( span const & other ) span_noexcept
1121 : data_( other.data_ )
1122 , size_( other.size_ )
1123 {}
1124
1125 ~span() span_noexcept
1126 {}
1127
1128 span_constexpr14 span & operator=( span const & other ) span_noexcept
1129 {
1130 data_ = other.data_;
1131 size_ = other.size_;
1132
1133 return *this;
1134 }
1135#endif
1136
1137 template< class OtherElementType, extent_type OtherExtent
1138 span_REQUIRES_T((
1139 (Extent == dynamic_extent || OtherExtent == dynamic_extent || Extent == OtherExtent)
1140 && std::is_convertible<OtherElementType(*)[], element_type(*)[]>::value
1141 ))
1142 >
1143 span_constexpr_exp span( span<OtherElementType, OtherExtent> const & other ) span_noexcept
1144 : data_( other.data() )
1145 , size_( other.size() )
1146 {
1147 span_EXPECTS( OtherExtent == dynamic_extent || other.size() == to_size(OtherExtent) );
1148 }
1149
1150 // 26.7.3.3 Subviews [span.sub]
1151
1152 template< extent_type Count >
1153 span_constexpr_exp span< element_type, Count >
1154 first() const
1155 {
1156 span_EXPECTS( detail::is_positive( Count ) && Count <= size() );
1157
1158 return span< element_type, Count >( data(), Count );
1159 }
1160
1161 template< extent_type Count >
1162 span_constexpr_exp span< element_type, Count >
1163 last() const
1164 {
1165 span_EXPECTS( detail::is_positive( Count ) && Count <= size() );
1166
1167 return span< element_type, Count >( data() + (size() - Count), Count );
1168 }
1169
1170#if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
1171 template< size_type Offset, extent_type Count = dynamic_extent >
1172#else
1173 template< size_type Offset, extent_type Count /*= dynamic_extent*/ >
1174#endif
1175 span_constexpr_exp span< element_type, Count >
1176 subspan() const
1177 {
1178 span_EXPECTS(
1179 ( detail::is_positive( Offset ) && Offset <= size() ) &&
1180 ( Count == dynamic_extent || (detail::is_positive( Count ) && Count + Offset <= size()) )
1181 );
1182
1183 return span< element_type, Count >(
1184 data() + Offset, Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : size() - Offset) );
1185 }
1186
1187 span_constexpr_exp span< element_type, dynamic_extent >
1188 first( size_type count ) const
1189 {
1190 span_EXPECTS( detail::is_positive( count ) && count <= size() );
1191
1192 return span< element_type, dynamic_extent >( data(), count );
1193 }
1194
1195 span_constexpr_exp span< element_type, dynamic_extent >
1196 last( size_type count ) const
1197 {
1198 span_EXPECTS( detail::is_positive( count ) && count <= size() );
1199
1200 return span< element_type, dynamic_extent >( data() + ( size() - count ), count );
1201 }
1202
1203 span_constexpr_exp span< element_type, dynamic_extent >
1204 subspan( size_type offset, size_type count = static_cast<size_type>(dynamic_extent) ) const
1205 {
1206 span_EXPECTS(
1207 ( ( detail::is_positive( offset ) && offset <= size() ) ) &&
1208 ( count == static_cast<size_type>(dynamic_extent) || ( detail::is_positive( count ) && offset + count <= size() ) )
1209 );
1210
1211 return span< element_type, dynamic_extent >(
1212 data() + offset, count == static_cast<size_type>(dynamic_extent) ? size() - offset : count );
1213 }
1214
1215 // 26.7.3.4 Observers [span.obs]
1216
1217 span_constexpr size_type size() const span_noexcept
1218 {
1219 return size_;
1220 }
1221
1222 span_constexpr std::ptrdiff_t ssize() const span_noexcept
1223 {
1224 return static_cast<std::ptrdiff_t>( size_ );
1225 }
1226
1227 span_constexpr size_type size_bytes() const span_noexcept
1228 {
1229 return size() * to_size( sizeof( element_type ) );
1230 }
1231
1232 span_nodiscard span_constexpr bool empty() const span_noexcept
1233 {
1234 return size() == 0;
1235 }
1236
1237 // 26.7.3.5 Element access [span.elem]
1238
1239 span_constexpr_exp reference operator[]( size_type idx ) const
1240 {
1241 span_EXPECTS( detail::is_positive( idx ) && idx < size() );
1242
1243 return *( data() + idx );
1244 }
1245
1246#if span_FEATURE( MEMBER_CALL_OPERATOR )
1247 span_deprecated("replace operator() with operator[]")
1248
1249 span_constexpr_exp reference operator()( size_type idx ) const
1250 {
1251 span_EXPECTS( detail::is_positive( idx ) && idx < size() );
1252
1253 return *( data() + idx );
1254 }
1255#endif
1256
1257#if span_FEATURE( MEMBER_AT )
1258 span_constexpr14 reference at( size_type idx ) const
1259 {
1260#if span_CONFIG( NO_EXCEPTIONS )
1261 return this->operator[]( idx );
1262#else
1263 if ( !detail::is_positive( idx ) || size() <= idx )
1264 {
1265 detail::throw_out_of_range( idx, size() );
1266 }
1267 return *( data() + idx );
1268#endif
1269 }
1270#endif
1271
1272 span_constexpr pointer data() const span_noexcept
1273 {
1274 return data_;
1275 }
1276
1277#if span_FEATURE( MEMBER_BACK_FRONT )
1278
1279 span_constexpr_exp reference front() const span_noexcept
1280 {
1281 span_EXPECTS( ! empty() );
1282
1283 return *data();
1284 }
1285
1286 span_constexpr_exp reference back() const span_noexcept
1287 {
1288 span_EXPECTS( ! empty() );
1289
1290 return *( data() + size() - 1 );
1291 }
1292
1293#endif
1294
1295 // xx.x.x.x Modifiers [span.modifiers]
1296
1297#if span_FEATURE( MEMBER_SWAP )
1298
1299 span_constexpr14 void swap( span & other ) span_noexcept
1300 {
1301 using std::swap;
1302 swap( data_, other.data_ );
1303 swap( size_, other.size_ );
1304 }
1305#endif
1306
1307 // 26.7.3.6 Iterator support [span.iterators]
1308
1309 span_constexpr iterator begin() const span_noexcept
1310 {
1311#if span_CPP11_OR_GREATER
1312 return { data() };
1313#else
1314 return iterator( data() );
1315#endif
1316 }
1317
1318 span_constexpr iterator end() const span_noexcept
1319 {
1320#if span_CPP11_OR_GREATER
1321 return { data() + size() };
1322#else
1323 return iterator( data() + size() );
1324#endif
1325 }
1326
1327 span_constexpr const_iterator cbegin() const span_noexcept
1328 {
1329#if span_CPP11_OR_GREATER
1330 return { data() };
1331#else
1332 return const_iterator( data() );
1333#endif
1334 }
1335
1336 span_constexpr const_iterator cend() const span_noexcept
1337 {
1338#if span_CPP11_OR_GREATER
1339 return { data() + size() };
1340#else
1341 return const_iterator( data() + size() );
1342#endif
1343 }
1344
1345 span_constexpr reverse_iterator rbegin() const span_noexcept
1346 {
1347 return reverse_iterator( end() );
1348 }
1349
1350 span_constexpr reverse_iterator rend() const span_noexcept
1351 {
1352 return reverse_iterator( begin() );
1353 }
1354
1355 span_constexpr const_reverse_iterator crbegin() const span_noexcept
1356 {
1357 return const_reverse_iterator ( cend() );
1358 }
1359
1360 span_constexpr const_reverse_iterator crend() const span_noexcept
1361 {
1362 return const_reverse_iterator( cbegin() );
1363 }
1364
1365private:
1366
1367 // Note: C++20 has std::pointer_traits<Ptr>::to_address( it );
1368
1369#if span_HAVE( ITERATOR_CTOR )
1370 static inline span_constexpr pointer to_address( std::nullptr_t ) span_noexcept
1371 {
1372 return nullptr;
1373 }
1374
1375 template< typename U >
1376 static inline span_constexpr U * to_address( U * p ) span_noexcept
1377 {
1378 return p;
1379 }
1380
1381 template< typename Ptr
1382 span_REQUIRES_T(( ! std::is_pointer<Ptr>::value ))
1383 >
1384 static inline span_constexpr pointer to_address( Ptr const & it ) span_noexcept
1385 {
1386 return to_address( it.operator->() );
1387 }
1388#endif // span_HAVE( ITERATOR_CTOR )
1389
1390private:
1391 pointer data_;
1392 size_type size_;
1393};
1394
1395// class template argument deduction guides:
1396
1397#if span_HAVE( DEDUCTION_GUIDES )
1398
1399template< class T, size_t N >
1400span( T (&)[N] ) -> span<T, static_cast<extent_t>(N)>;
1401
1402template< class T, size_t N >
1403span( std::array<T, N> & ) -> span<T, static_cast<extent_t>(N)>;
1404
1405template< class T, size_t N >
1406span( std::array<T, N> const & ) -> span<const T, static_cast<extent_t>(N)>;
1407
1408#if span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
1409
1410template< class Container >
1411span( Container& ) -> span<typename Container::value_type>;
1412
1413template< class Container >
1414span( Container const & ) -> span<const typename Container::value_type>;
1415
1416#endif
1417
1418// iterator: constraints: It satisfies contiguous_­iterator.
1419
1420template< class It, class EndOrSize >
1421span( It, EndOrSize ) -> span< typename std11::remove_reference< typename std20::iter_reference_t<It> >::type >;
1422
1423#endif // span_HAVE( DEDUCTION_GUIDES )
1424
1425// 26.7.3.7 Comparison operators [span.comparison]
1426
1427#if span_FEATURE( COMPARISON )
1428#if span_FEATURE( SAME )
1429
1430template< class T1, extent_t E1, class T2, extent_t E2 >
1431inline span_constexpr bool same( span<T1,E1> const & l, span<T2,E2> const & r ) span_noexcept
1432{
1433 return std11::is_same<T1, T2>::value
1434 && l.size() == r.size()
1435 && static_cast<void const*>( l.data() ) == r.data();
1436}
1437
1438#endif
1439
1440template< class T1, extent_t E1, class T2, extent_t E2 >
1441inline span_constexpr bool operator==( span<T1,E1> const & l, span<T2,E2> const & r )
1442{
1443 return
1444#if span_FEATURE( SAME )
1445 same( l, r ) ||
1446#endif
1447 ( l.size() == r.size() && std::equal( l.begin(), l.end(), r.begin() ) );
1448}
1449
1450template< class T1, extent_t E1, class T2, extent_t E2 >
1451inline span_constexpr bool operator<( span<T1,E1> const & l, span<T2,E2> const & r )
1452{
1453 return std::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() );
1454}
1455
1456template< class T1, extent_t E1, class T2, extent_t E2 >
1457inline span_constexpr bool operator!=( span<T1,E1> const & l, span<T2,E2> const & r )
1458{
1459 return !( l == r );
1460}
1461
1462template< class T1, extent_t E1, class T2, extent_t E2 >
1463inline span_constexpr bool operator<=( span<T1,E1> const & l, span<T2,E2> const & r )
1464{
1465 return !( r < l );
1466}
1467
1468template< class T1, extent_t E1, class T2, extent_t E2 >
1469inline span_constexpr bool operator>( span<T1,E1> const & l, span<T2,E2> const & r )
1470{
1471 return ( r < l );
1472}
1473
1474template< class T1, extent_t E1, class T2, extent_t E2 >
1475inline span_constexpr bool operator>=( span<T1,E1> const & l, span<T2,E2> const & r )
1476{
1477 return !( l < r );
1478}
1479
1480#endif // span_FEATURE( COMPARISON )
1481
1482// 26.7.2.6 views of object representation [span.objectrep]
1483
1484#if span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE )
1485
1486// Avoid MSVC 14.1 (1910), VS 2017: warning C4307: '*': integral constant overflow:
1487
1488template< typename T, extent_t Extent >
1489struct BytesExtent
1490{
1491#if span_CPP11_OR_GREATER
1492 enum ET : extent_t { value = span_sizeof(T) * Extent };
1493#else
1494 enum ET { value = span_sizeof(T) * Extent };
1495#endif
1496};
1497
1498template< typename T >
1499struct BytesExtent< T, dynamic_extent >
1500{
1501#if span_CPP11_OR_GREATER
1502 enum ET : extent_t { value = dynamic_extent };
1503#else
1504 enum ET { value = dynamic_extent };
1505#endif
1506};
1507
1508template< class T, extent_t Extent >
1509inline span_constexpr span< const std17::byte, BytesExtent<T, Extent>::value >
1510as_bytes( span<T,Extent> spn ) span_noexcept
1511{
1512#if 0
1513 return { reinterpret_cast< std17::byte const * >( spn.data() ), spn.size_bytes() };
1514#else
1515 return span< const std17::byte, BytesExtent<T, Extent>::value >(
1516 reinterpret_cast< std17::byte const * >( spn.data() ), spn.size_bytes() ); // NOLINT
1517#endif
1518}
1519
1520template< class T, extent_t Extent >
1521inline span_constexpr span< std17::byte, BytesExtent<T, Extent>::value >
1522as_writable_bytes( span<T,Extent> spn ) span_noexcept
1523{
1524#if 0
1525 return { reinterpret_cast< std17::byte * >( spn.data() ), spn.size_bytes() };
1526#else
1527 return span< std17::byte, BytesExtent<T, Extent>::value >(
1528 reinterpret_cast< std17::byte * >( spn.data() ), spn.size_bytes() ); // NOLINT
1529#endif
1530}
1531
1532#endif // span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE )
1533
1534// 27.8 Container and view access [iterator.container]
1535
1536template< class T, extent_t Extent /*= dynamic_extent*/ >
1537span_constexpr std::size_t size( span<T,Extent> const & spn )
1538{
1539 return static_cast<std::size_t>( spn.size() );
1540}
1541
1542template< class T, extent_t Extent /*= dynamic_extent*/ >
1543span_constexpr std::ptrdiff_t ssize( span<T,Extent> const & spn )
1544{
1545 return static_cast<std::ptrdiff_t>( spn.size() );
1546}
1547
1548} // namespace span_lite
1549} // namespace nonstd
1550
1551// make available in nonstd:
1552
1553namespace nonstd {
1554
1555using span_lite::dynamic_extent;
1556
1557using span_lite::span;
1558
1559using span_lite::with_container;
1560
1561#if span_FEATURE( COMPARISON )
1562#if span_FEATURE( SAME )
1563using span_lite::same;
1564#endif
1565
1566using span_lite::operator==;
1567using span_lite::operator!=;
1568using span_lite::operator<;
1569using span_lite::operator<=;
1570using span_lite::operator>;
1571using span_lite::operator>=;
1572#endif
1573
1574#if span_HAVE( BYTE )
1575using span_lite::as_bytes;
1576using span_lite::as_writable_bytes;
1577#endif
1578
1579using span_lite::size;
1580using span_lite::ssize;
1581
1582} // namespace nonstd
1583
1584#endif // span_USES_STD_SPAN
1585
1586// make_span() [span-lite extension]:
1587
1588#if span_FEATURE( MAKE_SPAN ) || span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_SPAN ) || span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_CONTAINER )
1589
1590#if span_USES_STD_SPAN
1591# define span_constexpr constexpr
1592# define span_noexcept noexcept
1593# define span_nullptr nullptr
1594# ifndef span_CONFIG_EXTENT_TYPE
1595# define span_CONFIG_EXTENT_TYPE std::size_t
1596# endif
1597using extent_t = span_CONFIG_EXTENT_TYPE;
1598#endif // span_USES_STD_SPAN
1599
1600namespace nonstd {
1601namespace span_lite {
1602
1603template< class T >
1604inline span_constexpr span<T>
1605make_span( T * ptr, size_t count ) span_noexcept
1606{
1607 return span<T>( ptr, count );
1608}
1609
1610template< class T >
1611inline span_constexpr span<T>
1612make_span( T * first, T * last ) span_noexcept
1613{
1614 return span<T>( first, last );
1615}
1616
1617template< class T, std::size_t N >
1618inline span_constexpr span<T, static_cast<extent_t>(N)>
1619make_span( T ( &arr )[ N ] ) span_noexcept
1620{
1621 return span<T, static_cast<extent_t>(N)>( &arr[ 0 ], N );
1622}
1623
1624#if span_USES_STD_SPAN || span_HAVE( ARRAY )
1625
1626template< class T, std::size_t N >
1627inline span_constexpr span<T, static_cast<extent_t>(N)>
1628make_span( std::array< T, N > & arr ) span_noexcept
1629{
1630 return span<T, static_cast<extent_t>(N)>( arr );
1631}
1632
1633template< class T, std::size_t N >
1634inline span_constexpr span< const T, static_cast<extent_t>(N) >
1635make_span( std::array< T, N > const & arr ) span_noexcept
1636{
1637 return span<const T, static_cast<extent_t>(N)>( arr );
1638}
1639
1640#endif // span_HAVE( ARRAY )
1641
1642#if span_USES_STD_SPAN || span_HAVE( INITIALIZER_LIST )
1643
1644template< class T >
1645inline span_constexpr span< const T >
1646make_span( std::initializer_list<T> il ) span_noexcept
1647{
1648 return span<const T>( il.begin(), il.size() );
1649}
1650
1651#endif // span_HAVE( INITIALIZER_LIST )
1652
1653#if span_USES_STD_SPAN
1654
1655template< class Container, class EP = decltype( std::data(std::declval<Container&>())) >
1656inline span_constexpr auto
1657make_span( Container & cont ) span_noexcept -> span< typename std::remove_pointer<EP>::type >
1658{
1659 return span< typename std::remove_pointer<EP>::type >( cont );
1660}
1661
1662template< class Container, class EP = decltype( std::data(std::declval<Container&>())) >
1663inline span_constexpr auto
1664make_span( Container const & cont ) span_noexcept -> span< const typename std::remove_pointer<EP>::type >
1665{
1666 return span< const typename std::remove_pointer<EP>::type >( cont );
1667}
1668
1669#elif span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) && span_HAVE( AUTO )
1670
1671template< class Container, class EP = decltype( std17::data(std::declval<Container&>())) >
1672inline span_constexpr auto
1673make_span( Container & cont ) span_noexcept -> span< typename std::remove_pointer<EP>::type >
1674{
1675 return span< typename std::remove_pointer<EP>::type >( cont );
1676}
1677
1678template< class Container, class EP = decltype( std17::data(std::declval<Container&>())) >
1679inline span_constexpr auto
1680make_span( Container const & cont ) span_noexcept -> span< const typename std::remove_pointer<EP>::type >
1681{
1682 return span< const typename std::remove_pointer<EP>::type >( cont );
1683}
1684
1685#else
1686
1687template< class T >
1688inline span_constexpr span<T>
1689make_span( span<T> spn ) span_noexcept
1690{
1691 return spn;
1692}
1693
1694template< class T, class Allocator >
1695inline span_constexpr span<T>
1696make_span( std::vector<T, Allocator> & cont ) span_noexcept
1697{
1698 return span<T>( with_container, cont );
1699}
1700
1701template< class T, class Allocator >
1702inline span_constexpr span<const T>
1703make_span( std::vector<T, Allocator> const & cont ) span_noexcept
1704{
1705 return span<const T>( with_container, cont );
1706}
1707
1708#endif // span_USES_STD_SPAN || ( ... )
1709
1710#if ! span_USES_STD_SPAN && span_FEATURE( WITH_CONTAINER )
1711
1712template< class Container >
1713inline span_constexpr span<typename Container::value_type>
1714make_span( with_container_t, Container & cont ) span_noexcept
1715{
1716 return span< typename Container::value_type >( with_container, cont );
1717}
1718
1719template< class Container >
1720inline span_constexpr span<const typename Container::value_type>
1721make_span( with_container_t, Container const & cont ) span_noexcept
1722{
1723 return span< const typename Container::value_type >( with_container, cont );
1724}
1725
1726#endif // ! span_USES_STD_SPAN && span_FEATURE( WITH_CONTAINER )
1727
1728// extensions: non-member views:
1729// this feature implies the presence of make_span()
1730
1731#if span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_SPAN )
1732
1733template< extent_t Count, class T, extent_t Extent >
1734span_constexpr span<T, Count>
1735first( span<T, Extent> spn )
1736{
1737 return spn.template first<Count>();
1738}
1739
1740template< class T, extent_t Extent >
1741span_constexpr span<T>
1742first( span<T, Extent> spn, size_t count )
1743{
1744 return spn.first( count );
1745}
1746
1747template< extent_t Count, class T, extent_t Extent >
1748span_constexpr span<T, Count>
1749last( span<T, Extent> spn )
1750{
1751 return spn.template last<Count>();
1752}
1753
1754template< class T, extent_t Extent >
1755span_constexpr span<T>
1756last( span<T, Extent> spn, size_t count )
1757{
1758 return spn.last( count );
1759}
1760
1761template< size_t Offset, extent_t Count, class T, extent_t Extent >
1762span_constexpr span<T, Count>
1763subspan( span<T, Extent> spn )
1764{
1765 return spn.template subspan<Offset, Count>();
1766}
1767
1768template< class T, extent_t Extent >
1769span_constexpr span<T>
1770subspan( span<T, Extent> spn, size_t offset, extent_t count = dynamic_extent )
1771{
1772 return spn.subspan( offset, count );
1773}
1774
1775#endif // span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_SPAN )
1776
1777#if span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_CONTAINER ) && span_CPP11_120
1778
1779template< extent_t Count, class T >
1780span_constexpr auto
1781first( T & t ) -> decltype( make_span(t).template first<Count>() )
1782{
1783 return make_span( t ).template first<Count>();
1784}
1785
1786template< class T >
1787span_constexpr auto
1788first( T & t, size_t count ) -> decltype( make_span(t).first(count) )
1789{
1790 return make_span( t ).first( count );
1791}
1792
1793template< extent_t Count, class T >
1794span_constexpr auto
1795last( T & t ) -> decltype( make_span(t).template last<Count>() )
1796{
1797 return make_span(t).template last<Count>();
1798}
1799
1800template< class T >
1801span_constexpr auto
1802last( T & t, extent_t count ) -> decltype( make_span(t).last(count) )
1803{
1804 return make_span( t ).last( count );
1805}
1806
1807template< size_t Offset, extent_t Count = dynamic_extent, class T >
1808span_constexpr auto
1809subspan( T & t ) -> decltype( make_span(t).template subspan<Offset, Count>() )
1810{
1811 return make_span( t ).template subspan<Offset, Count>();
1812}
1813
1814template< class T >
1815span_constexpr auto
1816subspan( T & t, size_t offset, extent_t count = dynamic_extent ) -> decltype( make_span(t).subspan(offset, count) )
1817{
1818 return make_span( t ).subspan( offset, count );
1819}
1820
1821#endif // span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_CONTAINER )
1822
1823} // namespace span_lite
1824} // namespace nonstd
1825
1826// make available in nonstd:
1827
1828namespace nonstd {
1829using span_lite::make_span;
1830
1831#if span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_SPAN ) || ( span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_CONTAINER ) && span_CPP11_120 )
1832
1833using span_lite::first;
1834using span_lite::last;
1835using span_lite::subspan;
1836
1837#endif // span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_[SPAN|CONTAINER] )
1838
1839} // namespace nonstd
1840
1841#endif // #if span_FEATURE_TO_STD( MAKE_SPAN )
1842
1843#if span_CPP11_OR_GREATER && span_FEATURE( BYTE_SPAN ) && ( span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE ) )
1844
1845namespace nonstd {
1846namespace span_lite {
1847
1848template< class T >
1849inline span_constexpr auto
1850byte_span( T & t ) span_noexcept -> span< std17::byte, span_sizeof(T) >
1851{
1852 return span< std17::byte, span_sizeof(t) >( reinterpret_cast< std17::byte * >( &t ), span_sizeof(T) );
1853}
1854
1855template< class T >
1856inline span_constexpr auto
1857byte_span( T const & t ) span_noexcept -> span< const std17::byte, span_sizeof(T) >
1858{
1859 return span< const std17::byte, span_sizeof(t) >( reinterpret_cast< std17::byte const * >( &t ), span_sizeof(T) );
1860}
1861
1862} // namespace span_lite
1863} // namespace nonstd
1864
1865// make available in nonstd:
1866
1867namespace nonstd {
1868using span_lite::byte_span;
1869} // namespace nonstd
1870
1871#endif // span_FEATURE( BYTE_SPAN )
1872
f90b6191 1873#if !span_USES_STD_SPAN && span_HAVE( STRUCT_BINDING )
30586bf0
PP
1874
1875#if span_CPP14_OR_GREATER
1876# include <tuple>
1877#elif span_CPP11_OR_GREATER
1878# include <tuple>
1879namespace std {
1880 template< std::size_t I, typename T >
1881 using tuple_element_t = typename tuple_element<I, T>::type;
1882}
1883#else
1884namespace std {
1885 template< typename T >
1886 class tuple_size; /*undefined*/
1887
1888 template< std::size_t I, typename T >
1889 class tuple_element; /* undefined */
1890}
1891#endif // span_CPP14_OR_GREATER
1892
1893namespace std {
1894
1895// 26.7.X Tuple interface
1896
1897// std::tuple_size<>:
1898
1899template< typename ElementType, nonstd::span_lite::extent_t Extent >
1900class tuple_size< nonstd::span<ElementType, Extent> > : public integral_constant<size_t, static_cast<size_t>(Extent)> {};
1901
1902// std::tuple_size<>: Leave undefined for dynamic extent:
1903
1904template< typename ElementType >
1905class tuple_size< nonstd::span<ElementType, nonstd::dynamic_extent> >;
1906
1907// std::tuple_element<>:
1908
1909template< size_t I, typename ElementType, nonstd::span_lite::extent_t Extent >
1910class tuple_element< I, nonstd::span<ElementType, Extent> >
1911{
1912public:
1913#if span_HAVE( STATIC_ASSERT )
1914 static_assert( Extent != nonstd::dynamic_extent && I < Extent, "tuple_element<I,span>: dynamic extent or index out of range" );
1915#endif
1916 using type = ElementType;
1917};
1918
1919// std::get<>(), 2 variants:
1920
1921template< size_t I, typename ElementType, nonstd::span_lite::extent_t Extent >
1922span_constexpr ElementType & get( nonstd::span<ElementType, Extent> & spn ) span_noexcept
1923{
1924#if span_HAVE( STATIC_ASSERT )
1925 static_assert( Extent != nonstd::dynamic_extent && I < Extent, "get<>(span): dynamic extent or index out of range" );
1926#endif
1927 return spn[I];
1928}
1929
1930template< size_t I, typename ElementType, nonstd::span_lite::extent_t Extent >
1931span_constexpr ElementType const & get( nonstd::span<ElementType, Extent> const & spn ) span_noexcept
1932{
1933#if span_HAVE( STATIC_ASSERT )
1934 static_assert( Extent != nonstd::dynamic_extent && I < Extent, "get<>(span): dynamic extent or index out of range" );
1935#endif
1936 return spn[I];
1937}
1938
1939} // end namespace std
1940
f90b6191 1941#endif // !span_USES_STD_SPAN && span_HAVE( STRUCT_BINDING )
30586bf0
PP
1942
1943#if ! span_USES_STD_SPAN
1944span_RESTORE_WARNINGS()
1945#endif // span_USES_STD_SPAN
1946
1947#endif // NONSTD_SPAN_HPP_INCLUDED
This page took 0.101772 seconds and 4 git commands to generate.