cpp-common: add `bt2s::span` 0.11.0 and other related symbols
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 31 Jan 2024 22:41:47 +0000 (17:41 -0500)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 5 Feb 2024 16:46:02 +0000 (11:46 -0500)
This patch adds `bt2s::span` which wraps `nonstd::span`, that is,
span lite [1], a project written by the author also who wrote our
`bt2s::optional` implementation, therefore I trust him.

span lite is an implementation of `std::span` [2] for C++98 and up:

> The class template `span` describes an object that can refer to a
> contiguous sequence of objects with the first element of the sequence
> at position zero.

This will be useful to pass some data block as a single parameter
without copying the viewed data (in other words, a pointer and a length
with some sugar such as operator[]() and the like).

[1]: https://github.com/martinmoene/span-lite
[2]: https://en.cppreference.com/w/cpp/container/span

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ife35b4be41536fec15aef9d6603a80746c3e8727
Reviewed-on: https://review.lttng.org/c/babeltrace/+/11728
CI-Build: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
src/Makefile.am
src/cpp-common/bt2s/span.hpp [new file with mode: 0644]
src/cpp-common/vendor/span-lite/span.hpp [new file with mode: 0644]
src/cpp-common/vendor/span-lite/span.hpp.license [new file with mode: 0644]

index b90a12132e5d067917ff6b7ec59f1a254d459931..cd23468a3561ecc24887382057dd22221eab59a3 100644 (file)
@@ -61,9 +61,11 @@ noinst_HEADERS = \
        cpp-common/bt2c/vector.hpp \
        cpp-common/bt2s/make-unique.hpp \
        cpp-common/bt2s/optional.hpp \
+       cpp-common/bt2s/span.hpp \
        cpp-common/bt2s/string-view.hpp \
        cpp-common/vendor/nlohmann/json.hpp \
        cpp-common/vendor/optional-lite/optional.hpp \
+       cpp-common/vendor/span-lite/span.hpp \
        cpp-common/vendor/string_view-standalone/string_view.hpp
 
 ## This target generates an include file that contains the git version
@@ -743,4 +745,6 @@ plugins_lttng_utils_babeltrace_plugin_lttng_utils_la_LIBADD += \
 endif # !ENABLE_BUILT_IN_PLUGINS
 endif # ENABLE_DEBUG_INFO
 
