span.hpp
Go to the documentation of this file.
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-2019 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 5
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 #ifndef span_CONFIG_SELECT_SPAN
30 # define span_CONFIG_SELECT_SPAN ( span_HAVE_STD_SPAN ? span_SPAN_STD : span_SPAN_NONSTD )
31 #endif
32 
33 #ifndef span_CONFIG_INDEX_TYPE
34 # define span_CONFIG_INDEX_TYPE std::ptrdiff_t
35 #endif
36 
37 // span configuration (features):
38 
39 #ifndef span_FEATURE_WITH_CONTAINER
40 #ifdef span_FEATURE_WITH_CONTAINER_TO_STD
41 # define span_FEATURE_WITH_CONTAINER span_IN_STD( span_FEATURE_WITH_CONTAINER_TO_STD )
42 #else
43 # define span_FEATURE_WITH_CONTAINER 0
44 #endif
45 #endif
46 
47 #ifndef span_FEATURE_CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE
48 # define span_FEATURE_CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE 0
49 #endif
50 
51 #ifndef span_FEATURE_MEMBER_AT
52 # define span_FEATURE_MEMBER_AT 0
53 #endif
54 
55 #ifndef span_FEATURE_MEMBER_BACK_FRONT
56 # define span_FEATURE_MEMBER_BACK_FRONT 1
57 #endif
58 
59 #ifndef span_FEATURE_MEMBER_CALL_OPERATOR
60 # define span_FEATURE_MEMBER_CALL_OPERATOR 0
61 #endif
62 
63 #ifndef span_FEATURE_MEMBER_SWAP
64 # define span_FEATURE_MEMBER_SWAP 0
65 #endif
66 
67 #ifndef span_FEATURE_NON_MEMBER_FIRST_LAST_SUB
68 # define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB 0
69 #endif
70 
71 #ifndef span_FEATURE_COMPARISON
72 # define span_FEATURE_COMPARISON 1 // Note: C++20 does not provide comparison
73 #endif
74 
75 #ifndef span_FEATURE_SAME
76 # define span_FEATURE_SAME 0
77 #endif
78 
79 #ifndef span_FEATURE_MAKE_SPAN
80 #ifdef span_FEATURE_MAKE_SPAN_TO_STD
81 # define span_FEATURE_MAKE_SPAN span_IN_STD( span_FEATURE_MAKE_SPAN_TO_STD )
82 #else
83 # define span_FEATURE_MAKE_SPAN 0
84 #endif
85 #endif
86 
87 #ifndef span_FEATURE_BYTE_SPAN
88 # define span_FEATURE_BYTE_SPAN 0
89 #endif
90 
91 // Control presence of exception handling (try and auto discover):
92 
93 #ifndef span_CONFIG_NO_EXCEPTIONS
94 # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
95 # define span_CONFIG_NO_EXCEPTIONS 0
96 # else
97 # define span_CONFIG_NO_EXCEPTIONS 1
98 # undef span_CONFIG_CONTRACT_VIOLATION_THROWS
99 # undef span_CONFIG_CONTRACT_VIOLATION_TERMINATES
100 # define span_CONFIG_CONTRACT_VIOLATION_THROWS 0
101 # define span_CONFIG_CONTRACT_VIOLATION_TERMINATES 1
102 # endif
103 #endif
104 
105 // Control pre- and postcondition violation behaviour:
106 
107 #if defined( span_CONFIG_CONTRACT_LEVEL_ON )
108 # define span_CONFIG_CONTRACT_LEVEL_MASK 0x11
109 #elif defined( span_CONFIG_CONTRACT_LEVEL_OFF )
110 # define span_CONFIG_CONTRACT_LEVEL_MASK 0x00
111 #elif defined( span_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY )
112 # define span_CONFIG_CONTRACT_LEVEL_MASK 0x01
113 #elif defined( span_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY )
114 # define span_CONFIG_CONTRACT_LEVEL_MASK 0x10
115 #else
116 # define span_CONFIG_CONTRACT_LEVEL_MASK 0x11
117 #endif
118 
119 #if defined( span_CONFIG_CONTRACT_VIOLATION_THROWS )
120 # define span_CONFIG_CONTRACT_VIOLATION_THROWS_V span_CONFIG_CONTRACT_VIOLATION_THROWS
121 #else
122 # define span_CONFIG_CONTRACT_VIOLATION_THROWS_V 0
123 #endif
124 
125 #if defined( span_CONFIG_CONTRACT_VIOLATION_THROWS ) && span_CONFIG_CONTRACT_VIOLATION_THROWS && \
126  defined( span_CONFIG_CONTRACT_VIOLATION_TERMINATES ) && span_CONFIG_CONTRACT_VIOLATION_TERMINATES
127 # error Please define none or one of span_CONFIG_CONTRACT_VIOLATION_THROWS and span_CONFIG_CONTRACT_VIOLATION_TERMINATES to 1, but not both.
128 #endif
129 
130 // C++ language version detection (C++20 is speculative):
131 // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
132 
133 #ifndef span_CPLUSPLUS
134 # if defined(_MSVC_LANG ) && !defined(__clang__)
135 # define span_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
136 # else
137 # define span_CPLUSPLUS __cplusplus
138 # endif
139 #endif
140 
141 #define span_CPP98_OR_GREATER ( span_CPLUSPLUS >= 199711L )
142 #define span_CPP11_OR_GREATER ( span_CPLUSPLUS >= 201103L )
143 #define span_CPP14_OR_GREATER ( span_CPLUSPLUS >= 201402L )
144 #define span_CPP17_OR_GREATER ( span_CPLUSPLUS >= 201703L )
145 #define span_CPP20_OR_GREATER ( span_CPLUSPLUS >= 202000L )
146 
147 // C++ language version (represent 98 as 3):
148 
149 #define span_CPLUSPLUS_V ( span_CPLUSPLUS / 100 - (span_CPLUSPLUS > 200000 ? 2000 : 1994) )
150 
151 #define span_IN_STD( v ) ( ((v) == 98 ? 3 : (v)) >= span_CPLUSPLUS_V )
152 
153 #define span_CONFIG( feature ) ( span_CONFIG_##feature )
154 #define span_FEATURE( feature ) ( span_FEATURE_##feature )
155 #define span_FEATURE_TO_STD( feature ) ( span_IN_STD( span_FEATURE( feature##_TO_STD ) ) )
156 
157 // Use C++20 std::span if available and requested:
158 
159 #if span_CPP20_OR_GREATER && defined(__has_include )
160 # if __has_include( <span> )
161 # define span_HAVE_STD_SPAN 1
162 # else
163 # define span_HAVE_STD_SPAN 0
164 # endif
165 #else
166 # define span_HAVE_STD_SPAN 0
167 #endif
168 
169 #define span_USES_STD_SPAN ( (span_CONFIG_SELECT_SPAN == span_SPAN_STD) || ((span_CONFIG_SELECT_SPAN == span_SPAN_DEFAULT) && span_HAVE_STD_SPAN) )
170 
171 //
172 // Use C++20 std::span:
173 //
174 
175 #if span_USES_STD_SPAN
176 
177 #include <span>
178 
179 namespace nonstd {
180 
181 using std::span;
182 
183 // Note: C++20 does not provide comparison
184 // using std::operator==;
185 // using std::operator!=;
186 // using std::operator<;
187 // using std::operator<=;
188 // using std::operator>;
189 // using std::operator>=;
190 } // namespace nonstd
191 
192 #else // span_USES_STD_SPAN
193 
194 #include <algorithm>
195 
196 // Compiler versions:
197 //
198 // MSVC++ 6.0 _MSC_VER == 1200 (Visual Studio 6.0)
199 // MSVC++ 7.0 _MSC_VER == 1300 (Visual Studio .NET 2002)
200 // MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio .NET 2003)
201 // MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
202 // MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
203 // MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
204 // MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
205 // MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
206 // MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
207 // MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017)
208 
209 #if defined(_MSC_VER ) && !defined(__clang__)
210 # define span_COMPILER_MSVC_VER (_MSC_VER )
211 # define span_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
212 #else
213 # define span_COMPILER_MSVC_VER 0
214 # define span_COMPILER_MSVC_VERSION 0
215 #endif
216 
217 #define span_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
218 
219 #if defined(__clang__)
220 # define span_COMPILER_CLANG_VERSION span_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
221 #else
222 # define span_COMPILER_CLANG_VERSION 0
223 #endif
224 
225 #if defined(__GNUC__) && !defined(__clang__)
226 # define span_COMPILER_GNUC_VERSION span_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
227 #else
228 # define span_COMPILER_GNUC_VERSION 0
229 #endif
230 
231 // half-open range [lo..hi):
232 #define span_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
233 
234 // Compiler warning suppression:
235 
236 #if defined(__clang__)
237 # pragma clang diagnostic push
238 # pragma clang diagnostic ignored "-Wundef"
239 # define span_RESTORE_WARNINGS() _Pragma( "clang diagnostic pop" )
240 
241 #elif defined __GNUC__
242 # pragma GCC diagnostic push
243 # pragma GCC diagnostic ignored "-Wundef"
244 # define span_RESTORE_WARNINGS() _Pragma( "GCC diagnostic pop" )
245 
246 #elif span_COMPILER_MSVC_VERSION >= 140
247 # define span_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes))
248 # define span_RESTORE_WARNINGS() __pragma(warning(pop ))
249 
250 // Suppress the following MSVC GSL warnings:
251 // - C26439, gsl::f.6 : special function 'function' can be declared 'noexcept'
252 // - C26440, gsl::f.6 : function 'function' can be declared 'noexcept'
253 // - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
254 // use brace initialization, gsl::narrow_cast or gsl::narrow
255 // - C26473: gsl::t.1 : don't cast between pointer types where the source type and the target type are the same
256 // - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
257 // - C26490: gsl::t.1 : don't use reinterpret_cast
258 
259 span_DISABLE_MSVC_WARNINGS( 26439 26440 26472 26473 26481 26490 )
260 
261 #else
262 # define span_RESTORE_WARNINGS() /*empty*/
263 #endif
264 
265 // Presence of language and library features:
266 
267 #define span_HAVE( feature ) ( span_HAVE_##feature )
268 
269 #ifdef _HAS_CPP0X
270 # define span_HAS_CPP0X _HAS_CPP0X
271 #else
272 # define span_HAS_CPP0X 0
273 #endif
274 
275 #define span_CPP11_80 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1400)
276 #define span_CPP11_90 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1500)
277 #define span_CPP11_100 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1600)
278 #define span_CPP11_110 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1700)
279 #define span_CPP11_120 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1800)
280 #define span_CPP11_140 (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1900)
281 
282 #define span_CPP14_000 (span_CPP14_OR_GREATER)
283 #define span_CPP14_120 (span_CPP14_OR_GREATER || span_COMPILER_MSVC_VER >= 1800)
284 #define span_CPP14_140 (span_CPP14_OR_GREATER || span_COMPILER_MSVC_VER >= 1900)
285 
286 #define span_CPP17_000 (span_CPP17_OR_GREATER)
287 
288 // Presence of C++11 language features:
289 
290 #define span_HAVE_ALIAS_TEMPLATE span_CPP11_140
291 #define span_HAVE_AUTO span_CPP11_100
292 #define span_HAVE_CONSTEXPR_11 span_CPP11_140
293 #define span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG span_CPP11_120
294 #define span_HAVE_EXPLICIT_CONVERSION span_CPP11_140
295 #define span_HAVE_INITIALIZER_LIST span_CPP11_120
296 #define span_HAVE_IS_DEFAULT span_CPP11_140
297 #define span_HAVE_IS_DELETE span_CPP11_140
298 #define span_HAVE_NOEXCEPT span_CPP11_140
299 #define span_HAVE_NULLPTR span_CPP11_100
300 #define span_HAVE_STATIC_ASSERT span_CPP11_100
301 
302 // Presence of C++14 language features:
303 
304 #define span_HAVE_CONSTEXPR_14 span_CPP14_000
305 
306 // Presence of C++17 language features:
307 
308 #define span_HAVE_DEPRECATED span_CPP17_000
309 #define span_HAVE_NODISCARD span_CPP17_000
310 #define span_HAVE_NORETURN span_CPP17_000
311 
312 // MSVC: template parameter deduction guides since Visual Studio 2017 v15.7
313 
314 #define span_HAVE_DEDUCTION_GUIDES (span_CPP17_OR_GREATER && ! span_BETWEEN( span_COMPILER_MSVC_VERSION, 1, 999 ))
315 
316 // Presence of C++ library features:
317 
318 #define span_HAVE_ADDRESSOF span_CPP17_000
319 #define span_HAVE_ARRAY span_CPP11_110
320 #define span_HAVE_BYTE span_CPP17_000
321 #define span_HAVE_CONDITIONAL span_CPP11_120
322 #define span_HAVE_CONTAINER_DATA_METHOD (span_CPP11_140 || ( span_COMPILER_MSVC_VERSION >= 90 && span_HAS_CPP0X ))
323 #define span_HAVE_DATA span_CPP17_000
324 #define span_HAVE_LONGLONG span_CPP11_80
325 #define span_HAVE_REMOVE_CONST span_CPP11_110
326 #define span_HAVE_SNPRINTF span_CPP11_140
327 #define span_HAVE_TYPE_TRAITS span_CPP11_90
328 
329 // Presence of byte-lite:
330 
331 #ifdef NONSTD_BYTE_LITE_HPP
332 # define span_HAVE_NONSTD_BYTE 1
333 #else
334 # define span_HAVE_NONSTD_BYTE 0
335 #endif
336 
337 // C++ feature usage:
338 
339 #if span_HAVE_ADDRESSOF
340 # define span_ADDRESSOF(x) std::addressof(x)
341 #else
342 # define span_ADDRESSOF(x) (&x)
343 #endif
344 
345 #if span_HAVE_CONSTEXPR_11
346 # define span_constexpr constexpr
347 #else
348 # define span_constexpr /*span_constexpr*/
349 #endif
350 
351 #if span_HAVE_CONSTEXPR_14
352 # define span_constexpr14 constexpr
353 #else
354 # define span_constexpr14 /*span_constexpr*/
355 #endif
356 
357 #if span_HAVE_EXPLICIT_CONVERSION
358 # define span_explicit explicit
359 #else
360 # define span_explicit /*explicit*/
361 #endif
362 
363 #if span_HAVE_IS_DELETE
364 # define span_is_delete = delete
365 #else
366 # define span_is_delete
367 #endif
368 
369 #if span_HAVE_IS_DELETE
370 # define span_is_delete_access public
371 #else
372 # define span_is_delete_access private
373 #endif
374 
375 #if span_HAVE_NOEXCEPT && ! span_CONFIG_CONTRACT_VIOLATION_THROWS_V
376 # define span_noexcept noexcept
377 #else
378 # define span_noexcept /*noexcept*/
379 #endif
380 
381 #if span_HAVE_NULLPTR
382 # define span_nullptr nullptr
383 #else
384 # define span_nullptr NULL
385 #endif
386 
387 #if span_HAVE_DEPRECATED
388 # define span_deprecated(msg) [[deprecated(msg)]]
389 #else
390 # define span_deprecated(msg) /*[[deprecated]]*/
391 #endif
392 
393 #if span_HAVE_NODISCARD
394 # define span_nodiscard [[nodiscard]]
395 #else
396 # define span_nodiscard /*[[nodiscard]]*/
397 #endif
398 
399 #if span_HAVE_NORETURN
400 # define span_noreturn [[noreturn]]
401 #else
402 # define span_noreturn /*[[noreturn]]*/
403 #endif
404 
405 // Other features:
406 
407 #define span_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
408 
409 // Additional includes:
410 
411 #if span_HAVE( ADDRESSOF )
412 # include <memory>
413 #endif
414 
415 #if span_HAVE( ARRAY )
416 # include <array>
417 #endif
418 
419 #if span_HAVE( BYTE )
420 # include <cstddef>
421 #endif
422 
423 #if span_HAVE( DATA )
424 # include <iterator> // for std::data(), std::size()
425 #endif
426 
427 #if span_HAVE( TYPE_TRAITS )
428 # include <type_traits>
429 #endif
430 
431 #if ! span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
432 # include <vector>
433 #endif
434 
435 #if span_FEATURE( MEMBER_AT ) > 1
436 # include <cstdio>
437 #endif
438 
439 #if span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
440 # include <stdexcept>
441 #endif
442 
443 // Contract violation
444 
445 #define span_ELIDE_CONTRACT_EXPECTS ( 0 == ( span_CONFIG_CONTRACT_LEVEL_MASK & 0x01 ) )
446 #define span_ELIDE_CONTRACT_ENSURES ( 0 == ( span_CONFIG_CONTRACT_LEVEL_MASK & 0x10 ) )
447 
448 #if span_ELIDE_CONTRACT_EXPECTS
449 # define span_constexpr_exp span_constexpr
450 # define span_EXPECTS( cond ) /* Expect elided */
451 #else
452 # define span_constexpr_exp span_constexpr14
453 # define span_EXPECTS( cond ) span_CONTRACT_CHECK( "Precondition", cond )
454 #endif
455 
456 #if span_ELIDE_CONTRACT_ENSURES
457 # define span_constexpr_ens span_constexpr
458 # define span_ENSURES( cond ) /* Ensures elided */
459 #else
460 # define span_constexpr_ens span_constexpr14
461 # define span_ENSURES( cond ) span_CONTRACT_CHECK( "Postcondition", cond )
462 #endif
463 
464 #define span_CONTRACT_CHECK( type, cond ) \
465  cond ? static_cast< void >( 0 ) \
466  : nonstd::span_lite::detail::report_contract_violation( span_LOCATION( __FILE__, __LINE__ ) ": " type " violation." )
467 
468 #ifdef __GNUG__
469 # define span_LOCATION( file, line ) file ":" span_STRINGIFY( line )
470 #else
471 # define span_LOCATION( file, line ) file "(" span_STRINGIFY( line ) ")"
472 #endif
473 
474 // Method enabling
475 
476 #define span_REQUIRES_0(VA) \
477  template< bool B = (VA), typename std::enable_if<B, int>::type = 0 >
478 
479 #define span_REQUIRES_T(VA) \
480  , typename = typename std::enable_if< (VA), nonstd::span_lite::detail::enabler >::type
481 
482 #define span_REQUIRES_R(R, VA) \
483  typename std::enable_if< (VA), R>::type
484 
485 #define span_REQUIRES_A(VA) \
486  , typename std::enable_if< (VA), void*>::type = nullptr
487 
488 namespace nonstd {
489 namespace span_lite {
490 
491 // [views.constants], constants
492 
494 
495 typedef std::ptrdiff_t extent_t;
496 
497 span_constexpr const extent_t dynamic_extent = -1;
498 
499 template< class T, extent_t Extent = dynamic_extent >
500 class span;
501 
502 // Tag to select span constructor taking a container (prevent ms-gsl warning C26426):
503 
506 
507 // C++11 emulation:
508 
509 namespace std11 {
510 
511 #if span_HAVE( REMOVE_CONST )
512 
513 using std::remove_cv;
514 using std::remove_const;
515 using std::remove_volatile;
516 
517 #else
518 
519 template< class T > struct remove_const { typedef T type; };
520 template< class T > struct remove_const< T const > { typedef T type; };
521 
522 template< class T > struct remove_volatile { typedef T type; };
523 template< class T > struct remove_volatile< T volatile > { typedef T type; };
524 
525 template< class T >
526 struct remove_cv
527 {
529 };
530 
531 #endif // span_HAVE( REMOVE_CONST )
532 
533 #if span_HAVE( TYPE_TRAITS )
534 
535 using std::is_same;
536 using std::integral_constant;
537 using std::true_type;
538 using std::false_type;
539 
540 #else
541 
542 template< class T, T v > struct integral_constant { enum { value = v }; };
545 
546 template< class T, class U > struct is_same : false_type{};
547 template< class T > struct is_same<T, T> : true_type{};
548 
549 #endif
550 
551 } // namespace std11
552 
553 // C++17 emulation:
554 
555 namespace std17 {
556 
557 template< bool v > struct bool_constant : std11::integral_constant<bool, v>{};
558 
559 #if span_CPP11_120
560 
561 template< class...>
562 using void_t = void;
563 
564 #endif
565 
566 #if span_HAVE( DATA )
567 
568 using std::data;
569 using std::size;
570 
571 #elif span_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR
572 
573 template< typename T, size_t N >
574 inline span_constexpr auto size( const T(&)[N] ) span_noexcept -> size_t
575 {
576  return N;
577 }
578 
579 template< typename C >
580 inline span_constexpr auto size( C const & cont ) -> decltype( cont.size() )
581 {
582  return cont.size();
583 }
584 
585 template< typename T, size_t N >
586 inline span_constexpr auto data( T(&arr)[N] ) span_noexcept -> T*
587 {
588  return &arr[0];
589 }
590 
591 template< typename C >
592 inline span_constexpr auto data( C & cont ) -> decltype( cont.data() )
593 {
594  return cont.data();
595 }
596 
597 template< typename C >
598 inline span_constexpr auto data( C const & cont ) -> decltype( cont.data() )
599 {
600  return cont.data();
601 }
602 
603 template< typename E >
604 inline span_constexpr auto data( std::initializer_list<E> il ) span_noexcept -> E const *
605 {
606  return il.begin();
607 }
608 
609 #endif // span_HAVE( DATA )
610 
611 #if span_HAVE( BYTE )
612 using std::byte;
613 #elif span_HAVE( NONSTD_BYTE )
614 using nonstd::byte;
615 #endif
616 
617 } // namespace std17
618 
619 // Implementation details:
620 
621 namespace detail {
622 
623 /*enum*/ struct enabler{};
624 
625 #if span_HAVE( TYPE_TRAITS )
626 
627 template< class Q >
628 struct is_span_oracle : std::false_type{};
629 
630 template< class T, std::ptrdiff_t Extent >
631 struct is_span_oracle< span<T, Extent> > : std::true_type{};
632 
633 template< class Q >
634 struct is_span : is_span_oracle< typename std::remove_cv<Q>::type >{};
635 
636 template< class Q >
637 struct is_std_array_oracle : std::false_type{};
638 
639 #if span_HAVE( ARRAY )
640 
641 template< class T, std::size_t Extent >
642 struct is_std_array_oracle< std::array<T, Extent> > : std::true_type{};
643 
644 #endif
645 
646 template< class Q >
647 struct is_std_array : is_std_array_oracle< typename std::remove_cv<Q>::type >{};
648 
649 template< class Q >
650 struct is_array : std::false_type {};
651 
652 template< class T >
653 struct is_array<T[]> : std::true_type {};
654 
655 template< class T, std::size_t N >
656 struct is_array<T[N]> : std::true_type {};
657 
658 #if span_CPP11_140 && ! span_BETWEEN( span_COMPILER_GNUC_VERSION, 1, 500 )
659 
660 template< class, class = void >
661 struct has_size_and_data : std::false_type{};
662 
663 template< class C >
664 struct has_size_and_data
665  <
666  C, std17::void_t<
667  decltype( std17::size(std::declval<C>()) ),
668  decltype( std17::data(std::declval<C>()) ) >
669  > : std::true_type{};
670 
671 template< class, class, class = void >
672 struct is_compatible_element : std::false_type {};
673 
674 template< class C, class E >
675 struct is_compatible_element
676  <
677  C, E, std17::void_t<
678  decltype( std17::data(std::declval<C>()) ) >
679  > : std::is_convertible< typename std::remove_pointer<decltype( std17::data( std::declval<C&>() ) )>::type(*)[], E(*)[] >{};
680 
681 template< class C >
682 struct is_container : std17::bool_constant
683  <
684  ! is_span< C >::value
685  && ! is_array< C >::value
686  && ! is_std_array< C >::value
687  && has_size_and_data< C >::value
688  >{};
689 
690 template< class C, class E >
691 struct is_compatible_container : std17::bool_constant
692  <
693  is_container<C>::value
694  && is_compatible_element<C,E>::value
695  >{};
696 
697 #else // span_CPP11_140
698 
699 template<
700  class C, class E
702  ! is_span< C >::value
703  && ! is_array< C >::value
704  && ! is_std_array< C >::value
705  && ( std::is_convertible< typename std::remove_pointer<decltype( std17::data( std::declval<C&>() ) )>::type(*)[], E(*)[] >::value)
706  // && has_size_and_data< C >::value
707  ))
708  , class = decltype( std17::size(std::declval<C>()) )
709  , class = decltype( std17::data(std::declval<C>()) )
710  >
711 struct is_compatible_container : std::true_type{};
712 
713 #endif // span_CPP11_140
714 
715 #endif // span_HAVE( TYPE_TRAITS )
716 
717 #if ! span_CONFIG( NO_EXCEPTIONS )
718 #if span_FEATURE( MEMBER_AT ) > 1
719 
720 // format index and size:
721 
722 #if defined(__clang__)
723 # pragma clang diagnostic ignored "-Wlong-long"
724 #elif defined __GNUC__
725 # pragma GCC diagnostic ignored "-Wformat=ll"
726 # pragma GCC diagnostic ignored "-Wlong-long"
727 #endif
728 
729 inline void throw_out_of_range( index_t idx, index_t size )
730 {
731  const char fmt[] = "span::at(): index '%lli' is out of range [0..%lli)";
732  char buffer[ 2 * 20 + sizeof fmt ];
733  sprintf( buffer, fmt, static_cast<long long>(idx), static_cast<long long>(size) );
734 
735  throw std::out_of_range( buffer );
736 }
737 
738 #else // MEMBER_AT
739 
740 inline void throw_out_of_range( index_t /*idx*/, index_t /*size*/ )
741 {
742  throw std::out_of_range( "span::at(): index outside span" );
743 }
744 #endif // MEMBER_AT
745 #endif // NO_EXCEPTIONS
746 
747 #if span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
748 
749 struct contract_violation : std::logic_error
750 {
751  explicit contract_violation( char const * const message )
752  : std::logic_error( message )
753  {}
754 };
755 
756 inline void report_contract_violation( char const * msg )
757 {
758  throw contract_violation( msg );
759 }
760 
761 #else // span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
762 
763 span_noreturn inline void report_contract_violation( char const * /*msg*/ ) span_noexcept
764 {
765  std::terminate();
766 }
767 
768 #endif // span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
769 
770 } // namespace detail
771 
772 // Prevent signed-unsigned mismatch:
773 
774 #define span_sizeof(T) static_cast<extent_t>( sizeof(T) )
775 
776 template< class T >
777 inline span_constexpr index_t to_size( T size )
778 {
779  return static_cast<index_t>( size );
780 }
781 
782 //
783 // [views.span] - A view over a contiguous, single-dimension sequence of objects
784 //
785 template< class T, extent_t Extent /*= dynamic_extent*/ >
786 class span
787 {
788 public:
789  // constants and types
790 
791  typedef T element_type;
793 
794  typedef T & reference;
795  typedef T * pointer;
796  typedef T const * const_pointer;
797  typedef T const & const_reference;
798 
799  typedef index_t index_type;
800  typedef extent_t extent_type;
801 
802  typedef pointer iterator;
803  typedef const_pointer const_iterator;
804 
805  typedef std::ptrdiff_t difference_type;
806 
807  typedef std::reverse_iterator< iterator > reverse_iterator;
808  typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
809 
810  // static constexpr extent_type extent = Extent;
811  enum { extent = Extent };
812 
813  // 26.7.3.2 Constructors, copy, and assignment [span.cons]
814 
815 #if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
816  span_REQUIRES_0(( Extent <= 0 ))
817 #endif
819  : data_( span_nullptr )
820  , size_( 0 )
821  {
822  // span_EXPECTS( data() == span_nullptr );
823  // span_EXPECTS( size() == 0 );
824  }
825 
826  span_constexpr_exp span( pointer ptr, index_type count )
827  : data_( ptr )
828  , size_( count )
829  {
830  span_EXPECTS(
831  ( ptr == span_nullptr && count == 0 ) ||
832  ( ptr != span_nullptr && count >= 0 )
833  );
834  }
835 
836  span_constexpr_exp span( pointer firstElem, pointer lastElem )
837  : data_( firstElem )
838  , size_( to_size( std::distance( firstElem, lastElem ) ) )
839  {
840  span_EXPECTS(
841  std::distance( firstElem, lastElem ) >= 0
842  );
843  }
844 
845  template< size_t N
846 #if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
848  (Extent == dynamic_extent || Extent == static_cast<extent_t>(N))
849  && std::is_convertible< value_type(*)[], element_type(*)[] >::value
850  ))
851 #endif
852  >
853  span_constexpr span( element_type ( &arr )[ N ] ) span_noexcept
854  : data_( span_ADDRESSOF( arr[0] ) )
855  , size_( N )
856  {}
857 
858 #if span_HAVE( ARRAY )
859 
860  template< size_t N
861 # if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
863  (Extent == dynamic_extent || Extent == static_cast<extent_t>(N))
864  && std::is_convertible< value_type(*)[], element_type(*)[] >::value
865  ))
866 # endif
867  >
868 # if span_FEATURE( CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE )
869  span_constexpr span( std::array< element_type, N > & arr ) span_noexcept
870 # else
871  span_constexpr span( std::array< value_type, N > & arr ) span_noexcept
872 # endif
873  : data_( span_ADDRESSOF( arr[0] ) )
874  , size_( to_size( arr.size() ) )
875  {}
876 
877  template< size_t N
878 # if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
880  (Extent == dynamic_extent || Extent == static_cast<extent_t>(N))
881  && std::is_convertible< value_type(*)[], element_type(*)[] >::value
882  ))
883 # endif
884  >
885  span_constexpr span( std::array< value_type, N> const & arr ) span_noexcept
886  : data_( span_ADDRESSOF( arr[0] ) )
887  , size_( to_size( arr.size() ) )
888  {}
889 
890 #endif // span_HAVE( ARRAY )
891 
892 #if span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
893  template< class Container
895  detail::is_compatible_container< Container, element_type >::value
896  ))
897  >
898  span_constexpr span( Container & cont )
899  : data_( std17::data( cont ) )
900  , size_( to_size( std17::size( cont ) ) )
901  {}
902 
903  template< class Container
905  std::is_const< element_type >::value
906  && detail::is_compatible_container< Container, element_type >::value
907  ))
908  >
909  span_constexpr span( Container const & cont )
910  : data_( std17::data( cont ) )
911  , size_( to_size( std17::size( cont ) ) )
912  {}
913 
914 #endif // span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
915 
916 #if span_FEATURE( WITH_CONTAINER )
917 
918  template< class Container >
919  span_constexpr span( with_container_t, Container & cont )
920  : data_( cont.size() == 0 ? span_nullptr : span_ADDRESSOF( cont[0] ) )
921  , size_( to_size( cont.size() ) )
922  {}
923 
924  template< class Container >
925  span_constexpr span( with_container_t, Container const & cont )
926  : data_( cont.size() == 0 ? span_nullptr : const_cast<pointer>( span_ADDRESSOF( cont[0] ) ) )
927  , size_( to_size( cont.size() ) )
928  {}
929 #endif
930 
931 #if span_HAVE( IS_DEFAULT )
932  span_constexpr span( span const & other ) span_noexcept = default;
933 
934  ~span() span_noexcept = default;
935 
936  span_constexpr14 span & operator=( span const & other ) span_noexcept = default;
937 #else
938  span_constexpr span( span const & other ) span_noexcept
939  : data_( other.data_ )
940  , size_( other.size_ )
941  {}
942 
943  ~span() span_noexcept
944  {}
945 
946  span_constexpr14 span & operator=( span const & other ) span_noexcept
947  {
948  data_ = other.data_;
949  size_ = other.size_;
950 
951  return *this;
952  }
953 #endif
954 
955  template< class OtherElementType, extent_type OtherExtent
956 #if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
958  (Extent == dynamic_extent || Extent == OtherExtent)
959  && std::is_convertible<OtherElementType(*)[], element_type(*)[]>::value
960  ))
961 #endif
962  >
964  : data_( reinterpret_cast<pointer>( other.data() ) )
965  , size_( other.size() )
966  {
967  span_EXPECTS( OtherExtent == dynamic_extent || other.size() == to_size(OtherExtent) );
968  }
969 
970  // 26.7.3.3 Subviews [span.sub]
971 
972  template< extent_type Count >
974  first() const
975  {
976  span_EXPECTS( 0 <= Count && Count <= size() );
977 
978  return span< element_type, Count >( data(), Count );
979  }
980 
981  template< extent_type Count >
983  last() const
984  {
985  span_EXPECTS( 0 <= Count && Count <= size() );
986 
987  return span< element_type, Count >( data() + (size() - Count), Count );
988  }
989 
990 #if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
991  template< index_type Offset, extent_type Count = dynamic_extent >
992 #else
993  template< index_type Offset, extent_type Count /*= dynamic_extent*/ >
994 #endif
996  subspan() const
997  {
998  span_EXPECTS(
999  ( 0 <= Offset && Offset <= size() ) &&
1000  ( Count == dynamic_extent || (0 <= Count && Count + Offset <= size()) )
1001  );
1002 
1004  data() + Offset, Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : size() - Offset) );
1005  }
1006 
1008  first( index_type count ) const
1009  {
1010  span_EXPECTS( 0 <= count && count <= size() );
1011 
1012  return span< element_type, dynamic_extent >( data(), count );
1013  }
1014 
1016  last( index_type count ) const
1017  {
1018  span_EXPECTS( 0 <= count && count <= size() );
1019 
1020  return span< element_type, dynamic_extent >( data() + ( size() - count ), count );
1021  }
1022 
1024  subspan( index_type offset, index_type count = static_cast<index_type>(dynamic_extent) ) const
1025  {
1026  span_EXPECTS(
1027  ( ( 0 <= offset && offset <= size() ) ) &&
1028  ( count == static_cast<index_type>(dynamic_extent) || ( 0 <= count && offset + count <= size() ) )
1029  );
1030 
1032  data() + offset, count == static_cast<index_type>(dynamic_extent) ? size() - offset : count );
1033  }
1034 
1035  // 26.7.3.4 Observers [span.obs]
1036 
1037  span_constexpr index_type size() const span_noexcept
1038  {
1039  return size_;
1040  }
1041 
1042  span_constexpr std::ptrdiff_t ssize() const span_noexcept
1043  {
1044  return static_cast<std::ptrdiff_t>( size_ );
1045  }
1046 
1047  span_constexpr index_type size_bytes() const span_noexcept
1048  {
1049  return size() * to_size( sizeof( element_type ) );
1050  }
1051 
1052  span_nodiscard span_constexpr bool empty() const span_noexcept
1053  {
1054  return size() == 0;
1055  }
1056 
1057  // 26.7.3.5 Element access [span.elem]
1058 
1059  span_constexpr_exp reference operator[]( index_type idx ) const
1060  {
1061  span_EXPECTS( 0 <= idx && idx < size() );
1062 
1063  return *( data() + idx );
1064  }
1065 
1066 #if span_FEATURE( MEMBER_CALL_OPERATOR )
1067  span_deprecated("replace operator() with operator[]")
1068 
1069  span_constexpr_exp reference operator()( index_type idx ) const
1070  {
1071  span_EXPECTS( 0 <= idx && idx < size() );
1072 
1073  return *( data() + idx );
1074  }
1075 #endif
1076 
1077 #if span_FEATURE( MEMBER_AT )
1078  span_constexpr14 reference at( index_type idx ) const
1079  {
1080 #if span_CONFIG( NO_EXCEPTIONS )
1081  return this->operator[]( idx );
1082 #else
1083  if ( idx < 0 || size() <= idx )
1084  {
1085  detail::throw_out_of_range( idx, size() );
1086  }
1087  return *( data() + idx );
1088 #endif
1089  }
1090 #endif
1091 
1092  span_constexpr pointer data() const span_noexcept
1093  {
1094  return data_;
1095  }
1096 
1097 #if span_FEATURE( MEMBER_BACK_FRONT )
1098 
1099  span_constexpr_exp reference front() const span_noexcept
1100  {
1101  span_EXPECTS( ! empty() );
1102 
1103  return *data();
1104  }
1105 
1106  span_constexpr_exp reference back() const span_noexcept
1107  {
1108  span_EXPECTS( ! empty() );
1109 
1110  return *( data() + size() - 1 );
1111  }
1112 
1113 #endif
1114 
1115  // xx.x.x.x Modifiers [span.modifiers]
1116 
1117 #if span_FEATURE( MEMBER_SWAP )
1118 
1119  span_constexpr14 void swap( span & other ) span_noexcept
1120  {
1121  using std::swap;
1122  swap( data_, other.data_ );
1123  swap( size_, other.size_ );
1124  }
1125 #endif
1126 
1127  // 26.7.3.6 Iterator support [span.iterators]
1128 
1129  span_constexpr iterator begin() const span_noexcept
1130  {
1131 #if span_CPP11_OR_GREATER
1132  return { data() };
1133 #else
1134  return iterator( data() );
1135 #endif
1136  }
1137 
1138  span_constexpr iterator end() const span_noexcept
1139  {
1140 #if span_CPP11_OR_GREATER
1141  return { data() + size() };
1142 #else
1143  return iterator( data() + size() );
1144 #endif
1145  }
1146 
1147  span_constexpr const_iterator cbegin() const span_noexcept
1148  {
1149 #if span_CPP11_OR_GREATER
1150  return { data() };
1151 #else
1152  return const_iterator( data() );
1153 #endif
1154  }
1155 
1156  span_constexpr const_iterator cend() const span_noexcept
1157  {
1158 #if span_CPP11_OR_GREATER
1159  return { data() + size() };
1160 #else
1161  return const_iterator( data() + size() );
1162 #endif
1163  }
1164 
1165  span_constexpr reverse_iterator rbegin() const span_noexcept
1166  {
1167  return reverse_iterator( end() );
1168  }
1169 
1170  span_constexpr reverse_iterator rend() const span_noexcept
1171  {
1172  return reverse_iterator( begin() );
1173  }
1174 
1175  span_constexpr const_reverse_iterator crbegin() const span_noexcept
1176  {
1177  return const_reverse_iterator ( cend() );
1178  }
1179 
1180  span_constexpr const_reverse_iterator crend() const span_noexcept
1181  {
1182  return const_reverse_iterator( cbegin() );
1183  }
1184 
1185 private:
1186  pointer data_;
1187  index_type size_;
1188 };
1189 
1190 // class template argument deduction guides:
1191 
1192 #if span_HAVE( DEDUCTION_GUIDES ) // span_CPP17_OR_GREATER
1193 
1194 template< class T, size_t N >
1195 span( T (&)[N] ) -> span<T, static_cast<extent_t>(N)>;
1196 
1197 template< class T, size_t N >
1198 span( std::array<T, N> & ) -> span<T, static_cast<extent_t>(N)>;
1199 
1200 template< class T, size_t N >
1201 span( std::array<T, N> const & ) -> span<const T, static_cast<extent_t>(N)>;
1202 
1203 template< class Container >
1204 span( Container& ) -> span<typename Container::value_type>;
1205 
1206 template< class Container >
1207 span( Container const & ) -> span<const typename Container::value_type>;
1208 
1209 #endif // span_HAVE( DEDUCTION_GUIDES )
1210 
1211 // 26.7.3.7 Comparison operators [span.comparison]
1212 
1213 #if span_FEATURE( COMPARISON )
1214 #if span_FEATURE( SAME )
1215 
1216 template< class T1, extent_t E1, class T2, extent_t E2 >
1217 inline span_constexpr bool same( span<T1,E1> const & l, span<T2,E2> const & r ) span_noexcept
1218 {
1220  && l.size() == r.size()
1221  && static_cast<void const*>( l.data() ) == r.data();
1222 }
1223 
1224 #endif
1225 
1226 template< class T1, extent_t E1, class T2, extent_t E2 >
1227 inline span_constexpr bool operator==( span<T1,E1> const & l, span<T2,E2> const & r )
1228 {
1229  return
1230 #if span_FEATURE( SAME )
1231  same( l, r ) ||
1232 #endif
1233  ( l.size() == r.size() && std::equal( l.begin(), l.end(), r.begin() ) );
1234 }
1235 
1236 template< class T1, extent_t E1, class T2, extent_t E2 >
1237 inline span_constexpr bool operator<( span<T1,E1> const & l, span<T2,E2> const & r )
1238 {
1239  return std::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() );
1240 }
1241 
1242 template< class T1, extent_t E1, class T2, extent_t E2 >
1243 inline span_constexpr bool operator!=( span<T1,E1> const & l, span<T2,E2> const & r )
1244 {
1245  return !( l == r );
1246 }
1247 
1248 template< class T1, extent_t E1, class T2, extent_t E2 >
1249 inline span_constexpr bool operator<=( span<T1,E1> const & l, span<T2,E2> const & r )
1250 {
1251  return !( r < l );
1252 }
1253 
1254 template< class T1, extent_t E1, class T2, extent_t E2 >
1255 inline span_constexpr bool operator>( span<T1,E1> const & l, span<T2,E2> const & r )
1256 {
1257  return ( r < l );
1258 }
1259 
1260 template< class T1, extent_t E1, class T2, extent_t E2 >
1261 inline span_constexpr bool operator>=( span<T1,E1> const & l, span<T2,E2> const & r )
1262 {
1263  return !( l < r );
1264 }
1265 
1266 #endif // span_FEATURE( COMPARISON )
1267 
1268 // 26.7.2.6 views of object representation [span.objectrep]
1269 
1270 #if span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE )
1271 
1272 template< class T, extent_t Extent >
1274 as_bytes( span<T,Extent> spn ) span_noexcept
1275 {
1276 #if 0
1277  return { reinterpret_cast< std17::byte const * >( spn.data() ), spn.size_bytes() };
1278 #else
1280  reinterpret_cast< std17::byte const * >( spn.data() ), spn.size_bytes() ); // NOLINT
1281 #endif
1282 }
1283 
1284 template< class T, extent_t Extent >
1286 as_writeable_bytes( span<T,Extent> spn ) span_noexcept
1287 {
1288 #if 0
1289  return { reinterpret_cast< std17::byte * >( spn.data() ), spn.size_bytes() };
1290 #else
1292  reinterpret_cast< std17::byte * >( spn.data() ), spn.size_bytes() ); // NOLINT
1293 #endif
1294 }
1295 
1296 #endif // span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE )
1297 
1298 // extensions: non-member views:
1299 // this feature implies the presence of make_span()
1300 
1301 #if span_FEATURE( NON_MEMBER_FIRST_LAST_SUB ) && span_CPP11_120
1302 
1303 template< extent_t Count, class T >
1304 span_constexpr auto
1305 first( T & t ) -> decltype( make_span(t).template first<Count>() )
1306 {
1307  return make_span( t ).template first<Count>();
1308 }
1309 
1310 template< class T >
1311 span_constexpr auto
1312 first( T & t, index_t count ) -> decltype( make_span(t).first(count) )
1313 {
1314  return make_span( t ).first( count );
1315 }
1316 
1317 template< extent_t Count, class T >
1318 span_constexpr auto
1319 last( T & t ) -> decltype( make_span(t).template last<Count>() )
1320 {
1321  return make_span(t).template last<Count>();
1322 }
1323 
1324 template< class T >
1325 span_constexpr auto
1326 last( T & t, extent_t count ) -> decltype( make_span(t).last(count) )
1327 {
1328  return make_span( t ).last( count );
1329 }
1330 
1331 template< index_t Offset, extent_t Count = dynamic_extent, class T >
1332 span_constexpr auto
1333 subspan( T & t ) -> decltype( make_span(t).template subspan<Offset, Count>() )
1334 {
1335  return make_span( t ).template subspan<Offset, Count>();
1336 }
1337 
1338 template< class T >
1339 span_constexpr auto
1340 subspan( T & t, index_t offset, extent_t count = dynamic_extent ) -> decltype( make_span(t).subspan(offset, count) )
1341 {
1342  return make_span( t ).subspan( offset, count );
1343 }
1344 
1345 #endif // span_FEATURE( NON_MEMBER_FIRST_LAST_SUB )
1346 
1347 // 27.8 Container and view access [iterator.container]
1348 
1349 template< class T, extent_t Extent /*= dynamic_extent*/ >
1350 span_constexpr std::size_t size( span<T,Extent> const & spn )
1351 {
1352  return static_cast<std::size_t>( spn.size() );
1353 }
1354 
1355 template< class T, extent_t Extent /*= dynamic_extent*/ >
1356 span_constexpr std::ptrdiff_t ssize( span<T,Extent> const & spn )
1357 {
1358  return static_cast<std::ptrdiff_t>( spn.size() );
1359 }
1360 
1361 } // namespace span_lite
1362 } // namespace nonstd
1363 
1364 // make available in nonstd:
1365 
1366 namespace nonstd {
1367 
1369 
1370 using span_lite::span;
1371 
1373 
1374 #if span_FEATURE( COMPARISON )
1375 #if span_FEATURE( SAME )
1376 using span_lite::same;
1377 #endif
1378 
1379 using span_lite::operator==;
1380 using span_lite::operator!=;
1381 using span_lite::operator<;
1382 using span_lite::operator<=;
1383 using span_lite::operator>;
1384 using span_lite::operator>=;
1385 #endif
1386 
1387 #if span_HAVE( BYTE )
1388 using span_lite::as_bytes;
1389 using span_lite::as_writeable_bytes;
1390 #endif
1391 
1392 using span_lite::size;
1393 using span_lite::ssize;
1394 
1395 } // namespace nonstd
1396 
1397 #endif // span_USES_STD_SPAN
1398 
1399 // make_span() [span-lite extension]:
1400 
1401 #if span_FEATURE( MAKE_SPAN ) || span_FEATURE( NON_MEMBER_FIRST_LAST_SUB )
1402 
1403 namespace nonstd {
1404 namespace span_lite {
1405 
1406 template< class T >
1407 inline span_constexpr span<T>
1408 make_span( T * ptr, index_t count ) span_noexcept
1409 {
1410  return span<T>( ptr, count );
1411 }
1412 
1413 template< class T >
1414 inline span_constexpr span<T>
1415 make_span( T * first, T * last ) span_noexcept
1416 {
1417  return span<T>( first, last );
1418 }
1419 
1420 template< class T, size_t N >
1422  make_span( T ( &arr )[ N ] ) span_noexcept
1423 {
1424  return span<T, static_cast<extent_t>(N)>( &arr[ 0 ], N );
1425 }
1426 
1427 #if span_USES_STD_SPAN || span_HAVE( ARRAY )
1428 
1429 template< class T, size_t N >
1431 make_span( std::array< T, N > & arr ) span_noexcept
1432 {
1433  return span<T, static_cast<extent_t>(N)>( arr );
1434 }
1435 
1436 template< class T, size_t N >
1438 make_span( std::array< T, N > const & arr ) span_noexcept
1439 {
1440  return span<const T, static_cast<extent_t>(N)>( arr );
1441 }
1442 
1443 #endif // span_HAVE( ARRAY )
1444 
1445 #if span_USES_STD_SPAN || ( span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) && span_HAVE( AUTO ) )
1446 
1447 template< class Container, class EP = decltype( std17::data(std::declval<Container&>())) >
1448 inline span_constexpr auto
1449 make_span( Container & cont ) span_noexcept -> span< typename std::remove_pointer<EP>::type >
1450 {
1452 }
1453 
1454 template< class Container, class EP = decltype( std17::data(std::declval<Container&>())) >
1455 inline span_constexpr auto
1456 make_span( Container const & cont ) span_noexcept -> span< const typename std::remove_pointer<EP>::type >
1457 {
1459 }
1460 
1461 #else
1462 
1463 template< class T, class Allocator >
1464 inline span_constexpr span<T>
1465 make_span( std::vector<T, Allocator> & cont ) span_noexcept
1466 {
1467  return span<T>( with_container, cont );
1468 }
1469 
1470 template< class T, class Allocator >
1472 make_span( std::vector<T, Allocator> const & cont ) span_noexcept
1473 {
1474  return span<const T>( with_container, cont );
1475 }
1476 
1477 #endif // span_USES_STD_SPAN || ( ... )
1478 
1479 #if ! span_USES_STD_SPAN && span_FEATURE( WITH_CONTAINER )
1480 
1481 template< class Container >
1483 make_span( with_container_t, Container & cont ) span_noexcept
1484 {
1486 }
1487 
1488 template< class Container >
1490 make_span( with_container_t, Container const & cont ) span_noexcept
1491 {
1493 }
1494 
1495 #endif // ! span_USES_STD_SPAN && span_FEATURE( WITH_CONTAINER )
1496 
1497 
1498 } // namespace span_lite
1499 } // namespace nonstd
1500 
1501 // make available in nonstd:
1502 
1503 namespace nonstd {
1504 using span_lite::make_span;
1505 } // namespace nonstd
1506 
1507 #endif // #if span_FEATURE_TO_STD( MAKE_SPAN )
1508 
1509 #if span_CPP11_OR_GREATER && span_FEATURE( BYTE_SPAN ) && ( span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE ) )
1510 
1511 namespace nonstd {
1512 namespace span_lite {
1513 
1514 template< class T >
1515 inline span_constexpr auto
1516 byte_span( T & t ) span_noexcept -> span< std17::byte, span_sizeof(T) >
1517 {
1518  return span< std17::byte, span_sizeof(t) >( reinterpret_cast< std17::byte * >( &t ), span_sizeof(T) );
1519 }
1520 
1521 template< class T >
1522 inline span_constexpr auto
1523 byte_span( T const & t ) span_noexcept -> span< const std17::byte, span_sizeof(T) >
1524 {
1525  return span< const std17::byte, span_sizeof(t) >( reinterpret_cast< std17::byte const * >( &t ), span_sizeof(T) );
1526 }
1527 
1528 } // namespace span_lite
1529 } // namespace nonstd
1530 
1531 // make available in nonstd:
1532 
1533 namespace nonstd {
1534 using span_lite::byte_span;
1535 } // namespace nonstd
1536 
1537 #endif // span_FEATURE( BYTE_SPAN )
1538 
1539 #if ! span_USES_STD_SPAN
1541 #endif // span_USES_STD_SPAN
1542 
1543 #endif // NONSTD_SPAN_HPP_INCLUDED
std11::remove_volatile< typename std11::remove_const< T >::type >::type type
Definition: span.hpp:528
#define span_CONFIG_INDEX_TYPE
Definition: span.hpp:34
const_pointer const_iterator
Definition: span.hpp:803
#define span_noexcept
Definition: span.hpp:378
span_constexpr span(span const &other) span_noexcept
Definition: span.hpp:938
span_constexpr_exp span< element_type, dynamic_extent > subspan(index_type offset, index_type count=static_cast< index_type >(dynamic_extent)) const
Definition: span.hpp:1024
span_constexpr_exp span(pointer ptr, index_type count)
Definition: span.hpp:826
span_constexpr iterator begin() const span_noexcept
Definition: span.hpp:1129
span_constexpr_exp reference operator[](index_type idx) const
Definition: span.hpp:1059
span_CONFIG_INDEX_TYPE index_t
Definition: span.hpp:493
span_constexpr_exp span(span< OtherElementType, OtherExtent > const &other) span_noexcept
Definition: span.hpp:963
#define span_REQUIRES_0(VA)
Definition: span.hpp:476
span_constexpr bool operator>=(span< T1, E1 > const &l, span< T2, E2 > const &r)
Definition: span.hpp:1261
span_constexpr bool operator!=(span< T1, E1 > const &l, span< T2, E2 > const &r)
Definition: span.hpp:1243
#define span_constexpr_exp
Definition: span.hpp:452
span_constexpr std::ptrdiff_t ssize(span< T, Extent > const &spn)
Definition: span.hpp:1356
#define span_REQUIRES_T(VA)
Definition: span.hpp:479
std::ptrdiff_t difference_type
Definition: span.hpp:805
T const & const_reference
Definition: span.hpp:797
Count
span_constexpr reverse_iterator rbegin() const span_noexcept
Definition: span.hpp:1165
span_constexpr_exp span< element_type, Count > last() const
Definition: span.hpp:983
#define span_EXPECTS(cond)
Definition: span.hpp:453
span_constexpr index_t to_size(T size)
Definition: span.hpp:777
#define span_sizeof(T)
Definition: span.hpp:774
span_constexpr_exp span< element_type, dynamic_extent > last(index_type count) const
Definition: span.hpp:1016
#define span_ADDRESSOF(x)
Definition: span.hpp:342
span_constexpr const_iterator cbegin() const span_noexcept
Definition: span.hpp:1147
const span_constexpr with_container_t with_container
Definition: span.hpp:505
extent_t extent_type
Definition: span.hpp:800
span_constexpr span(element_type(&arr)[N]) span_noexcept
Definition: span.hpp:853
T const * const_pointer
Definition: span.hpp:796
#define span_RESTORE_WARNINGS()
Definition: span.hpp:262
span_constexpr const_reverse_iterator crbegin() const span_noexcept
Definition: span.hpp:1175
std::ptrdiff_t extent_t
Definition: span.hpp:495
span_constexpr bool operator==(span< T1, E1 > const &l, span< T2, E2 > const &r)
Definition: span.hpp:1227
integral_constant< bool, false > false_type
Definition: span.hpp:544
#define span_noreturn
Definition: span.hpp:402
span_constexpr pointer data() const span_noexcept
Definition: span.hpp:1092
span_noreturn void report_contract_violation(char const *) span_noexcept
Definition: span.hpp:763
integral_constant< bool, true > true_type
Definition: span.hpp:543
#define span_constexpr14
Definition: span.hpp:354
span_constexpr_exp reference back() const span_noexcept
Definition: span.hpp:1106
std11::remove_cv< T >::type value_type
Definition: span.hpp:792
span_constexpr_exp span(pointer firstElem, pointer lastElem)
Definition: span.hpp:836
Definition: span.hpp:488
#define span_nodiscard
Definition: span.hpp:396
std::reverse_iterator< iterator > reverse_iterator
Definition: span.hpp:807
span_constexpr_exp span< element_type, Count > first() const
Definition: span.hpp:974
span_constexpr span() span_noexcept
Definition: span.hpp:818
#define span_deprecated(msg)
Definition: span.hpp:390
span_constexpr with_container_t() span_noexcept
Definition: span.hpp:504
span_constexpr_exp reference front() const span_noexcept
Definition: span.hpp:1099
span_constexpr const extent_t dynamic_extent
Definition: span.hpp:497
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: span.hpp:808
span_constexpr_exp span< element_type, Count > subspan() const
Definition: span.hpp:996
span_constexpr const_iterator cend() const span_noexcept
Definition: span.hpp:1156
span_constexpr std::ptrdiff_t ssize() const span_noexcept
Definition: span.hpp:1042
span_constexpr iterator end() const span_noexcept
Definition: span.hpp:1138
#define span_constexpr
Definition: span.hpp:348
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1350
span_nodiscard span_constexpr bool empty() const span_noexcept
Definition: span.hpp:1052
#define span_nullptr
Definition: span.hpp:384
span_constexpr_exp span< element_type, dynamic_extent > first(index_type count) const
Definition: span.hpp:1008
span_constexpr reverse_iterator rend() const span_noexcept
Definition: span.hpp:1170
~span() span_noexcept
Definition: span.hpp:943
span_constexpr const_reverse_iterator crend() const span_noexcept
Definition: span.hpp:1180
span_constexpr index_type size() const span_noexcept
Definition: span.hpp:1037
span_constexpr index_type size_bytes() const span_noexcept
Definition: span.hpp:1047
span_constexpr bool operator>(span< T1, E1 > const &l, span< T2, E2 > const &r)
Definition: span.hpp:1255
span_constexpr14 span & operator=(span const &other) span_noexcept
Definition: span.hpp:946


ros_type_introspection
Author(s): Davide Faconti
autogenerated on Sun Sep 6 2020 03:19:54