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