-EXTRA_DIST = cpp-common/vendor/optional-lite/optional.hpp.license
+EXTRA_DIST = \
+       cpp-common/vendor/optional-lite/optional.hpp.license \
+       cpp-common/vendor/span-lite/span.hpp.license
diff --git a/src/cpp-common/bt2s/span.hpp b/src/cpp-common/bt2s/span.hpp
new file mode 100644 (file)
index 0000000..4313c9a
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef BABELTRACE_CPP_COMMON_BT2S_SPAN_HPP
+#define BABELTRACE_CPP_COMMON_BT2S_SPAN_HPP
+
+#include "cpp-common/vendor/span-lite/span.hpp"
+
+namespace bt2s {
+
+using nonstd::dynamic_extent;
+using nonstd::span;
+
+} /* namespace bt2s */
+
+#endif /* BABELTRACE_CPP_COMMON_BT2S_SPAN_HPP */
diff --git a/src/cpp-common/vendor/span-lite/span.hpp b/src/cpp-common/vendor/span-lite/span.hpp
new file mode 100644 (file)
index 0000000..3d2d86a
--- /dev/null
@@ -0,0 +1,1947 @@
+//
+// span for C++98 and later.
+// Based on http://wg21.link/p0122r7
+// For more information see https://github.com/martinmoene/span-lite
+//
+// Copyright 2018-2021 Martin Moene
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NONSTD_SPAN_HPP_INCLUDED
+#define NONSTD_SPAN_HPP_INCLUDED
+
+#define span_lite_MAJOR  0
+#define span_lite_MINOR  11
+#define span_lite_PATCH  0
+
+#define span_lite_VERSION  span_STRINGIFY(span_lite_MAJOR) "." span_STRINGIFY(span_lite_MINOR) "." span_STRINGIFY(span_lite_PATCH)
+
+#define span_STRINGIFY(  x )  span_STRINGIFY_( x )
+#define span_STRINGIFY_( x )  #x
+
+// span configuration:
+
+#define span_SPAN_DEFAULT  0
+#define span_SPAN_NONSTD   1
+#define span_SPAN_STD      2
+
+// tweak header support:
+
+#ifdef __has_include
+# if __has_include(<nonstd/span.tweak.hpp>)
+#  include <nonstd/span.tweak.hpp>
+# endif
+#define span_HAVE_TWEAK_HEADER  1
+#else
+#define span_HAVE_TWEAK_HEADER  0
+//# pragma message("span.hpp: Note: Tweak header not supported.")
+#endif
+
+// span selection and configuration:
+
+#define span_HAVE( feature )  ( span_HAVE_##feature )
+
+#ifndef  span_CONFIG_SELECT_SPAN
+# define span_CONFIG_SELECT_SPAN  ( span_HAVE_STD_SPAN ? span_SPAN_STD : span_SPAN_NONSTD )
+#endif
+
+#ifndef  span_CONFIG_EXTENT_TYPE
+# define span_CONFIG_EXTENT_TYPE  std::size_t
+#endif
+
+#ifndef  span_CONFIG_SIZE_TYPE
+# define span_CONFIG_SIZE_TYPE  std::size_t
+#endif
+
+#ifdef span_CONFIG_INDEX_TYPE
+# error `span_CONFIG_INDEX_TYPE` is deprecated since v0.7.0; it is replaced by `span_CONFIG_SIZE_TYPE`.
+#endif
+
+// span configuration (features):
+
+#ifndef  span_FEATURE_WITH_INITIALIZER_LIST_P2447
+# define span_FEATURE_WITH_INITIALIZER_LIST_P2447  0
+#endif
+
+#ifndef  span_FEATURE_WITH_CONTAINER
+#ifdef   span_FEATURE_WITH_CONTAINER_TO_STD
+# define span_FEATURE_WITH_CONTAINER  span_IN_STD( span_FEATURE_WITH_CONTAINER_TO_STD )
+#else
+# define span_FEATURE_WITH_CONTAINER  0
+# define span_FEATURE_WITH_CONTAINER_TO_STD  0
+#endif
+#endif
+
+#ifndef  span_FEATURE_CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE
+# define span_FEATURE_CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE  0
+#endif
+
+#ifndef  span_FEATURE_MEMBER_AT
+# define span_FEATURE_MEMBER_AT  0
+#endif
+
+#ifndef  span_FEATURE_MEMBER_BACK_FRONT
+# define span_FEATURE_MEMBER_BACK_FRONT  1
+#endif
+
+#ifndef  span_FEATURE_MEMBER_CALL_OPERATOR
+# define span_FEATURE_MEMBER_CALL_OPERATOR  0
+#endif
+
+#ifndef  span_FEATURE_MEMBER_SWAP
+# define span_FEATURE_MEMBER_SWAP  0
+#endif
+
+#ifndef  span_FEATURE_NON_MEMBER_FIRST_LAST_SUB
+# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB  0
+#elif    span_FEATURE_NON_MEMBER_FIRST_LAST_SUB
+# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_SPAN       1
+# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_CONTAINER  1
+#endif
+
+#ifndef  span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_SPAN
+# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_SPAN  0
+#endif
+
+#ifndef  span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_CONTAINER
+# define span_FEATURE_NON_MEMBER_FIRST_LAST_SUB_CONTAINER  0
+#endif
+
+#ifndef  span_FEATURE_COMPARISON
+# define span_FEATURE_COMPARISON  0  // Note: C++20 does not provide comparison
+#endif
+
+#ifndef  span_FEATURE_SAME
+# define span_FEATURE_SAME  0
+#endif
+
+#if span_FEATURE_SAME && !span_FEATURE_COMPARISON
+# error `span_FEATURE_SAME` requires `span_FEATURE_COMPARISON`
+#endif
+
+#ifndef  span_FEATURE_MAKE_SPAN
+#ifdef   span_FEATURE_MAKE_SPAN_TO_STD
+# define span_FEATURE_MAKE_SPAN  span_IN_STD( span_FEATURE_MAKE_SPAN_TO_STD )
+#else
+# define span_FEATURE_MAKE_SPAN  0
+# define span_FEATURE_MAKE_SPAN_TO_STD  0
+#endif
+#endif
+
+#ifndef  span_FEATURE_BYTE_SPAN
+# define span_FEATURE_BYTE_SPAN  0
+#endif
+
+// Control presence of exception handling (try and auto discover):
+
+#ifndef span_CONFIG_NO_EXCEPTIONS
+# if defined(_MSC_VER)
+#  include <cstddef>    // for _HAS_EXCEPTIONS
+# endif
+# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
+#  define span_CONFIG_NO_EXCEPTIONS  0
+# else
+#  define span_CONFIG_NO_EXCEPTIONS  1
+#  undef  span_CONFIG_CONTRACT_VIOLATION_THROWS
+#  undef  span_CONFIG_CONTRACT_VIOLATION_TERMINATES
+#  define span_CONFIG_CONTRACT_VIOLATION_THROWS  0
+#  define span_CONFIG_CONTRACT_VIOLATION_TERMINATES  1
+# endif
+#endif
+
+// Control pre- and postcondition violation behaviour:
+
+#if    defined( span_CONFIG_CONTRACT_LEVEL_ON )
+# define        span_CONFIG_CONTRACT_LEVEL_MASK  0x11
+#elif  defined( span_CONFIG_CONTRACT_LEVEL_OFF )
+# define        span_CONFIG_CONTRACT_LEVEL_MASK  0x00
+#elif  defined( span_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY )
+# define        span_CONFIG_CONTRACT_LEVEL_MASK  0x01
+#elif  defined( span_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY )
+# define        span_CONFIG_CONTRACT_LEVEL_MASK  0x10
+#else
+# define        span_CONFIG_CONTRACT_LEVEL_MASK  0x11
+#endif
+
+#if    defined( span_CONFIG_CONTRACT_VIOLATION_THROWS )
+# define        span_CONFIG_CONTRACT_VIOLATION_THROWS_V  span_CONFIG_CONTRACT_VIOLATION_THROWS
+#else
+# define        span_CONFIG_CONTRACT_VIOLATION_THROWS_V  0
+#endif
+
+#if    defined( span_CONFIG_CONTRACT_VIOLATION_THROWS     ) && span_CONFIG_CONTRACT_VIOLATION_THROWS && \
+       defined( span_CONFIG_CONTRACT_VIOLATION_TERMINATES ) && span_CONFIG_CONTRACT_VIOLATION_TERMINATES
+# error Please define none or one of span_CONFIG_CONTRACT_VIOLATION_THROWS and span_CONFIG_CONTRACT_VIOLATION_TERMINATES to 1, but not both.
+#endif
+
+// C++ language version detection (C++23 is speculative):
+// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
+
+#ifndef   span_CPLUSPLUS
+# if defined(_MSVC_LANG ) && !defined(__clang__)
+#  define span_CPLUSPLUS  (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
+# else
+#  define span_CPLUSPLUS  __cplusplus
+# endif
+#endif
+
+#define span_CPP98_OR_GREATER  ( span_CPLUSPLUS >= 199711L )
+#define span_CPP11_OR_GREATER  ( span_CPLUSPLUS >= 201103L )
+#define span_CPP14_OR_GREATER  ( span_CPLUSPLUS >= 201402L )
+#define span_CPP17_OR_GREATER  ( span_CPLUSPLUS >= 201703L )
+#define span_CPP20_OR_GREATER  ( span_CPLUSPLUS >= 202002L )
+#define span_CPP23_OR_GREATER  ( span_CPLUSPLUS >= 202300L )
+
+// C++ language version (represent 98 as 3):
+
+#define span_CPLUSPLUS_V  ( span_CPLUSPLUS / 100 - (span_CPLUSPLUS > 200000 ? 2000 : 1994) )
+
+#define span_IN_STD( v )  ( ((v) == 98 ? 3 : (v)) >= span_CPLUSPLUS_V )
+
+#define span_CONFIG(         feature )  ( span_CONFIG_##feature )
+#define span_FEATURE(        feature )  ( span_FEATURE_##feature )
+#define span_FEATURE_TO_STD( feature )  ( span_IN_STD( span_FEATURE( feature##_TO_STD ) ) )
+
+// Use C++20 std::span if available and requested:
+
+#if span_CPP20_OR_GREATER && defined(__has_include )
+# if __has_include( <span> )
+#  define span_HAVE_STD_SPAN  1
+# else
+#  define span_HAVE_STD_SPAN  0
+# endif
+#else
+# define  span_HAVE_STD_SPAN  0
+#endif
+
+#define  span_USES_STD_SPAN  ( (span_CONFIG_SELECT_SPAN == span_SPAN_STD) || ((span_CONFIG_SELECT_SPAN == span_SPAN_DEFAULT) && span_HAVE_STD_SPAN) )
+
+//
+// Use C++20 std::span:
+//
+
+#if span_USES_STD_SPAN
+
+#include <span>
+
+namespace nonstd {
+
+using std::span;
+using std::dynamic_extent;
+
+// Note: C++20 does not provide comparison
+// using std::operator==;
+// using std::operator!=;
+// using std::operator<;
+// using std::operator<=;
+// using std::operator>;
+// using std::operator>=;
+}  // namespace nonstd
+
+#else  // span_USES_STD_SPAN
+
+#include <algorithm>
+
+// Compiler versions:
+//
+// MSVC++  6.0  _MSC_VER == 1200  span_COMPILER_MSVC_VERSION ==  60  (Visual Studio 6.0)
+// MSVC++  7.0  _MSC_VER == 1300  span_COMPILER_MSVC_VERSION ==  70  (Visual Studio .NET 2002)
+// MSVC++  7.1  _MSC_VER == 1310  span_COMPILER_MSVC_VERSION ==  71  (Visual Studio .NET 2003)
+// MSVC++  8.0  _MSC_VER == 1400  span_COMPILER_MSVC_VERSION ==  80  (Visual Studio 2005)
+// MSVC++  9.0  _MSC_VER == 1500  span_COMPILER_MSVC_VERSION ==  90  (Visual Studio 2008)
+// MSVC++ 10.0  _MSC_VER == 1600  span_COMPILER_MSVC_VERSION == 100  (Visual Studio 2010)
+// MSVC++ 11.0  _MSC_VER == 1700  span_COMPILER_MSVC_VERSION == 110  (Visual Studio 2012)
+// MSVC++ 12.0  _MSC_VER == 1800  span_COMPILER_MSVC_VERSION == 120  (Visual Studio 2013)
+// MSVC++ 14.0  _MSC_VER == 1900  span_COMPILER_MSVC_VERSION == 140  (Visual Studio 2015)
+// MSVC++ 14.1  _MSC_VER >= 1910  span_COMPILER_MSVC_VERSION == 141  (Visual Studio 2017)
+// MSVC++ 14.2  _MSC_VER >= 1920  span_COMPILER_MSVC_VERSION == 142  (Visual Studio 2019)
+
+#if defined(_MSC_VER ) && !defined(__clang__)
+# define span_COMPILER_MSVC_VER      (_MSC_VER )
+# define span_COMPILER_MSVC_VERSION  (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
+#else
+# define span_COMPILER_MSVC_VER      0
+# define span_COMPILER_MSVC_VERSION  0
+#endif
+
+#define span_COMPILER_VERSION( major, minor, patch )  ( 10 * ( 10 * (major) + (minor) ) + (patch) )
+
+#if defined(__clang__)
+# define span_COMPILER_CLANG_VERSION  span_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
+#else
+# define span_COMPILER_CLANG_VERSION  0
+#endif
+
+#if defined(__GNUC__) && !defined(__clang__)
+# define span_COMPILER_GNUC_VERSION  span_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+#else
+# define span_COMPILER_GNUC_VERSION  0
+#endif
+
+// half-open range [lo..hi):
+#define span_BETWEEN( v, lo, hi )  ( (lo) <= (v) && (v) < (hi) )
+
+// Compiler warning suppression:
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wundef"
+# pragma clang diagnostic ignored "-Wmismatched-tags"
+# define span_RESTORE_WARNINGS()   _Pragma( "clang diagnostic pop" )
+
+#elif defined __GNUC__
+# pragma GCC   diagnostic push
+# pragma GCC   diagnostic ignored "-Wundef"
+# define span_RESTORE_WARNINGS()   _Pragma( "GCC diagnostic pop" )
+
+#elif span_COMPILER_MSVC_VER >= 1900
+# define span_DISABLE_MSVC_WARNINGS(codes)  __pragma(warning(push))  __pragma(warning(disable: codes))
+# define span_RESTORE_WARNINGS()            __pragma(warning(pop ))
+
+// Suppress the following MSVC GSL warnings:
+// - C26439, gsl::f.6 : special function 'function' can be declared 'noexcept'
+// - C26440, gsl::f.6 : function 'function' can be declared 'noexcept'
+// - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
+//                      use brace initialization, gsl::narrow_cast or gsl::narrow
+// - C26473: gsl::t.1 : don't cast between pointer types where the source type and the target type are the same
+// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
+// - C26490: gsl::t.1 : don't use reinterpret_cast
+
+span_DISABLE_MSVC_WARNINGS( 26439 26440 26472 26473 26481 26490 )
+
+#else
+# define span_RESTORE_WARNINGS()  /*empty*/
+#endif
+
+// Presence of language and library features:
+
+#ifdef _HAS_CPP0X
+# define span_HAS_CPP0X  _HAS_CPP0X
+#else
+# define span_HAS_CPP0X  0
+#endif
+
+#define span_CPP11_80   (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1400)
+#define span_CPP11_90   (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1500)
+#define span_CPP11_100  (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1600)
+#define span_CPP11_110  (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1700)
+#define span_CPP11_120  (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1800)
+#define span_CPP11_140  (span_CPP11_OR_GREATER || span_COMPILER_MSVC_VER >= 1900)
+
+#define span_CPP14_000  (span_CPP14_OR_GREATER)
+#define span_CPP14_120  (span_CPP14_OR_GREATER || span_COMPILER_MSVC_VER >= 1800)
+#define span_CPP14_140  (span_CPP14_OR_GREATER || span_COMPILER_MSVC_VER >= 1900)
+
+#define span_CPP17_000  (span_CPP17_OR_GREATER)
+
+// Presence of C++11 language features:
+
+#define span_HAVE_ALIAS_TEMPLATE            span_CPP11_140
+#define span_HAVE_AUTO                      span_CPP11_100
+#define span_HAVE_CONSTEXPR_11              span_CPP11_140
+#define span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG  span_CPP11_120
+#define span_HAVE_EXPLICIT_CONVERSION       span_CPP11_140
+#define span_HAVE_INITIALIZER_LIST          span_CPP11_120
+#define span_HAVE_IS_DEFAULT                span_CPP11_140
+#define span_HAVE_IS_DELETE                 span_CPP11_140
+#define span_HAVE_NOEXCEPT                  span_CPP11_140
+#define span_HAVE_NORETURN                ( span_CPP11_140 && ! span_BETWEEN( span_COMPILER_GNUC_VERSION, 1, 480 ) )
+#define span_HAVE_NULLPTR                   span_CPP11_100
+#define span_HAVE_STATIC_ASSERT             span_CPP11_100
+
+// Presence of C++14 language features:
+
+#define span_HAVE_CONSTEXPR_14              span_CPP14_000
+
+// Presence of C++17 language features:
+
+#define span_HAVE_DEPRECATED                span_CPP17_000
+#define span_HAVE_NODISCARD                 span_CPP17_000
+
+// MSVC: template parameter deduction guides since Visual Studio 2017 v15.7
+
+#if defined(__cpp_deduction_guides)
+# define span_HAVE_DEDUCTION_GUIDES         1
+#else
+# define span_HAVE_DEDUCTION_GUIDES         (span_CPP17_OR_GREATER && ! span_BETWEEN( span_COMPILER_MSVC_VER, 1, 1913 ))
+#endif
+
+// Presence of C++ library features:
+
+#define span_HAVE_ADDRESSOF                 span_CPP17_000
+#define span_HAVE_ARRAY                     span_CPP11_110
+#define span_HAVE_BYTE                      span_CPP17_000
+#define span_HAVE_CONDITIONAL               span_CPP11_120
+#define span_HAVE_CONTAINER_DATA_METHOD    (span_CPP11_140 || ( span_COMPILER_MSVC_VER >= 1500 && span_HAS_CPP0X ))
+#define span_HAVE_DATA                      span_CPP17_000
+#define span_HAVE_LONGLONG                  span_CPP11_80
+#define span_HAVE_REMOVE_CONST              span_CPP11_110
+#define span_HAVE_SNPRINTF                  span_CPP11_140
+#define span_HAVE_STRUCT_BINDING            span_CPP11_120
+#define span_HAVE_TYPE_TRAITS               span_CPP11_90
+
+// Presence of byte-lite:
+
+#ifdef NONSTD_BYTE_LITE_HPP
+# define span_HAVE_NONSTD_BYTE  1
+#else
+# define span_HAVE_NONSTD_BYTE  0
+#endif
+
+// C++ feature usage:
+
+#if span_HAVE_ADDRESSOF
+# define span_ADDRESSOF(x)  std::addressof(x)
+#else
+# define span_ADDRESSOF(x)  (&x)
+#endif
+
+#if span_HAVE_CONSTEXPR_11
+# define span_constexpr constexpr
+#else
+# define span_constexpr /*span_constexpr*/
+#endif
+
+#if span_HAVE_CONSTEXPR_14
+# define span_constexpr14 constexpr
+#else
+# define span_constexpr14 /*span_constexpr*/
+#endif
+
+#if span_HAVE_EXPLICIT_CONVERSION
+# define span_explicit explicit
+#else
+# define span_explicit /*explicit*/
+#endif
+
+#if span_HAVE_IS_DELETE
+# define span_is_delete = delete
+#else
+# define span_is_delete
+#endif
+
+#if span_HAVE_IS_DELETE
+# define span_is_delete_access public
+#else
+# define span_is_delete_access private
+#endif
+
+#if span_HAVE_NOEXCEPT && ! span_CONFIG_CONTRACT_VIOLATION_THROWS_V
+# define span_noexcept noexcept
+#else
+# define span_noexcept /*noexcept*/
+#endif
+
+#if span_HAVE_NULLPTR
+# define span_nullptr nullptr
+#else
+# define span_nullptr NULL
+#endif
+
+#if span_HAVE_DEPRECATED
+# define span_deprecated(msg) [[deprecated(msg)]]
+#else
+# define span_deprecated(msg) /*[[deprecated]]*/
+#endif
+
+#if span_HAVE_NODISCARD
+# define span_nodiscard [[nodiscard]]
+#else
+# define span_nodiscard /*[[nodiscard]]*/
+#endif
+
+#if span_HAVE_NORETURN
+# define span_noreturn [[noreturn]]
+#else
+# define span_noreturn /*[[noreturn]]*/
+#endif
+
+// Other features:
+
+#define span_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR  span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
+#define span_HAVE_ITERATOR_CTOR                    span_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
+
+// Additional includes:
+
+#if span_HAVE( ADDRESSOF )
+# include <memory>
+#endif
+
+#if span_HAVE( ARRAY )
+# include <array>
+#endif
+
+#if span_HAVE( BYTE )
+# include <cstddef>
+#endif
+
+#if span_HAVE( DATA )
+# include <iterator> // for std::data(), std::size()
+#endif
+
+#if span_HAVE( TYPE_TRAITS )
+# include <type_traits>
+#endif
+
+#if ! span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
+# include <vector>
+#endif
+
+#if span_FEATURE( MEMBER_AT ) > 1
+# include <cstdio>
+#endif
+
+#if ! span_CONFIG( NO_EXCEPTIONS )
+# include <stdexcept>
+#endif
+
+// Contract violation
+
+#define span_ELIDE_CONTRACT_EXPECTS  ( 0 == ( span_CONFIG_CONTRACT_LEVEL_MASK & 0x01 ) )
+#define span_ELIDE_CONTRACT_ENSURES  ( 0 == ( span_CONFIG_CONTRACT_LEVEL_MASK & 0x10 ) )
+
+#if span_ELIDE_CONTRACT_EXPECTS
+# define span_constexpr_exp    span_constexpr
+# define span_EXPECTS( cond )  /* Expect elided */
+#else
+# define span_constexpr_exp    span_constexpr14
+# define span_EXPECTS( cond )  span_CONTRACT_CHECK( "Precondition", cond )
+#endif
+
+#if span_ELIDE_CONTRACT_ENSURES
+# define span_constexpr_ens    span_constexpr
+# define span_ENSURES( cond )  /* Ensures elided */
+#else
+# define span_constexpr_ens    span_constexpr14
+# define span_ENSURES( cond )  span_CONTRACT_CHECK( "Postcondition", cond )
+#endif
+
+#define span_CONTRACT_CHECK( type, cond ) \
+    cond ? static_cast< void >( 0 ) \
+         : nonstd::span_lite::detail::report_contract_violation( span_LOCATION( __FILE__, __LINE__ ) ": " type " violation." )
+
+#ifdef __GNUG__
+# define span_LOCATION( file, line )  file ":" span_STRINGIFY( line )
+#else
+# define span_LOCATION( file, line )  file "(" span_STRINGIFY( line ) ")"
+#endif
+
+// Method enabling
+
+#if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
+
+#define span_REQUIRES_0(VA) \
+    template< bool B = (VA), typename std::enable_if<B, int>::type = 0 >
+
+# if span_BETWEEN( span_COMPILER_MSVC_VERSION, 1, 140 )
+// VS 2013 and earlier seem to have trouble with SFINAE for default non-type arguments
+# define span_REQUIRES_T(VA) \
+    , typename = typename std::enable_if< ( VA ), nonstd::span_lite::detail::enabler >::type
+# else
+# define span_REQUIRES_T(VA) \
+    , typename std::enable_if< (VA), int >::type = 0
+# endif
+
+#define span_REQUIRES_R(R, VA) \
+    typename std::enable_if< (VA), R>::type
+
+#define span_REQUIRES_A(VA) \
+    , typename std::enable_if< (VA), void*>::type = nullptr
+
+#else
+
+# define span_REQUIRES_0(VA)    /*empty*/
+# define span_REQUIRES_T(VA)    /*empty*/
+# define span_REQUIRES_R(R, VA) R
+# define span_REQUIRES_A(VA)    /*empty*/
+
+#endif
+
+namespace nonstd {
+namespace span_lite {
+
+// [views.constants], constants
+
+typedef span_CONFIG_EXTENT_TYPE extent_t;
+typedef span_CONFIG_SIZE_TYPE   size_t;
+
+span_constexpr const extent_t dynamic_extent = static_cast<extent_t>( -1 );
+
+template< class T, extent_t Extent = dynamic_extent >
+class span;
+
+// Tag to select span constructor taking a container (prevent ms-gsl warning C26426):
+
+struct with_container_t { span_constexpr with_container_t() span_noexcept {} };
+const  span_constexpr   with_container_t with_container;
+
+// C++11 emulation:
+
+namespace std11 {
+
+#if span_HAVE( REMOVE_CONST )
+
+using std::remove_cv;
+using std::remove_const;
+using std::remove_volatile;
+
+#else
+
+template< class T > struct remove_const            { typedef T type; };
+template< class T > struct remove_const< T const > { typedef T type; };
+
+template< class T > struct remove_volatile               { typedef T type; };
+template< class T > struct remove_volatile< T volatile > { typedef T type; };
+
+template< class T >
+struct remove_cv
+{
+    typedef typename std11::remove_volatile< typename std11::remove_const< T >::type >::type type;
+};
+
+#endif  // span_HAVE( REMOVE_CONST )
+
+#if span_HAVE( TYPE_TRAITS )
+
+using std::is_same;
+using std::is_signed;
+using std::integral_constant;
+using std::true_type;
+using std::false_type;
+using std::remove_reference;
+
+#else
+
+template< class T, T v > struct integral_constant { enum { value = v }; };
+typedef integral_constant< bool, true  > true_type;
+typedef integral_constant< bool, false > false_type;
+
+template< class T, class U > struct is_same : false_type{};
+template< class T          > struct is_same<T, T> : true_type{};
+
+template< typename T >  struct is_signed : false_type {};
+template<> struct is_signed<signed char> : true_type {};
+template<> struct is_signed<signed int > : true_type {};
+template<> struct is_signed<signed long> : true_type {};
+
+#endif
+
+} // namespace std11
+
+// C++17 emulation:
+
+namespace std17 {
+
+template< bool v > struct bool_constant : std11::integral_constant<bool, v>{};
+
+#if span_CPP11_120
+
+template< class...>
+using void_t = void;
+
+#endif
+
+#if span_HAVE( DATA )
+
+using std::data;
+using std::size;
+
+#elif span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
+
+template< typename T, std::size_t N >
+inline span_constexpr auto size( const T(&)[N] ) span_noexcept -> size_t
+{
+    return N;
+}
+
+template< typename C >
+inline span_constexpr auto size( C const & cont ) -> decltype( cont.size() )
+{
+    return cont.size();
+}
+
+template< typename T, std::size_t N >
+inline span_constexpr auto data( T(&arr)[N] ) span_noexcept -> T*
+{
+    return &arr[0];
+}
+
+template< typename C >
+inline span_constexpr auto data( C & cont ) -> decltype( cont.data() )
+{
+    return cont.data();
+}
+
+template< typename C >
+inline span_constexpr auto data( C const & cont ) -> decltype( cont.data() )
+{
+    return cont.data();
+}
+
+template< typename E >
+inline span_constexpr auto data( std::initializer_list<E> il ) span_noexcept -> E const *
+{
+    return il.begin();
+}
+
+#endif // span_HAVE( DATA )
+
+#if span_HAVE( BYTE )
+using std::byte;
+#elif span_HAVE( NONSTD_BYTE )
+using nonstd::byte;
+#endif
+
+} // namespace std17
+
+// C++20 emulation:
+
+namespace std20 {
+
+#if span_HAVE( DEDUCTION_GUIDES )
+template< class T >
+using iter_reference_t = decltype( *std::declval<T&>() );
+#endif
+
+} // namespace std20
+
+// Implementation details:
+
+namespace detail {
+
+/*enum*/ struct enabler{};
+
+template< typename T >
+span_constexpr bool is_positive( T x )
+{
+    return std11::is_signed<T>::value ? x >= 0 : true;
+}
+
+#if span_HAVE( TYPE_TRAITS )
+
+template< class Q >
+struct is_span_oracle : std::false_type{};
+
+template< class T, span_CONFIG_EXTENT_TYPE Extent >
+struct is_span_oracle< span<T, Extent> > : std::true_type{};
+
+template< class Q >
+struct is_span : is_span_oracle< typename std::remove_cv<Q>::type >{};
+
+template< class Q >
+struct is_std_array_oracle : std::false_type{};
+
+#if span_HAVE( ARRAY )
+
+template< class T, std::size_t Extent >
+struct is_std_array_oracle< std::array<T, Extent> > : std::true_type{};
+
+#endif
+
+template< class Q >
+struct is_std_array : is_std_array_oracle< typename std::remove_cv<Q>::type >{};
+
+template< class Q >
+struct is_array : std::false_type {};
+
+template< class T >
+struct is_array<T[]> : std::true_type {};
+
+template< class T, std::size_t N >
+struct is_array<T[N]> : std::true_type {};
+
+#if span_CPP11_140 && ! span_BETWEEN( span_COMPILER_GNUC_VERSION, 1, 500 )
+
+template< class, class = void >
+struct has_size_and_data : std::false_type{};
+
+template< class C >
+struct has_size_and_data
+<
+    C, std17::void_t<
+        decltype( std17::size(std::declval<C>()) ),
+        decltype( std17::data(std::declval<C>()) ) >
+> : std::true_type{};
+
+template< class, class, class = void >
+struct is_compatible_element : std::false_type {};
+
+template< class C, class E >
+struct is_compatible_element
+<
+    C, E, std17::void_t<
+        decltype( std17::data(std::declval<C>()) ) >
+> : std::is_convertible< typename std::remove_pointer<decltype( std17::data( std::declval<C&>() ) )>::type(*)[], E(*)[] >{};
+
+template< class C >
+struct is_container : std17::bool_constant
+<
+    ! is_span< C >::value
+    && ! is_array< C >::value
+    && ! is_std_array< C >::value
+    &&   has_size_and_data< C >::value
+>{};
+
+template< class C, class E >
+struct is_compatible_container : std17::bool_constant
+<
+    is_container<C>::value
+    && is_compatible_element<C,E>::value
+>{};
+
+#else // span_CPP11_140
+
+template<
+    class C, class E
+        span_REQUIRES_T((
+            ! is_span< C >::value
+            && ! is_array< C >::value
+            && ! is_std_array< C >::value
+            && ( std::is_convertible< typename std::remove_pointer<decltype( std17::data( std::declval<C&>() ) )>::type(*)[], E(*)[] >::value)
+        //  &&   has_size_and_data< C >::value
+        ))
+        , class = decltype( std17::size(std::declval<C>()) )
+        , class = decltype( std17::data(std::declval<C>()) )
+>
+struct is_compatible_container : std::true_type{};
+
+#endif // span_CPP11_140
+
+#endif // span_HAVE( TYPE_TRAITS )
+
+#if ! span_CONFIG( NO_EXCEPTIONS )
+#if   span_FEATURE( MEMBER_AT ) > 1
+
+// format index and size:
+
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wlong-long"
+#elif defined __GNUC__
+# pragma GCC   diagnostic ignored "-Wformat=ll"
+# pragma GCC   diagnostic ignored "-Wlong-long"
+#endif
+
+span_noreturn inline void throw_out_of_range( size_t idx, size_t size )
+{
+    const char fmt[] = "span::at(): index '%lli' is out of range [0..%lli)";
+    char buffer[ 2 * 20 + sizeof fmt ];
+    sprintf( buffer, fmt, static_cast<long long>(idx), static_cast<long long>(size) );
+
+    throw std::out_of_range( buffer );
+}
+
+#else // MEMBER_AT
+
+span_noreturn inline void throw_out_of_range( size_t /*idx*/, size_t /*size*/ )
+{
+    throw std::out_of_range( "span::at(): index outside span" );
+}
+#endif  // MEMBER_AT
+#endif  // NO_EXCEPTIONS
+
+#if span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
+
+struct contract_violation : std::logic_error
+{
+    explicit contract_violation( char const * const message )
+        : std::logic_error( message )
+    {}
+};
+
+inline void report_contract_violation( char const * msg )
+{
+    throw contract_violation( msg );
+}
+
+#else // span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
+
+span_noreturn inline void report_contract_violation( char const * /*msg*/ ) span_noexcept
+{
+    std::terminate();
+}
+
+#endif // span_CONFIG( CONTRACT_VIOLATION_THROWS_V )
+
+}  // namespace detail
+
+// Prevent signed-unsigned mismatch:
+
+#define span_sizeof(T)  static_cast<extent_t>( sizeof(T) )
+
+template< class T >
+inline span_constexpr size_t to_size( T size )
+{
+    return static_cast<size_t>( size );
+}
+
+//
+// [views.span] - A view over a contiguous, single-dimension sequence of objects
+//
+template< class T, extent_t Extent /*= dynamic_extent*/ >
+class span
+{
+public:
+    // constants and types
+
+    typedef T element_type;
+    typedef typename std11::remove_cv< T >::type value_type;
+
+    typedef T &       reference;
+    typedef T *       pointer;
+    typedef T const * const_pointer;
+    typedef T const & const_reference;
+
+    typedef size_t    size_type;
+    typedef extent_t  extent_type;
+
+    typedef pointer        iterator;
+    typedef const_pointer  const_iterator;
+
+    typedef std::ptrdiff_t difference_type;
+
+    typedef std::reverse_iterator< iterator >       reverse_iterator;
+    typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
+
+//    static constexpr extent_type extent = Extent;
+    enum { extent = Extent };
+
+    // 26.7.3.2 Constructors, copy, and assignment [span.cons]
+
+    span_REQUIRES_0(
+        ( Extent == 0 ) ||
+        ( Extent == dynamic_extent )
+    )
+    span_constexpr span() span_noexcept
+        : data_( span_nullptr )
+        , size_( 0 )
+    {
+        // span_EXPECTS( data() == span_nullptr );
+        // span_EXPECTS( size() == 0 );
+    }
+
+#if span_HAVE( ITERATOR_CTOR )
+    // Didn't yet succeed in combining the next two constructors:
+
+    span_constexpr_exp span( std::nullptr_t, size_type count )
+        : data_( span_nullptr )
+        , size_( count )
+    {
+        span_EXPECTS( data_ == span_nullptr && count == 0 );
+    }
+
+    template< typename It
+        span_REQUIRES_T((
+            std::is_convertible<decltype(*std::declval<It&>()), element_type &>::value
+        ))
+    >
+    span_constexpr_exp span( It first, size_type count )
+        : data_( to_address( first ) )
+        , size_( count )
+    {
+        span_EXPECTS(
+            ( data_ == span_nullptr && count == 0 ) ||
+            ( data_ != span_nullptr && detail::is_positive( count ) )
+        );
+    }
+#else
+    span_constexpr_exp span( pointer ptr, size_type count )
+        : data_( ptr )
+        , size_( count )
+    {
+        span_EXPECTS(
+            ( ptr == span_nullptr && count == 0 ) ||
+            ( ptr != span_nullptr && detail::is_positive( count ) )
+        );
+    }
+#endif
+
+#if span_HAVE( ITERATOR_CTOR )
+    template< typename It, typename End
+        span_REQUIRES_T((
+            std::is_convertible<decltype(&*std::declval<It&>()), element_type *>::value
+            && ! std::is_convertible<End, std::size_t>::value
+        ))
+     >
+    span_constexpr_exp span( It first, End last )
+        : data_( to_address( first ) )
+        , size_( to_size( last - first ) )
+    {
+        span_EXPECTS(
+             last - first >= 0
+        );
+    }
+#else
+    span_constexpr_exp span( pointer first, pointer last )
+        : data_( first )
+        , size_( to_size( last - first ) )
+    {
+        span_EXPECTS(
+            last - first >= 0
+        );
+    }
+#endif
+
+    template< std::size_t N
+        span_REQUIRES_T((
+            (Extent == dynamic_extent || Extent == static_cast<extent_t>(N))
+            && std::is_convertible< value_type(*)[], element_type(*)[] >::value
+        ))
+    >
+    span_constexpr span( element_type ( &arr )[ N ] ) span_noexcept
+        : data_( span_ADDRESSOF( arr[0] ) )
+        , size_( N  )
+    {}
+
+#if span_HAVE( ARRAY )
+
+    template< std::size_t N
+        span_REQUIRES_T((
+            (Extent == dynamic_extent || Extent == static_cast<extent_t>(N))
+            && std::is_convertible< value_type(*)[], element_type(*)[] >::value
+        ))
+    >
+# if span_FEATURE( CONSTRUCTION_FROM_STDARRAY_ELEMENT_TYPE )
+        span_constexpr span( std::array< element_type, N > & arr ) span_noexcept
+# else
+        span_constexpr span( std::array< value_type, N > & arr ) span_noexcept
+# endif
+        : data_( arr.data() )
+        , size_( to_size( arr.size() ) )
+    {}
+
+    template< std::size_t N
+# if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
+        span_REQUIRES_T((
+            (Extent == dynamic_extent || Extent == static_cast<extent_t>(N))
+            && std::is_convertible< value_type(*)[], element_type(*)[] >::value
+        ))
+# endif
+    >
+    span_constexpr span( std::array< value_type, N> const & arr ) span_noexcept
+        : data_( arr.data() )
+        , size_( to_size( arr.size() ) )
+    {}
+
+#endif // span_HAVE( ARRAY )
+
+#if span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
+    template< class Container
+        span_REQUIRES_T((
+            detail::is_compatible_container< Container, element_type >::value
+        ))
+    >
+    span_constexpr span( Container & cont )
+        : data_( std17::data( cont ) )
+        , size_( to_size( std17::size( cont ) ) )
+    {}
+
+    template< class Container
+        span_REQUIRES_T((
+            std::is_const< element_type >::value
+            && detail::is_compatible_container< Container, element_type >::value
+        ))
+    >
+    span_constexpr span( Container const & cont )
+        : data_( std17::data( cont ) )
+        , size_( to_size( std17::size( cont ) ) )
+    {}
+
+#endif // span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
+
+#if span_FEATURE( WITH_CONTAINER )
+
+    template< class Container >
+    span_constexpr span( with_container_t, Container & cont )
+        : data_( cont.size() == 0 ? span_nullptr : span_ADDRESSOF( cont[0] ) )
+        , size_( to_size( cont.size() ) )
+    {}
+
+    template< class Container >
+    span_constexpr span( with_container_t, Container const & cont )
+        : data_( cont.size() == 0 ? span_nullptr : const_cast<pointer>( span_ADDRESSOF( cont[0] ) ) )
+        , size_( to_size( cont.size() ) )
+    {}
+#endif
+
+#if span_FEATURE( WITH_INITIALIZER_LIST_P2447 ) && span_HAVE( INITIALIZER_LIST )
+
+    // constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il) noexcept;
+
+#if !span_BETWEEN( span_COMPILER_MSVC_VERSION, 120, 130 )
+
+    template< extent_t U = Extent
+        span_REQUIRES_T((
+            U != dynamic_extent
+        ))
+    >
+#if span_COMPILER_GNUC_VERSION >= 900   // prevent GCC's "-Winit-list-lifetime"
+    span_constexpr14 explicit span( std::initializer_list<value_type> il ) span_noexcept
+    {
+        data_ = il.begin();
+        size_ = il.size();
+    }
+#else
+    span_constexpr explicit span( std::initializer_list<value_type> il ) span_noexcept
+        : data_( il.begin() )
+        , size_( il.size()  )
+    {}
+#endif
+
+#endif // MSVC 120 (VS2013)
+
+    template< extent_t U = Extent
+        span_REQUIRES_T((
+            U == dynamic_extent
+        ))
+    >
+#if span_COMPILER_GNUC_VERSION >= 900   // prevent GCC's "-Winit-list-lifetime"
+    span_constexpr14 /*explicit*/ span( std::initializer_list<value_type> il ) span_noexcept
+    {
+        data_ = il.begin();
+        size_ = il.size();
+    }
+#else
+    span_constexpr /*explicit*/ span( std::initializer_list<value_type> il ) span_noexcept
+        : data_( il.begin() )
+        , size_( il.size()  )
+    {}
+#endif
+
+#endif // P2447
+
+#if span_HAVE( IS_DEFAULT )
+    span_constexpr span( span const & other ) span_noexcept = default;
+
+    ~span() span_noexcept = default;
+
+    span_constexpr14 span & operator=( span const & other ) span_noexcept = default;
+#else
+    span_constexpr span( span const & other ) span_noexcept
+        : data_( other.data_ )
+        , size_( other.size_ )
+    {}
+
+    ~span() span_noexcept
+    {}
+
+    span_constexpr14 span & operator=( span const & other ) span_noexcept
+    {
+        data_ = other.data_;
+        size_ = other.size_;
+
+        return *this;
+    }
+#endif
+
+    template< class OtherElementType, extent_type OtherExtent
+        span_REQUIRES_T((
+            (Extent == dynamic_extent || OtherExtent == dynamic_extent || Extent == OtherExtent)
+            && std::is_convertible<OtherElementType(*)[], element_type(*)[]>::value
+        ))
+    >
+    span_constexpr_exp span( span<OtherElementType, OtherExtent> const & other ) span_noexcept
+        : data_( other.data() )
+        , size_( other.size() )
+    {
+        span_EXPECTS( OtherExtent == dynamic_extent || other.size() == to_size(OtherExtent) );
+    }
+
+    // 26.7.3.3 Subviews [span.sub]
+
+    template< extent_type Count >
+    span_constexpr_exp span< element_type, Count >
+    first() const
+    {
+        span_EXPECTS( detail::is_positive( Count ) && Count <= size() );
+
+        return span< element_type, Count >( data(), Count );
+    }
+
+    template< extent_type Count >
+    span_constexpr_exp span< element_type, Count >
+    last() const
+    {
+        span_EXPECTS( detail::is_positive( Count ) && Count <= size() );
+
+        return span< element_type, Count >( data() + (size() - Count), Count );
+    }
+
+#if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
+    template< size_type Offset, extent_type Count = dynamic_extent >
+#else
+    template< size_type Offset, extent_type Count /*= dynamic_extent*/ >
+#endif
+    span_constexpr_exp span< element_type, Count >
+    subspan() const
+    {
+        span_EXPECTS(
+            ( detail::is_positive( Offset ) && Offset <= size() ) &&
+            ( Count == dynamic_extent || (detail::is_positive( Count ) && Count + Offset <= size()) )
+        );
+
+        return span< element_type, Count >(
+            data() + Offset, Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : size() - Offset) );
+    }
+
+    span_constexpr_exp span< element_type, dynamic_extent >
+    first( size_type count ) const
+    {
+        span_EXPECTS( detail::is_positive( count ) && count <= size() );
+
+        return span< element_type, dynamic_extent >( data(), count );
+    }
+
+    span_constexpr_exp span< element_type, dynamic_extent >
+    last( size_type count ) const
+    {
+        span_EXPECTS( detail::is_positive( count ) && count <= size() );
+
+        return span< element_type, dynamic_extent >( data() + ( size() - count ), count );
+    }
+
+    span_constexpr_exp span< element_type, dynamic_extent >
+    subspan( size_type offset, size_type count = static_cast<size_type>(dynamic_extent) ) const
+    {
+        span_EXPECTS(
+            ( ( detail::is_positive( offset ) && offset <= size() ) ) &&
+            ( count == static_cast<size_type>(dynamic_extent) || ( detail::is_positive( count ) && offset + count <= size() ) )
+        );
+
+        return span< element_type, dynamic_extent >(
+            data() + offset, count == static_cast<size_type>(dynamic_extent) ? size() - offset : count );
+    }
+
+    // 26.7.3.4 Observers [span.obs]
+
+    span_constexpr size_type size() const span_noexcept
+    {
+        return size_;
+    }
+
+    span_constexpr std::ptrdiff_t ssize() const span_noexcept
+    {
+        return static_cast<std::ptrdiff_t>( size_ );
+    }
+
+    span_constexpr size_type size_bytes() const span_noexcept
+    {
+        return size() * to_size( sizeof( element_type ) );
+    }
+
+    span_nodiscard span_constexpr bool empty() const span_noexcept
+    {
+        return size() == 0;
+    }
+
+    // 26.7.3.5 Element access [span.elem]
+
+    span_constexpr_exp reference operator[]( size_type idx ) const
+    {
+        span_EXPECTS( detail::is_positive( idx ) && idx < size() );
+
+        return *( data() + idx );
+    }
+
+#if span_FEATURE( MEMBER_CALL_OPERATOR )
+    span_deprecated("replace operator() with operator[]")
+
+    span_constexpr_exp reference operator()( size_type idx ) const
+    {
+        span_EXPECTS( detail::is_positive( idx ) && idx < size() );
+
+        return *( data() + idx );
+    }
+#endif
+
+#if span_FEATURE( MEMBER_AT )
+    span_constexpr14 reference at( size_type idx ) const
+    {
+#if span_CONFIG( NO_EXCEPTIONS )
+        return this->operator[]( idx );
+#else
+        if ( !detail::is_positive( idx ) || size() <= idx )
+        {
+            detail::throw_out_of_range( idx, size() );
+        }
+        return *( data() + idx );
+#endif
+    }
+#endif
+
+    span_constexpr pointer data() const span_noexcept
+    {
+        return data_;
+    }
+
+#if span_FEATURE( MEMBER_BACK_FRONT )
+
+    span_constexpr_exp reference front() const span_noexcept
+    {
+        span_EXPECTS( ! empty() );
+
+        return *data();
+    }
+
+    span_constexpr_exp reference back() const span_noexcept
+    {
+        span_EXPECTS( ! empty() );
+
+        return *( data() + size() - 1 );
+    }
+
+#endif
+
+    // xx.x.x.x Modifiers [span.modifiers]
+
+#if span_FEATURE( MEMBER_SWAP )
+
+    span_constexpr14 void swap( span & other ) span_noexcept
+    {
+        using std::swap;
+        swap( data_, other.data_ );
+        swap( size_, other.size_ );
+    }
+#endif
+
+    // 26.7.3.6 Iterator support [span.iterators]
+
+    span_constexpr iterator begin() const span_noexcept
+    {
+#if span_CPP11_OR_GREATER
+        return { data() };
+#else
+        return iterator( data() );
+#endif
+    }
+
+    span_constexpr iterator end() const span_noexcept
+    {
+#if span_CPP11_OR_GREATER
+        return { data() + size() };
+#else
+        return iterator( data() + size() );
+#endif
+    }
+
+    span_constexpr const_iterator cbegin() const span_noexcept
+    {
+#if span_CPP11_OR_GREATER
+        return { data() };
+#else
+        return const_iterator( data() );
+#endif
+    }
+
+    span_constexpr const_iterator cend() const span_noexcept
+    {
+#if span_CPP11_OR_GREATER
+        return { data() + size() };
+#else
+        return const_iterator( data() + size() );
+#endif
+    }
+
+    span_constexpr reverse_iterator rbegin() const span_noexcept
+    {
+        return reverse_iterator( end() );
+    }
+
+    span_constexpr reverse_iterator rend() const span_noexcept
+    {
+        return reverse_iterator( begin() );
+    }
+
+    span_constexpr const_reverse_iterator crbegin() const span_noexcept
+    {
+        return const_reverse_iterator ( cend() );
+    }
+
+    span_constexpr const_reverse_iterator crend() const span_noexcept
+    {
+        return const_reverse_iterator( cbegin() );
+    }
+
+private:
+
+    // Note: C++20 has std::pointer_traits<Ptr>::to_address( it );
+
+#if span_HAVE( ITERATOR_CTOR )
+    static inline span_constexpr pointer to_address( std::nullptr_t ) span_noexcept
+    {
+        return nullptr;
+    }
+
+    template< typename U >
+    static inline span_constexpr U * to_address( U * p ) span_noexcept
+    {
+        return p;
+    }
+
+    template< typename Ptr
+        span_REQUIRES_T(( ! std::is_pointer<Ptr>::value ))
+    >
+    static inline span_constexpr pointer to_address( Ptr const & it ) span_noexcept
+    {
+        return to_address( it.operator->() );
+    }
+#endif // span_HAVE( ITERATOR_CTOR )
+
+private:
+    pointer   data_;
+    size_type size_;
+};
+
+// class template argument deduction guides:
+
+#if span_HAVE( DEDUCTION_GUIDES )
+
+template< class T, size_t N >
+span( T (&)[N] ) -> span<T, static_cast<extent_t>(N)>;
+
+template< class T, size_t N >
+span( std::array<T, N> & ) -> span<T, static_cast<extent_t>(N)>;
+
+template< class T, size_t N >
+span( std::array<T, N> const & ) -> span<const T, static_cast<extent_t>(N)>;
+
+#if span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR )
+
+template< class Container >
+span( Container& ) -> span<typename Container::value_type>;
+
+template< class Container >
+span( Container const & ) -> span<const typename Container::value_type>;
+
+#endif
+
+// iterator: constraints: It satisfies contiguous_­iterator.
+
+template< class It, class EndOrSize >
+span( It, EndOrSize ) -> span< typename std11::remove_reference< typename std20::iter_reference_t<It> >::type >;
+
+#endif // span_HAVE( DEDUCTION_GUIDES )
+
+// 26.7.3.7 Comparison operators [span.comparison]
+
+#if span_FEATURE( COMPARISON )
+#if span_FEATURE( SAME )
+
+template< class T1, extent_t E1, class T2, extent_t E2  >
+inline span_constexpr bool same( span<T1,E1> const & l, span<T2,E2> const & r ) span_noexcept
+{
+    return std11::is_same<T1, T2>::value
+        && l.size() == r.size()
+        && static_cast<void const*>( l.data() ) == r.data();
+}
+
+#endif
+
+template< class T1, extent_t E1, class T2, extent_t E2  >
+inline span_constexpr bool operator==( span<T1,E1> const & l, span<T2,E2> const & r )
+{
+    return
+#if span_FEATURE( SAME )
+        same( l, r ) ||
+#endif
+        ( l.size() == r.size() && std::equal( l.begin(), l.end(), r.begin() ) );
+}
+
+template< class T1, extent_t E1, class T2, extent_t E2  >
+inline span_constexpr bool operator<( span<T1,E1> const & l, span<T2,E2> const & r )
+{
+    return std::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() );
+}
+
+template< class T1, extent_t E1, class T2, extent_t E2  >
+inline span_constexpr bool operator!=( span<T1,E1> const & l, span<T2,E2> const & r )
+{
+    return !( l == r );
+}
+
+template< class T1, extent_t E1, class T2, extent_t E2  >
+inline span_constexpr bool operator<=( span<T1,E1> const & l, span<T2,E2> const & r )
+{
+    return !( r < l );
+}
+
+template< class T1, extent_t E1, class T2, extent_t E2  >
+inline span_constexpr bool operator>( span<T1,E1> const & l, span<T2,E2> const & r )
+{
+    return ( r < l );
+}
+
+template< class T1, extent_t E1, class T2, extent_t E2  >
+inline span_constexpr bool operator>=( span<T1,E1> const & l, span<T2,E2> const & r )
+{
+    return !( l < r );
+}
+
+#endif // span_FEATURE( COMPARISON )
+
+// 26.7.2.6 views of object representation [span.objectrep]
+
+#if span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE )
+
+// Avoid MSVC 14.1 (1910), VS 2017: warning C4307: '*': integral constant overflow:
+
+template< typename T, extent_t Extent >
+struct BytesExtent
+{
+#if span_CPP11_OR_GREATER
+    enum ET : extent_t { value = span_sizeof(T) * Extent };
+#else
+    enum ET { value = span_sizeof(T) * Extent };
+#endif
+};
+
+template< typename T >
+struct BytesExtent< T, dynamic_extent >
+{
+#if span_CPP11_OR_GREATER
+    enum ET : extent_t { value = dynamic_extent };
+#else
+    enum ET { value = dynamic_extent };
+#endif
+};
+
+template< class T, extent_t Extent >
+inline span_constexpr span< const std17::byte, BytesExtent<T, Extent>::value >
+as_bytes( span<T,Extent> spn ) span_noexcept
+{
+#if 0
+    return { reinterpret_cast< std17::byte const * >( spn.data() ), spn.size_bytes() };
+#else
+    return span< const std17::byte, BytesExtent<T, Extent>::value >(
+        reinterpret_cast< std17::byte const * >( spn.data() ), spn.size_bytes() );  // NOLINT
+#endif
+}
+
+template< class T, extent_t Extent >
+inline span_constexpr span< std17::byte, BytesExtent<T, Extent>::value >
+as_writable_bytes( span<T,Extent> spn ) span_noexcept
+{
+#if 0
+    return { reinterpret_cast< std17::byte * >( spn.data() ), spn.size_bytes() };
+#else
+    return span< std17::byte, BytesExtent<T, Extent>::value >(
+        reinterpret_cast< std17::byte * >( spn.data() ), spn.size_bytes() );  // NOLINT
+#endif
+}
+
+#endif // span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE )
+
+// 27.8 Container and view access [iterator.container]
+
+template< class T, extent_t Extent /*= dynamic_extent*/ >
+span_constexpr std::size_t size( span<T,Extent> const & spn )
+{
+    return static_cast<std::size_t>( spn.size() );
+}
+
+template< class T, extent_t Extent /*= dynamic_extent*/ >
+span_constexpr std::ptrdiff_t ssize( span<T,Extent> const & spn )
+{
+    return static_cast<std::ptrdiff_t>( spn.size() );
+}
+
+}  // namespace span_lite
+}  // namespace nonstd
+
+// make available in nonstd:
+
+namespace nonstd {
+
+using span_lite::dynamic_extent;
+
+using span_lite::span;
+
+using span_lite::with_container;
+
+#if span_FEATURE( COMPARISON )
+#if span_FEATURE( SAME )
+using span_lite::same;
+#endif
+
+using span_lite::operator==;
+using span_lite::operator!=;
+using span_lite::operator<;
+using span_lite::operator<=;
+using span_lite::operator>;
+using span_lite::operator>=;
+#endif
+
+#if span_HAVE( BYTE )
+using span_lite::as_bytes;
+using span_lite::as_writable_bytes;
+#endif
+
+using span_lite::size;
+using span_lite::ssize;
+
+}  // namespace nonstd
+
+#endif  // span_USES_STD_SPAN
+
+// make_span() [span-lite extension]:
+
+#if span_FEATURE( MAKE_SPAN ) || span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_SPAN ) || span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_CONTAINER )
+
+#if span_USES_STD_SPAN
+# define  span_constexpr  constexpr
+# define  span_noexcept   noexcept
+# define  span_nullptr    nullptr
+# ifndef  span_CONFIG_EXTENT_TYPE
+#  define span_CONFIG_EXTENT_TYPE  std::size_t
+# endif
+using extent_t = span_CONFIG_EXTENT_TYPE;
+#endif  // span_USES_STD_SPAN
+
+namespace nonstd {
+namespace span_lite {
+
+template< class T >
+inline span_constexpr span<T>
+make_span( T * ptr, size_t count ) span_noexcept
+{
+    return span<T>( ptr, count );
+}
+
+template< class T >
+inline span_constexpr span<T>
+make_span( T * first, T * last ) span_noexcept
+{
+    return span<T>( first, last );
+}
+
+template< class T, std::size_t N >
+inline span_constexpr span<T, static_cast<extent_t>(N)>
+make_span( T ( &arr )[ N ] ) span_noexcept
+{
+    return span<T, static_cast<extent_t>(N)>( &arr[ 0 ], N );
+}
+
+#if span_USES_STD_SPAN || span_HAVE( ARRAY )
+
+template< class T, std::size_t N >
+inline span_constexpr span<T, static_cast<extent_t>(N)>
+make_span( std::array< T, N > & arr ) span_noexcept
+{
+    return span<T, static_cast<extent_t>(N)>( arr );
+}
+
+template< class T, std::size_t N >
+inline span_constexpr span< const T, static_cast<extent_t>(N) >
+make_span( std::array< T, N > const & arr ) span_noexcept
+{
+    return span<const T, static_cast<extent_t>(N)>( arr );
+}
+
+#endif // span_HAVE( ARRAY )
+
+#if span_USES_STD_SPAN || span_HAVE( INITIALIZER_LIST )
+
+template< class T >
+inline span_constexpr span< const T >
+make_span( std::initializer_list<T> il ) span_noexcept
+{
+    return span<const T>( il.begin(), il.size() );
+}
+
+#endif // span_HAVE( INITIALIZER_LIST )
+
+#if span_USES_STD_SPAN
+
+template< class Container, class EP = decltype( std::data(std::declval<Container&>())) >
+inline span_constexpr auto
+make_span( Container & cont ) span_noexcept -> span< typename std::remove_pointer<EP>::type >
+{
+    return span< typename std::remove_pointer<EP>::type >( cont );
+}
+
+template< class Container, class EP = decltype( std::data(std::declval<Container&>())) >
+inline span_constexpr auto
+make_span( Container const & cont ) span_noexcept -> span< const typename std::remove_pointer<EP>::type >
+{
+    return span< const typename std::remove_pointer<EP>::type >( cont );
+}
+
+#elif span_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) && span_HAVE( AUTO )
+
+template< class Container, class EP = decltype( std17::data(std::declval<Container&>())) >
+inline span_constexpr auto
+make_span( Container & cont ) span_noexcept -> span< typename std::remove_pointer<EP>::type >
+{
+    return span< typename std::remove_pointer<EP>::type >( cont );
+}
+
+template< class Container, class EP = decltype( std17::data(std::declval<Container&>())) >
+inline span_constexpr auto
+make_span( Container const & cont ) span_noexcept -> span< const typename std::remove_pointer<EP>::type >
+{
+    return span< const typename std::remove_pointer<EP>::type >( cont );
+}
+
+#else
+
+template< class T >
+inline span_constexpr span<T>
+make_span( span<T> spn ) span_noexcept
+{
+    return spn;
+}
+
+template< class T, class Allocator >
+inline span_constexpr span<T>
+make_span( std::vector<T, Allocator> & cont ) span_noexcept
+{
+    return span<T>( with_container, cont );
+}
+
+template< class T, class Allocator >
+inline span_constexpr span<const T>
+make_span( std::vector<T, Allocator> const & cont ) span_noexcept
+{
+    return span<const T>( with_container, cont );
+}
+
+#endif // span_USES_STD_SPAN || ( ... )
+
+#if ! span_USES_STD_SPAN && span_FEATURE( WITH_CONTAINER )
+
+template< class Container >
+inline span_constexpr span<typename Container::value_type>
+make_span( with_container_t, Container & cont ) span_noexcept
+{
+    return span< typename Container::value_type >( with_container, cont );
+}
+
+template< class Container >
+inline span_constexpr span<const typename Container::value_type>
+make_span( with_container_t, Container const & cont ) span_noexcept
+{
+    return span< const typename Container::value_type >( with_container, cont );
+}
+
+#endif // ! span_USES_STD_SPAN && span_FEATURE( WITH_CONTAINER )
+
+// extensions: non-member views:
+// this feature implies the presence of make_span()
+
+#if span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_SPAN )
+
+template< extent_t Count, class T, extent_t Extent >
+span_constexpr span<T, Count>
+first( span<T, Extent> spn )
+{
+    return spn.template first<Count>();
+}
+
+template< class T, extent_t Extent >
+span_constexpr span<T>
+first( span<T, Extent> spn, size_t count )
+{
+    return spn.first( count );
+}
+
+template< extent_t Count, class T, extent_t Extent >
+span_constexpr span<T, Count>
+last( span<T, Extent> spn )
+{
+    return spn.template last<Count>();
+}
+
+template< class T, extent_t Extent >
+span_constexpr span<T>
+last( span<T, Extent> spn, size_t count )
+{
+    return spn.last( count );
+}
+
+template< size_t Offset, extent_t Count, class T, extent_t Extent >
+span_constexpr span<T, Count>
+subspan( span<T, Extent> spn )
+{
+    return spn.template subspan<Offset, Count>();
+}
+
+template< class T, extent_t Extent >
+span_constexpr span<T>
+subspan( span<T, Extent> spn, size_t offset, extent_t count = dynamic_extent )
+{
+    return spn.subspan( offset, count );
+}
+
+#endif // span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_SPAN )
+
+#if span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_CONTAINER ) && span_CPP11_120
+
+template< extent_t Count, class T >
+span_constexpr auto
+first( T & t ) -> decltype( make_span(t).template first<Count>() )
+{
+    return make_span( t ).template first<Count>();
+}
+
+template< class T >
+span_constexpr auto
+first( T & t, size_t count ) -> decltype( make_span(t).first(count) )
+{
+    return make_span( t ).first( count );
+}
+
+template< extent_t Count, class T >
+span_constexpr auto
+last( T & t ) -> decltype( make_span(t).template last<Count>() )
+{
+    return make_span(t).template last<Count>();
+}
+
+template< class T >
+span_constexpr auto
+last( T & t, extent_t count ) -> decltype( make_span(t).last(count) )
+{
+    return make_span( t ).last( count );
+}
+
+template< size_t Offset, extent_t Count = dynamic_extent, class T >
+span_constexpr auto
+subspan( T & t ) -> decltype( make_span(t).template subspan<Offset, Count>() )
+{
+    return make_span( t ).template subspan<Offset, Count>();
+}
+
+template< class T >
+span_constexpr auto
+subspan( T & t, size_t offset, extent_t count = dynamic_extent ) -> decltype( make_span(t).subspan(offset, count) )
+{
+    return make_span( t ).subspan( offset, count );
+}
+
+#endif // span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_CONTAINER )
+
+}  // namespace span_lite
+}  // namespace nonstd
+
+// make available in nonstd:
+
+namespace nonstd {
+using span_lite::make_span;
+
+#if span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_SPAN ) || ( span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_CONTAINER ) && span_CPP11_120 )
+
+using span_lite::first;
+using span_lite::last;
+using span_lite::subspan;
+
+#endif // span_FEATURE( NON_MEMBER_FIRST_LAST_SUB_[SPAN|CONTAINER] )
+
+}  // namespace nonstd
+
+#endif // #if span_FEATURE_TO_STD( MAKE_SPAN )
+
+#if span_CPP11_OR_GREATER && span_FEATURE( BYTE_SPAN ) && ( span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE ) )
+
+namespace nonstd {
+namespace span_lite {
+
+template< class T >
+inline span_constexpr auto
+byte_span( T & t ) span_noexcept -> span< std17::byte, span_sizeof(T) >
+{
+    return span< std17::byte, span_sizeof(t) >( reinterpret_cast< std17::byte * >( &t ), span_sizeof(T) );
+}
+
+template< class T >
+inline span_constexpr auto
+byte_span( T const & t ) span_noexcept -> span< const std17::byte, span_sizeof(T) >
+{
+    return span< const std17::byte, span_sizeof(t) >( reinterpret_cast< std17::byte const * >( &t ), span_sizeof(T) );
+}
+
+}  // namespace span_lite
+}  // namespace nonstd
+
+// make available in nonstd:
+
+namespace nonstd {
+using span_lite::byte_span;
+}  // namespace nonstd
+
+#endif // span_FEATURE( BYTE_SPAN )
+
+#if span_HAVE( STRUCT_BINDING )
+
+#if   span_CPP14_OR_GREATER
+# include <tuple>
+#elif span_CPP11_OR_GREATER
+# include <tuple>
+namespace std {
+    template< std::size_t I, typename T >
+    using tuple_element_t = typename tuple_element<I, T>::type;
+}
+#else
+namespace std {
+    template< typename T >
+    class tuple_size; /*undefined*/
+
+    template< std::size_t I, typename T >
+    class tuple_element; /* undefined */
+}
+#endif // span_CPP14_OR_GREATER
+
+namespace std {
+
+// 26.7.X Tuple interface
+
+// std::tuple_size<>:
+
+template< typename ElementType, nonstd::span_lite::extent_t Extent >
+class tuple_size< nonstd::span<ElementType, Extent> > : public integral_constant<size_t, static_cast<size_t>(Extent)> {};
+
+// std::tuple_size<>: Leave undefined for dynamic extent:
+
+template< typename ElementType >
+class tuple_size< nonstd::span<ElementType, nonstd::dynamic_extent> >;
+
+// std::tuple_element<>:
+
+template< size_t I, typename ElementType, nonstd::span_lite::extent_t Extent >
+class tuple_element< I, nonstd::span<ElementType, Extent> >
+{
+public:
+#if span_HAVE( STATIC_ASSERT )
+    static_assert( Extent != nonstd::dynamic_extent && I < Extent, "tuple_element<I,span>: dynamic extent or index out of range" );
+#endif
+    using type = ElementType;
+};
+
+// std::get<>(), 2 variants:
+
+template< size_t I, typename ElementType, nonstd::span_lite::extent_t Extent >
+span_constexpr ElementType & get( nonstd::span<ElementType, Extent> & spn ) span_noexcept
+{
+#if span_HAVE( STATIC_ASSERT )
+    static_assert( Extent != nonstd::dynamic_extent && I < Extent, "get<>(span): dynamic extent or index out of range" );
+#endif
+    return spn[I];
+}
+
+template< size_t I, typename ElementType, nonstd::span_lite::extent_t Extent >
+span_constexpr ElementType const & get( nonstd::span<ElementType, Extent> const & spn ) span_noexcept
+{
+#if span_HAVE( STATIC_ASSERT )
+    static_assert( Extent != nonstd::dynamic_extent && I < Extent, "get<>(span): dynamic extent or index out of range" );
+#endif
+    return spn[I];
+}
+
+} // end namespace std
+
+#endif // span_HAVE( STRUCT_BINDING )
+
+#if ! span_USES_STD_SPAN
+span_RESTORE_WARNINGS()
+#endif  // span_USES_STD_SPAN
+
+#endif  // NONSTD_SPAN_HPP_INCLUDED
diff --git a/src/cpp-common/vendor/span-lite/span.hpp.license b/src/cpp-common/vendor/span-lite/span.hpp.license
new file mode 100644 (file)
index 0000000..c8fc2e9
--- /dev/null
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2018-2021 Martin Moene
+SPDX-License-Identifier: BSL-1.0
This page took 0.043799 seconds and 4 git commands to generate.