// // gsl-lite is based on GSL: Guidelines Support Library. // For more information see https://github.com/martinmoene/gsl-lite // // Copyright (c) 2015-2018 Martin Moene // Copyright (c) 2015-2018 Microsoft Corporation. All rights reserved. // // This code is licensed under the MIT License (MIT). // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #pragma once #ifndef GSL_GSL_LITE_HPP_INCLUDED #define GSL_GSL_LITE_HPP_INCLUDED #include #include #include #include #include #include #include #include #include #include #define gsl_lite_MAJOR 0 #define gsl_lite_MINOR 35 #define gsl_lite_PATCH 0 #define gsl_lite_VERSION gsl_STRINGIFY(gsl_lite_MAJOR) "." gsl_STRINGIFY(gsl_lite_MINOR) "." gsl_STRINGIFY(gsl_lite_PATCH) // gsl-lite backward compatibility: #ifdef gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR #define gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR #pragma message("gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR is deprecated since gsl-lite 0.7.0; replace with gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR, or consider span(with_container, cont).") #endif #if defined(gsl_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY) #pragma message("gsl_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY is deprecated since gsl-lite 0.35.0; replace with gsl_CONFIG_CONTRACT_LEVEL_ON and gsl_CONFIG_CONTRACT_EXPECTS_ONLY.") #define gsl_CONFIG_CONTRACT_LEVEL_ON #define gsl_CONFIG_CONTRACT_EXPECTS_ONLY #elif defined(gsl_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY) #pragma message("gsl_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY is deprecated since gsl-lite 0.35.0; replace with gsl_CONFIG_CONTRACT_LEVEL_ON and gsl_CONFIG_CONTRACT_ENSURES_ONLY.") #define gsl_CONFIG_CONTRACT_LEVEL_ON #define gsl_CONFIG_CONTRACT_ENSURES_ONLY #endif // M-GSL compatibility: #if defined(GSL_THROW_ON_CONTRACT_VIOLATION) #define gsl_CONFIG_CONTRACT_VIOLATION_THROWS 1 #endif #if defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) #define gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES 1 #endif #if defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION) #define gsl_CONFIG_CONTRACT_LEVEL_OFF 1 #endif // Configuration: Features #ifndef gsl_FEATURE_WITH_CONTAINER_TO_STD #define gsl_FEATURE_WITH_CONTAINER_TO_STD 99 #endif #ifndef gsl_FEATURE_MAKE_SPAN_TO_STD #define gsl_FEATURE_MAKE_SPAN_TO_STD 99 #endif #ifndef gsl_FEATURE_BYTE_SPAN_TO_STD #define gsl_FEATURE_BYTE_SPAN_TO_STD 99 #endif #ifndef gsl_FEATURE_IMPLICIT_MACRO #define gsl_FEATURE_IMPLICIT_MACRO 0 #endif #ifndef gsl_FEATURE_OWNER_MACRO #define gsl_FEATURE_OWNER_MACRO 1 #endif #ifndef gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD #define gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD 0 #endif // Configuration: Other #ifndef gsl_CONFIG_DEPRECATE_TO_LEVEL #define gsl_CONFIG_DEPRECATE_TO_LEVEL 0 #endif #ifndef gsl_CONFIG_SPAN_INDEX_TYPE #define gsl_CONFIG_SPAN_INDEX_TYPE size_t #endif #ifndef gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR #define gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR 0 #endif #ifndef gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF #define gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF 0 #endif #ifndef gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS #define gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS 0 #endif #ifndef gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON #define gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON 1 #endif #ifndef gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR #define gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR 0 #endif #if 2 <= defined(gsl_CONFIG_CONTRACT_LEVEL_AUDIT) + defined(gsl_CONFIG_CONTRACT_LEVEL_ON) + defined(gsl_CONFIG_CONTRACT_LEVEL_ASSUME) + defined(gsl_CONFIG_CONTRACT_LEVEL_OFF) #error only one of gsl_CONFIG_CONTRACT_LEVEL_AUDIT, gsl_CONFIG_CONTRACT_LEVEL_ON, gsl_CONFIG_CONTRACT_LEVEL_ASSUME, and gsl_CONFIG_CONTRACT_LEVEL_OFF may be defined. #elif defined(gsl_CONFIG_CONTRACT_LEVEL_AUDIT) #define gsl_CONFIG_CONTRACT_LEVEL_MASK_0 0x33 #elif defined(gsl_CONFIG_CONTRACT_LEVEL_ON) #define gsl_CONFIG_CONTRACT_LEVEL_MASK_0 0x11 #elif defined(gsl_CONFIG_CONTRACT_LEVEL_ASSUME) #define gsl_CONFIG_CONTRACT_LEVEL_MASK_0 0x44 #elif defined(gsl_CONFIG_CONTRACT_LEVEL_OFF) #define gsl_CONFIG_CONTRACT_LEVEL_MASK_0 0x00 #else #define gsl_CONFIG_CONTRACT_LEVEL_MASK_0 0x11 #endif #if defined(gsl_CONFIG_CONTRACT_EXPECTS_ONLY) #define gsl_CONFIG_CONTRACT_LEVEL_MASK (gsl_CONFIG_CONTRACT_LEVEL_MASK_0 & 0x0F) #elif defined(gsl_CONFIG_CONTRACT_ENSURES_ONLY) #define gsl_CONFIG_CONTRACT_LEVEL_MASK (gsl_CONFIG_CONTRACT_LEVEL_MASK_0 & 0xF0) #else #define gsl_CONFIG_CONTRACT_LEVEL_MASK gsl_CONFIG_CONTRACT_LEVEL_MASK_0 #endif #if 2 <= defined(gsl_CONFIG_CONTRACT_VIOLATION_THROWS) + defined(gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES) + defined(gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER) #error only one of gsl_CONFIG_CONTRACT_VIOLATION_THROWS, gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES, and gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER may be defined. #elif defined(gsl_CONFIG_CONTRACT_VIOLATION_THROWS) #define gsl_CONFIG_CONTRACT_VIOLATION_THROWS_V 1 #define gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER_V 0 #elif defined(gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES) #define gsl_CONFIG_CONTRACT_VIOLATION_THROWS_V 0 #define gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER_V 0 #elif defined(gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER) #define gsl_CONFIG_CONTRACT_VIOLATION_THROWS_V 0 #define gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER_V 1 #else #define gsl_CONFIG_CONTRACT_VIOLATION_THROWS_V 0 #define gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER_V 0 #endif #if defined(gsl_CONFIG_CONTRACT_LEVEL_ASSUME) && (defined(gsl_CONFIG_CONTRACT_VIOLATION_THROWS) || defined(gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES) || defined(gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER)) // `gsl_CONFIG_CONTRACT_LEVEL_ASSUME` should not be combined with any of the violation // response macros. Contract violations are undefined behavior in ASSUME mode, and // code which expects a particular violation response will not work as expected. #error cannot define gsl_CONFIG_CONTRACT_VIOLATION_THROWS, gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES, or gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER if gsl_CONFIG_CONTRACT_LEVEL_ASSUME is defined. #endif // C++ language version detection (C++20 is speculative): // Note: VC14.0/1900 (VS2015) lacks too much from C++14. #ifndef gsl_CPLUSPLUS #if defined(_MSVC_LANG) && !defined(__clang__) #define gsl_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG) #else #define gsl_CPLUSPLUS __cplusplus #endif #endif #define gsl_CPP98_OR_GREATER (gsl_CPLUSPLUS >= 199711L) #define gsl_CPP11_OR_GREATER (gsl_CPLUSPLUS >= 201103L) #define gsl_CPP14_OR_GREATER (gsl_CPLUSPLUS >= 201402L) #define gsl_CPP17_OR_GREATER (gsl_CPLUSPLUS >= 201703L) #define gsl_CPP20_OR_GREATER (gsl_CPLUSPLUS >= 202000L) // C++ language version (represent 98 as 3): #define gsl_CPLUSPLUS_V (gsl_CPLUSPLUS / 100 - (gsl_CPLUSPLUS > 200000 ? 2000 : 1994)) // half-open range [lo..hi): #define gsl_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi)) // Compiler versions: // // MSVC++ 6.0 _MSC_VER == 1200 (Visual Studio 6.0) // MSVC++ 7.0 _MSC_VER == 1300 (Visual Studio .NET 2002) // MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio .NET 2003) // MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005) // MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008) // MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010) // MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012) // MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013) // MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) // MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017) #if defined(_MSC_VER) && !defined(__clang__) #define gsl_COMPILER_MSVC_VER (_MSC_VER) #define gsl_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * (5 + (_MSC_VER < 1900))) #else #define gsl_COMPILER_MSVC_VER 0 #define gsl_COMPILER_MSVC_VERSION 0 #endif #define gsl_COMPILER_VERSION(major, minor, patch) (10 * (10 * (major) + (minor)) + (patch)) #if defined(__clang__) #define gsl_COMPILER_CLANG_VERSION gsl_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) #else #define gsl_COMPILER_CLANG_VERSION 0 #endif #if defined(__GNUC__) && !defined(__clang__) #define gsl_COMPILER_GNUC_VERSION gsl_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) #else #define gsl_COMPILER_GNUC_VERSION 0 #endif // Method enabling (C++98, VC120 (VS2013) cannot use __VA_ARGS__) #define gsl_REQUIRES_0(VA) \ template ::type = 0> #define gsl_REQUIRES_T(VA) \ , typename = typename std::enable_if<(VA), gsl::detail::enabler>::type #define gsl_REQUIRES_R(R, VA) \ typename std::enable_if::type #define gsl_REQUIRES_A(VA) \ , typename std::enable_if::type = nullptr // Compiler non-strict aliasing: #if defined(__clang__) || defined(__GNUC__) #define gsl_may_alias __attribute__((__may_alias__)) #else #define gsl_may_alias #endif // Presence of gsl, language and library features: #define gsl_IN_STD(v) (((v) == 98 ? 3 : (v)) >= gsl_CPLUSPLUS_V) #define gsl_DEPRECATE_TO_LEVEL(level) (level <= gsl_CONFIG_DEPRECATE_TO_LEVEL) #define gsl_FEATURE_TO_STD(feature) (gsl_IN_STD(gsl_FEATURE(feature##_TO_STD))) #define gsl_FEATURE(feature) (gsl_FEATURE_##feature) #define gsl_CONFIG(feature) (gsl_CONFIG_##feature) #define gsl_HAVE(feature) (gsl_HAVE_##feature) // Presence of wide character support: #ifdef __DJGPP__ #define gsl_HAVE_WCHAR 0 #else #define gsl_HAVE_WCHAR 1 #endif // Presence of language & library features: #ifdef _HAS_CPP0X #define gsl_HAS_CPP0X _HAS_CPP0X #else #define gsl_HAS_CPP0X 0 #endif #define gsl_CPP11_100 (gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1600) #define gsl_CPP11_110 (gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1700) #define gsl_CPP11_120 (gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1800) #define gsl_CPP11_140 (gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1900) #define gsl_CPP14_000 (gsl_CPP14_OR_GREATER) #define gsl_CPP14_120 (gsl_CPP14_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1800) #define gsl_CPP14_140 (gsl_CPP14_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1900) #define gsl_CPP17_000 (gsl_CPP17_OR_GREATER) #define gsl_CPP17_140 (gsl_CPP17_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1900) #define gsl_CPP11_140_CPP0X_90 (gsl_CPP11_140 || (gsl_COMPILER_MSVC_VER >= 1500 && gsl_HAS_CPP0X)) #define gsl_CPP11_140_CPP0X_100 (gsl_CPP11_140 || (gsl_COMPILER_MSVC_VER >= 1600 && gsl_HAS_CPP0X)) // Presence of C++11 language features: #define gsl_HAVE_AUTO gsl_CPP11_100 #define gsl_HAVE_NULLPTR gsl_CPP11_100 #define gsl_HAVE_RVALUE_REFERENCE gsl_CPP11_100 #define gsl_HAVE_ENUM_CLASS gsl_CPP11_110 #define gsl_HAVE_ALIAS_TEMPLATE gsl_CPP11_120 #define gsl_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG gsl_CPP11_120 #define gsl_HAVE_EXPLICIT gsl_CPP11_120 #define gsl_HAVE_INITIALIZER_LIST gsl_CPP11_120 #define gsl_HAVE_CONSTEXPR_11 gsl_CPP11_140 #define gsl_HAVE_IS_DEFAULT gsl_CPP11_140 #define gsl_HAVE_IS_DELETE gsl_CPP11_140 #define gsl_HAVE_NOEXCEPT gsl_CPP11_140 #if gsl_CPP11_OR_GREATER // see above #endif // Presence of C++14 language features: #define gsl_HAVE_CONSTEXPR_14 gsl_CPP14_000 #define gsl_HAVE_DECLTYPE_AUTO gsl_CPP14_140 // Presence of C++17 language features: // MSVC: template parameter deduction guides since Visual Studio 2017 v15.7 #define gsl_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE gsl_CPP17_000 #define gsl_HAVE_DEDUCTION_GUIDES (gsl_CPP17_000 && !gsl_BETWEEN(gsl_COMPILER_MSVC_VERSION, 1, 999)) // Presence of C++ library features: #define gsl_HAVE_ADDRESSOF gsl_CPP17_000 #define gsl_HAVE_ARRAY gsl_CPP11_110 #define gsl_HAVE_TYPE_TRAITS gsl_CPP11_110 #define gsl_HAVE_TR1_TYPE_TRAITS gsl_CPP11_110 #define gsl_HAVE_CONTAINER_DATA_METHOD gsl_CPP11_140_CPP0X_90 #define gsl_HAVE_STD_DATA gsl_CPP17_000 #define gsl_HAVE_SIZED_TYPES gsl_CPP11_140 #define gsl_HAVE_MAKE_SHARED gsl_CPP11_140_CPP0X_100 #define gsl_HAVE_SHARED_PTR gsl_CPP11_140_CPP0X_100 #define gsl_HAVE_UNIQUE_PTR gsl_CPP11_140_CPP0X_100 #define gsl_HAVE_MAKE_UNIQUE gsl_CPP14_120 #define gsl_HAVE_UNCAUGHT_EXCEPTIONS gsl_CPP17_140 #define gsl_HAVE_ADD_CONST gsl_HAVE_TYPE_TRAITS #define gsl_HAVE_INTEGRAL_CONSTANT gsl_HAVE_TYPE_TRAITS #define gsl_HAVE_REMOVE_CONST gsl_HAVE_TYPE_TRAITS #define gsl_HAVE_REMOVE_REFERENCE gsl_HAVE_TYPE_TRAITS #define gsl_HAVE_TR1_ADD_CONST gsl_HAVE_TR1_TYPE_TRAITS #define gsl_HAVE_TR1_INTEGRAL_CONSTANT gsl_HAVE_TR1_TYPE_TRAITS #define gsl_HAVE_TR1_REMOVE_CONST gsl_HAVE_TR1_TYPE_TRAITS #define gsl_HAVE_TR1_REMOVE_REFERENCE gsl_HAVE_TR1_TYPE_TRAITS // C++ feature usage: #if gsl_HAVE(ADDRESSOF) #define gsl_ADDRESSOF(x) std::addressof(x) #else #define gsl_ADDRESSOF(x) (&x) #endif #if gsl_HAVE(CONSTEXPR_11) #define gsl_constexpr constexpr #else #define gsl_constexpr /*constexpr*/ #endif #if gsl_HAVE(CONSTEXPR_14) #define gsl_constexpr14 constexpr #else #define gsl_constexpr14 /*constexpr*/ #endif #if gsl_HAVE(EXPLICIT) #define gsl_explicit explicit #else #define gsl_explicit /*explicit*/ #endif #if gsl_FEATURE(IMPLICIT_MACRO) #define implicit /*implicit*/ #endif #if gsl_HAVE(IS_DELETE) #define gsl_is_delete = delete #else #define gsl_is_delete #endif #if gsl_HAVE(IS_DELETE) #define gsl_is_delete_access public #else #define gsl_is_delete_access private #endif #if !gsl_HAVE(NOEXCEPT) || gsl_CONFIG(CONTRACT_VIOLATION_THROWS_V) #define gsl_noexcept /*noexcept*/ #else #define gsl_noexcept noexcept #endif #if gsl_HAVE(NULLPTR) #define gsl_nullptr nullptr #else #define gsl_nullptr NULL #endif #define gsl_DIMENSION_OF(a) (sizeof(a) / sizeof(0 [a])) // Other features: #define gsl_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR \ (gsl_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG && gsl_HAVE_CONTAINER_DATA_METHOD) // Note: !defined(__NVCC__) doesn't work with nvcc here: #define gsl_HAVE_UNCONSTRAINED_SPAN_CONTAINER_CTOR \ (gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR && (__NVCC__ == 0)) // GSL API (e.g. for CUDA platform): #ifndef gsl_api #ifdef __CUDACC__ #define gsl_api __host__ __device__ #else #define gsl_api /*gsl_api*/ #endif #endif // Additional includes: #if gsl_HAVE(ARRAY) #include #endif #if gsl_HAVE(INITIALIZER_LIST) #include #endif #if gsl_HAVE(TYPE_TRAITS) #include #elif gsl_HAVE(TR1_TYPE_TRAITS) #include #endif #if gsl_HAVE(SIZED_TYPES) #include #endif // MSVC warning suppression macros: #if gsl_COMPILER_MSVC_VERSION >= 140 #define gsl_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]] #define gsl_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress \ : code)) #define gsl_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable \ : codes)) #define gsl_RESTORE_MSVC_WARNINGS() __pragma(warning(pop)) #else #define gsl_SUPPRESS_MSGSL_WARNING(expr) #define gsl_SUPPRESS_MSVC_WARNING(code, descr) #define gsl_DISABLE_MSVC_WARNINGS(codes) #define gsl_RESTORE_MSVC_WARNINGS() #endif // Suppress the following MSVC GSL warnings: // - C26410: gsl::r.32: the parameter 'ptr' is a reference to const unique pointer, use const T* or const T& instead // - C26415: gsl::r.30: smart pointer parameter 'ptr' is used only to access contained pointer. Use T* or T& instead // - C26418: gsl::r.36: shared pointer parameter 'ptr' is not copied or moved. Use T* or T& instead // - C26472: gsl::t.1 : don't use a static_cast for arithmetic conversions; // use brace initialization, gsl::narrow_cast or gsl::narow // - C26439: gsl::f.6 : special function 'function' can be declared 'noexcept' // - C26440: gsl::f.6 : function 'function' can be declared 'noexcept' // - 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 // - C26482: gsl::b.2 : only index into arrays using constant expressions // - C26446: gdl::b.4 : prefer to use gsl::at() instead of unchecked subscript operator // - C26490: gsl::t.1 : don't use reinterpret_cast // - C26487: gsl::l.4 : don't return a pointer '('s result)' that may be invalid gsl_DISABLE_MSVC_WARNINGS(26410 26415 26418 26472 26439 26440 26473 26481 26482 26446 26490 26487) namespace gsl { // forward declare span<>: template class span; // C++11 emulation: namespace std11 { #if gsl_HAVE(ADD_CONST) using std::add_const; #elif gsl_HAVE(TR1_ADD_CONST) using std::tr1::add_const; #else template struct add_const { typedef const T type; }; #endif // gsl_HAVE( ADD_CONST ) #if gsl_HAVE(REMOVE_CONST) using std::remove_const; using std::remove_cv; using std::remove_volatile; #elif gsl_HAVE(TR1_REMOVE_CONST) using std::tr1::remove_const; using std::tr1::remove_cv; using std::tr1::remove_volatile; #else template struct remove_const { typedef T type; }; template struct remove_const { typedef T type; }; template struct remove_volatile { typedef T type; }; template struct remove_volatile { typedef T type; }; template struct remove_cv { typedef typename remove_volatile::type>::type type; }; #endif // gsl_HAVE( REMOVE_CONST ) #if gsl_HAVE(INTEGRAL_CONSTANT) using std::false_type; using std::integral_constant; using std::true_type; #elif gsl_HAVE(TR1_INTEGRAL_CONSTANT) using std::tr1::false_type; using std::tr1::integral_constant; using std::tr1::true_type; #else template struct integral_constant { enum { value = v }; }; typedef integral_constant true_type; typedef integral_constant false_type; #endif } // namespace std11 // C++17 emulation: namespace std17 { template struct bool_constant : std11::integral_constant {}; #if gsl_CPP11_120 template using void_t = void; #endif #if gsl_HAVE(STD_DATA) using std::data; using std::size; #elif gsl_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR) template inline gsl_constexpr auto size(const T (&)[N]) gsl_noexcept -> size_t { return N; } template inline gsl_constexpr auto size(C const& cont) -> decltype(cont.size()) { return cont.size(); } template inline gsl_constexpr auto data(T (&arr)[N]) gsl_noexcept -> T* { return &arr[0]; } template inline gsl_constexpr auto data(C& cont) -> decltype(cont.data()) { return cont.data(); } template inline gsl_constexpr auto data(C const& cont) -> decltype(cont.data()) { return cont.data(); } template inline gsl_constexpr auto data(std::initializer_list il) gsl_noexcept -> E const* { return il.begin(); } #endif // span_HAVE( DATA ) } // namespace std17 namespace detail { /// for nsel_REQUIRES_T /*enum*/ class enabler {}; #if gsl_HAVE(TYPE_TRAITS) template struct is_span_oracle : std::false_type {}; template struct is_span_oracle > : std::true_type {}; template struct is_span : is_span_oracle::type> {}; template struct is_std_array_oracle : std::false_type {}; #if gsl_HAVE(ARRAY) template struct is_std_array_oracle > : std::true_type {}; #endif template struct is_std_array : is_std_array_oracle::type> {}; template struct is_array : std::false_type {}; template struct is_array : std::true_type {}; template struct is_array : std::true_type {}; #if gsl_CPP11_140 && !gsl_BETWEEN(gsl_COMPILER_GNUC_VERSION, 1, 500) template struct has_size_and_data : std::false_type {}; template struct has_size_and_data< C, std17::void_t< decltype(std17::size(std::declval())), decltype(std17::data(std::declval()))> > : std::true_type {}; template struct is_compatible_element : std::false_type {}; template struct is_compatible_element< C, E, std17::void_t()))> > : std::is_convertible()))>::type (*)[], E (*)[]> {}; template struct is_container : std17::bool_constant< !is_span::value && !is_array::value && !is_std_array::value && has_size_and_data::value> {}; template struct is_compatible_container : std17::bool_constant< is_container::value && is_compatible_element::value> {}; #else // gsl_CPP11_140 template < class C, class E gsl_REQUIRES_T((!is_span::value && !is_array::value && !is_std_array::value && (std::is_convertible()))>::type (*)[], E (*)[]>::value) // && has_size_and_data< C >::value )), class = decltype(std17::size(std::declval())), class = decltype(std17::data(std::declval()))> struct is_compatible_container : std::true_type {}; #endif // gsl_CPP11_140 #endif // gsl_HAVE( TYPE_TRAITS ) } // namespace detail // // GSL.util: utilities // // index type for all container indexes/subscripts/sizes typedef gsl_CONFIG_SPAN_INDEX_TYPE index; // p0122r3 uses std::ptrdiff_t // // GSL.owner: ownership pointers // #if gsl_HAVE(SHARED_PTR) using std::make_shared; using std::shared_ptr; using std::unique_ptr; #if gsl_HAVE(MAKE_UNIQUE) using std::make_unique; #endif #endif #if gsl_HAVE(ALIAS_TEMPLATE) #if gsl_HAVE(TYPE_TRAITS) template ::value)> using owner = T; #else template using owner = T; #endif #else template struct owner { typedef T type; }; #endif #define gsl_HAVE_OWNER_TEMPLATE gsl_HAVE_ALIAS_TEMPLATE #if gsl_FEATURE(OWNER_MACRO) #if gsl_HAVE(OWNER_TEMPLATE) #define Owner(t) ::gsl::owner #else #define Owner(t) ::gsl::owner::type #endif #endif // // GSL.assert: assertions // #if gsl_HAVE(TYPE_TRAITS) #define gsl_ELIDE_CONTRACT(x) static_assert(::std::is_convertible::value, "argument of contract check must be convertible to bool") #else #define gsl_ELIDE_CONTRACT(x) #endif #if defined(__CUDACC__) && defined(__CUDA_ARCH__) #define gsl_ASSUME(x) gsl_ELIDE_CONTRACT(x) /* there is no assume intrinsic in CUDA device code */ #elif gsl_COMPILER_MSVC_VERSION #define gsl_ASSUME(x) __assume(x) #elif gsl_COMPILER_GNUC_VERSION #define gsl_ASSUME(x) ((x) ? static_cast(0) : __builtin_unreachable()) #elif defined(__has_builtin) #if __has_builtin(__builtin_unreachable) #define gsl_ASSUME(x) ((x) ? static_cast(0) : __builtin_unreachable()) #endif #else #define gsl_ASSUME(x) gsl_ELIDE_CONTRACT(x) /* unknown compiler; cannot rely on assume intrinsic */ #endif #define gsl_ELIDE_CONTRACT_EXPECTS (0 == (gsl_CONFIG_CONTRACT_LEVEL_MASK & 0x01)) #define gsl_ELIDE_CONTRACT_ENSURES (0 == (gsl_CONFIG_CONTRACT_LEVEL_MASK & 0x10)) #define gsl_ASSUME_CONTRACT_EXPECTS (0 != (gsl_CONFIG_CONTRACT_LEVEL_MASK & 0x04)) #define gsl_ASSUME_CONTRACT_ENSURES (0 != (gsl_CONFIG_CONTRACT_LEVEL_MASK & 0x40)) #define gsl_ELIDE_CONTRACT_EXPECTS_AUDIT (0 == (gsl_CONFIG_CONTRACT_LEVEL_MASK & 0x02)) #define gsl_ELIDE_CONTRACT_ENSURES_AUDIT (0 == (gsl_CONFIG_CONTRACT_LEVEL_MASK & 0x20)) #if gsl_ELIDE_CONTRACT_EXPECTS #if gsl_ASSUME_CONTRACT_EXPECTS #define Expects(x) gsl_ASSUME(x) #else #define Expects(x) gsl_ELIDE_CONTRACT(x) #endif #elif gsl_CONFIG(CONTRACT_VIOLATION_THROWS_V) #define Expects(x) ::gsl::fail_fast_assert((x), "GSL: Precondition failure at " __FILE__ ":" gsl_STRINGIFY(__LINE__)) #elif gsl_CONFIG(CONTRACT_VIOLATION_CALLS_HANDLER_V) #define Expects(x) ::gsl::fail_fast_assert((x), #x, "GSL: Precondition failure", __FILE__, __LINE__) #else #define Expects(x) ::gsl::fail_fast_assert((x)) #endif #if gsl_ELIDE_CONTRACT_EXPECTS_AUDIT #define ExpectsAudit(x) gsl_ELIDE_CONTRACT(x) #elif gsl_CONFIG(CONTRACT_VIOLATION_THROWS_V) #define ExpectsAudit(x) ::gsl::fail_fast_assert((x), "GSL: Precondition failure at " __FILE__ ":" gsl_STRINGIFY(__LINE__)) #elif gsl_CONFIG(CONTRACT_VIOLATION_CALLS_HANDLER_V) #define ExpectsAudit(x) ::gsl::fail_fast_assert((x), #x, "GSL: Precondition failure", __FILE__, __LINE__) #else #define ExpectsAudit(x) ::gsl::fail_fast_assert((x)) #endif #if gsl_ELIDE_CONTRACT_ENSURES #if gsl_ASSUME_CONTRACT_ENSURES #define Ensures(x) gsl_ASSUME(x) #else #define Ensures(x) gsl_ELIDE_CONTRACT(x) #endif #elif gsl_CONFIG(CONTRACT_VIOLATION_THROWS_V) #define Ensures(x) ::gsl::fail_fast_assert((x), "GSL: Postcondition failure at " __FILE__ ":" gsl_STRINGIFY(__LINE__)) #elif gsl_CONFIG(CONTRACT_VIOLATION_CALLS_HANDLER_V) #define Ensures(x) ::gsl::fail_fast_assert((x), #x, "GSL: Postcondition failure", __FILE__, __LINE__) #else #define Ensures(x) ::gsl::fail_fast_assert((x)) #endif #if gsl_ELIDE_CONTRACT_ENSURES_AUDIT #define EnsuresAudit(x) gsl_ELIDE_CONTRACT(x) #elif gsl_CONFIG(CONTRACT_VIOLATION_THROWS_V) #define EnsuresAudit(x) ::gsl::fail_fast_assert((x), "GSL: Postcondition failure at " __FILE__ ":" gsl_STRINGIFY(__LINE__)) #elif gsl_CONFIG(CONTRACT_VIOLATION_CALLS_HANDLER_V) #define EnsuresAudit(x) ::gsl::fail_fast_assert((x), #x, "GSL: Postcondition failure", __FILE__, __LINE__) #else #define EnsuresAudit(x) ::gsl::fail_fast_assert((x)) #endif #define gsl_STRINGIFY(x) gsl_STRINGIFY_(x) #define gsl_STRINGIFY_(x) #x struct fail_fast : public std::logic_error { gsl_api explicit fail_fast(char const* const message) : std::logic_error(message) {} }; #if gsl_CONFIG(CONTRACT_VIOLATION_THROWS_V) gsl_api inline void fail_fast_assert(bool cond, char const* const message) { #ifdef __CUDA_ARCH__ assert(cond); #else // __CUDA_ARCH__ if (!cond) throw fail_fast(message); #endif // __CUDA_ARCH__ } #elif gsl_CONFIG(CONTRACT_VIOLATION_CALLS_HANDLER_V) // Should be defined by user gsl_api void fail_fast_assert_handler(char const* const expression, char const* const message, char const* const file, int line); gsl_api inline void fail_fast_assert(bool cond, char const* const expression, char const* const message, char const* const file, int line) { #ifdef __CUDA_ARCH__ assert(cond); #else // __CUDA_ARCH__ if (!cond) fail_fast_assert_handler(expression, message, file, line); #endif // __CUDA_ARCH__ } #else gsl_api inline void fail_fast_assert(bool cond) gsl_noexcept { #ifdef __CUDA_ARCH__ assert(cond); #else // __CUDA_ARCH__ if (!cond) std::terminate(); #endif // __CUDA_ARCH__ } #endif // // GSL.util: utilities // #if gsl_FEATURE(EXPERIMENTAL_RETURN_GUARD) // Add uncaught_exceptions for pre-2017 MSVC, GCC and Clang // Return unsigned char to save stack space, uncaught_exceptions can only increase by 1 in a scope namespace detail { inline unsigned char to_uchar(unsigned x) gsl_noexcept { return static_cast(x); } } // namespace detail namespace std11 { #if gsl_HAVE(UNCAUGHT_EXCEPTIONS) inline unsigned char uncaught_exceptions() gsl_noexcept { return detail::to_uchar(std::uncaught_exceptions()); } #elif gsl_COMPILER_MSVC_VERSION extern "C" char* __cdecl _getptd(); inline unsigned char uncaught_exceptions() gsl_noexcept { return detail::to_uchar(*reinterpret_cast(_getptd() + (sizeof(void*) == 8 ? 0x100 : 0x90))); } #elif gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_GNUC_VERSION extern "C" char* __cxa_get_globals(); inline unsigned char uncaught_exceptions() gsl_noexcept { return detail::to_uchar(*reinterpret_cast(__cxa_get_globals() + sizeof(void*))); } #endif } // namespace std11 #endif #if gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 110 template class final_action { public: gsl_api explicit final_action(F action) gsl_noexcept : action_(std::move(action)), invoke_(true) {} gsl_api final_action(final_action&& other) gsl_noexcept : action_(std::move(other.action_)), invoke_(other.invoke_) { other.invoke_ = false; } gsl_api virtual ~final_action() gsl_noexcept { if (invoke_) action_(); } gsl_is_delete_access : gsl_api final_action(final_action const&) gsl_is_delete; gsl_api final_action& operator=(final_action const&) gsl_is_delete; gsl_api final_action& operator=(final_action&&) gsl_is_delete; protected: gsl_api void dismiss() gsl_noexcept { invoke_ = false; } private: F action_; bool invoke_; }; template gsl_api inline final_action finally(F const& action) gsl_noexcept { return final_action(action); } template gsl_api inline final_action finally(F && action) gsl_noexcept { return final_action(std::forward(action)); } #if gsl_FEATURE(EXPERIMENTAL_RETURN_GUARD) template class final_action_return : public final_action { public: gsl_api explicit final_action_return(F&& action) gsl_noexcept : final_action(std::move(action)), exception_count(std11::uncaught_exceptions()) {} gsl_api final_action_return(final_action_return&& other) gsl_noexcept : final_action(std::move(other)), exception_count(std11::uncaught_exceptions()) {} gsl_api ~final_action_return() override { if (std11::uncaught_exceptions() != exception_count) this->dismiss(); } gsl_is_delete_access : gsl_api final_action_return(final_action_return const&) gsl_is_delete; gsl_api final_action_return& operator=(final_action_return const&) gsl_is_delete; private: unsigned char exception_count; }; template gsl_api inline final_action_return on_return(F const& action) gsl_noexcept { return final_action_return(action); } template gsl_api inline final_action_return on_return(F && action) gsl_noexcept { return final_action_return(std::forward(action)); } template class final_action_error : public final_action { public: gsl_api explicit final_action_error(F&& action) gsl_noexcept : final_action(std::move(action)), exception_count(std11::uncaught_exceptions()) {} gsl_api final_action_error(final_action_error&& other) gsl_noexcept : final_action(std::move(other)), exception_count(std11::uncaught_exceptions()) {} gsl_api ~final_action_error() override { if (std11::uncaught_exceptions() == exception_count) this->dismiss(); } gsl_is_delete_access : gsl_api final_action_error(final_action_error const&) gsl_is_delete; gsl_api final_action_error& operator=(final_action_error const&) gsl_is_delete; private: unsigned char exception_count; }; template gsl_api inline final_action_error on_error(F const& action) gsl_noexcept { return final_action_error(action); } template gsl_api inline final_action_error on_error(F && action) gsl_noexcept { return final_action_error(std::forward(action)); } #endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) #else // gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 110 class final_action { public: typedef void (*Action)(); gsl_api final_action(Action action) : action_(action), invoke_(true) {} gsl_api final_action(final_action const& other) : action_(other.action_), invoke_(other.invoke_) { other.invoke_ = false; } gsl_api virtual ~final_action() { if (invoke_) action_(); } protected: gsl_api void dismiss() { invoke_ = false; } private: gsl_api final_action& operator=(final_action const&); private: Action action_; mutable bool invoke_; }; template gsl_api inline final_action finally(F const& f) { return final_action((f)); } #if gsl_FEATURE(EXPERIMENTAL_RETURN_GUARD) class final_action_return : public final_action { public: gsl_api explicit final_action_return(Action action) : final_action(action), exception_count(std11::uncaught_exceptions()) {} gsl_api ~final_action_return() { if (std11::uncaught_exceptions() != exception_count) this->dismiss(); } private: gsl_api final_action_return& operator=(final_action_return const&); private: unsigned char exception_count; }; template gsl_api inline final_action_return on_return(F const& action) { return final_action_return(action); } class final_action_error : public final_action { public: gsl_api explicit final_action_error(Action action) : final_action(action), exception_count(std11::uncaught_exceptions()) {} gsl_api ~final_action_error() { if (std11::uncaught_exceptions() == exception_count) this->dismiss(); } private: gsl_api final_action_error& operator=(final_action_error const&); private: unsigned char exception_count; }; template gsl_api inline final_action_error on_error(F const& action) { return final_action_error(action); } #endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) #endif // gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION == 110 #if gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120 template gsl_api inline gsl_constexpr T narrow_cast(U && u) gsl_noexcept { return static_cast(std::forward(u)); } #else template gsl_api inline T narrow_cast(U u) gsl_noexcept { return static_cast(u); } #endif // gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120 struct narrowing_error : public std::exception {}; #if gsl_HAVE(TYPE_TRAITS) namespace detail { template struct is_same_signedness : public std::integral_constant::value == std::is_signed::value> {}; } // namespace detail #endif template gsl_api inline T narrow(U u) { T t = narrow_cast(u); if (static_cast(t) != u) { #if gsl_CONFIG(CONTRACT_VIOLATION_THROWS_V) throw narrowing_error(); #else std::terminate(); #endif } #if gsl_HAVE(TYPE_TRAITS) if (!detail::is_same_signedness::value && ((t < T()) != (u < U()))) #else // Don't assume T() works: if ((t < 0) != (u < 0)) #endif { #if gsl_CONFIG(CONTRACT_VIOLATION_THROWS_V) throw narrowing_error(); #else std::terminate(); #endif } return t; } // // at() - Bounds-checked way of accessing static arrays, std::array, std::vector. // template gsl_api inline gsl_constexpr14 T& at(T(&arr)[N], size_t pos) { Expects(pos < N); return arr[pos]; } template gsl_api inline gsl_constexpr14 typename Container::value_type& at(Container & cont, size_t pos) { Expects(pos < cont.size()); return cont[pos]; } template gsl_api inline gsl_constexpr14 typename Container::value_type const& at(Container const& cont, size_t pos) { Expects(pos < cont.size()); return cont[pos]; } #if gsl_HAVE(INITIALIZER_LIST) template gsl_api inline const gsl_constexpr14 T at(std::initializer_list cont, size_t pos) { Expects(pos < cont.size()); return *(cont.begin() + pos); } #endif template gsl_api inline gsl_constexpr T& at(span s, size_t pos) { return s.at(pos); } // // GSL.views: views // // // not_null<> - Wrap any indirection and enforce non-null. // template class not_null { #if gsl_CONFIG(NOT_NULL_EXPLICIT_CTOR) #define gsl_not_null_explicit explicit #else #define gsl_not_null_explicit /*explicit*/ #endif #if gsl_CONFIG(NOT_NULL_GET_BY_CONST_REF) typedef T const& get_result_t; #else typedef T get_result_t; #endif public: #if gsl_HAVE(TYPE_TRAITS) static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); #endif template ::value)) #endif > gsl_api gsl_constexpr14 gsl_not_null_explicit #if gsl_HAVE(RVALUE_REFERENCE) not_null(U&& u) : ptr_(std::forward(u)) #else not_null(U const& u) : ptr_(u) #endif { Expects(ptr_ != gsl_nullptr); } #undef gsl_not_null_explicit #if gsl_HAVE(IS_DEFAULT) ~not_null() = default; gsl_constexpr not_null(not_null&& other) = default; gsl_constexpr not_null(not_null const& other) = default; not_null& operator=(not_null&& other) = default; not_null& operator=(not_null const& other) = default; #else gsl_api ~not_null(){}; gsl_api gsl_constexpr not_null(not_null const& other) : ptr_(other.ptr_) {} gsl_api not_null& operator=(not_null const& other) { ptr_ = other.ptr_; return *this; } #if gsl_HAVE(RVALUE_REFERENCE) gsl_api gsl_constexpr not_null(not_null&& other) : ptr_(std::move(other.get())) {} gsl_api not_null& operator=(not_null&& other) { ptr_ = std::move(other.get()); return *this; } #endif #endif template ::value)) #endif > gsl_api gsl_constexpr not_null(not_null const& other) : ptr_(other.get()) { } gsl_api gsl_constexpr14 get_result_t get() const { // Without cheating and changing ptr_ from the outside, this check is superfluous: Ensures(ptr_ != gsl_nullptr); return ptr_; } gsl_api gsl_constexpr operator get_result_t() const { return get(); } gsl_api gsl_constexpr get_result_t operator->() const { return get(); } #if gsl_HAVE(DECLTYPE_AUTO) gsl_api gsl_constexpr decltype(auto) operator*() const { return *get(); } #endif gsl_is_delete_access : // prevent compilation when initialized with a nullptr or literal 0: #if gsl_HAVE(NULLPTR) gsl_api not_null(std::nullptr_t) gsl_is_delete; gsl_api not_null& operator=(std::nullptr_t) gsl_is_delete; #else gsl_api not_null(int) gsl_is_delete; gsl_api not_null& operator=(int) gsl_is_delete; #endif // unwanted operators...pointers only point to single objects! gsl_api not_null& operator++() gsl_is_delete; gsl_api not_null& operator--() gsl_is_delete; gsl_api not_null operator++(int) gsl_is_delete; gsl_api not_null operator--(int) gsl_is_delete; gsl_api not_null& operator+(size_t) gsl_is_delete; gsl_api not_null& operator+=(size_t) gsl_is_delete; gsl_api not_null& operator-(size_t) gsl_is_delete; gsl_api not_null& operator-=(size_t) gsl_is_delete; gsl_api not_null& operator+=(std::ptrdiff_t) gsl_is_delete; gsl_api not_null& operator-=(std::ptrdiff_t) gsl_is_delete; gsl_api void operator[](std::ptrdiff_t) const gsl_is_delete; private: T ptr_; }; // not_null with implicit constructor, allowing copy-initialization: template class not_null_ic : public not_null { public: template ::value)) #endif > gsl_api gsl_constexpr14 #if gsl_HAVE(RVALUE_REFERENCE) not_null_ic(U&& u) : not_null(std::forward(u)) #else not_null_ic(U const& u) : not_null(u) #endif { } }; // more not_null unwanted operators template std::ptrdiff_t operator-(not_null const&, not_null const&) gsl_is_delete; template not_null operator-(not_null const&, std::ptrdiff_t) gsl_is_delete; template not_null operator+(not_null const&, std::ptrdiff_t) gsl_is_delete; template not_null operator+(std::ptrdiff_t, not_null const&) gsl_is_delete; // not_null comparisons template gsl_api inline gsl_constexpr bool operator==(not_null const& l, not_null const& r) { return l.get() == r.get(); } template gsl_api inline gsl_constexpr bool operator<(not_null const& l, not_null const& r) { return l.get() < r.get(); } template gsl_api inline gsl_constexpr bool operator!=(not_null const& l, not_null const& r) { return !(l == r); } template gsl_api inline gsl_constexpr bool operator<=(not_null const& l, not_null const& r) { return !(r < l); } template gsl_api inline gsl_constexpr bool operator>(not_null const& l, not_null const& r) { return (r < l); } template gsl_api inline gsl_constexpr bool operator>=(not_null const& l, not_null const& r) { return !(l < r); } // // Byte-specific type. // #if gsl_HAVE(ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE) enum class gsl_may_alias byte : unsigned char {}; #else struct gsl_may_alias byte { typedef unsigned char type; type v; }; #endif #if gsl_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG) #define gsl_ENABLE_IF_INTEGRAL_T(T) \ gsl_REQUIRES_T((std::is_integral::value)) #else #define gsl_ENABLE_IF_INTEGRAL_T(T) #endif template gsl_api inline gsl_constexpr byte to_byte(T v) gsl_noexcept { #if gsl_HAVE(ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE) return static_cast(v); #elif gsl_HAVE(CONSTEXPR_11) return {static_cast(v)}; #else byte b = {static_cast(v)}; return b; #endif } template gsl_api inline gsl_constexpr IntegerType to_integer(byte b) gsl_noexcept { #if gsl_HAVE(ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE) return static_cast::type>(b); #else return b.v; #endif } gsl_api inline gsl_constexpr unsigned char to_uchar(byte b) gsl_noexcept { return to_integer(b); } gsl_api inline gsl_constexpr unsigned char to_uchar(int i) gsl_noexcept { return static_cast(i); } #if !gsl_HAVE(ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE) gsl_api inline gsl_constexpr bool operator==(byte l, byte r) gsl_noexcept { return l.v == r.v; } gsl_api inline gsl_constexpr bool operator!=(byte l, byte r) gsl_noexcept { return !(l == r); } gsl_api inline gsl_constexpr bool operator<(byte l, byte r) gsl_noexcept { return l.v < r.v; } gsl_api inline gsl_constexpr bool operator<=(byte l, byte r) gsl_noexcept { return !(r < l); } gsl_api inline gsl_constexpr bool operator>(byte l, byte r) gsl_noexcept { return (r < l); } gsl_api inline gsl_constexpr bool operator>=(byte l, byte r) gsl_noexcept { return !(l < r); } #endif template gsl_api inline gsl_constexpr14 byte& operator<<=(byte& b, IntegerType shift) gsl_noexcept { #if gsl_HAVE(ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE) return b = to_byte(to_uchar(b) << shift); #else b.v = to_uchar(b.v << shift); return b; #endif } template gsl_api inline gsl_constexpr byte operator<<(byte b, IntegerType shift) gsl_noexcept { return to_byte(to_uchar(b) << shift); } template gsl_api inline gsl_constexpr14 byte& operator>>=(byte& b, IntegerType shift) gsl_noexcept { #if gsl_HAVE(ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE) return b = to_byte(to_uchar(b) >> shift); #else b.v = to_uchar(b.v >> shift); return b; #endif } template gsl_api inline gsl_constexpr byte operator>>(byte b, IntegerType shift) gsl_noexcept { return to_byte(to_uchar(b) >> shift); } gsl_api inline gsl_constexpr14 byte& operator|=(byte& l, byte r) gsl_noexcept { #if gsl_HAVE(ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE) return l = to_byte(to_uchar(l) | to_uchar(r)); #else l.v = to_uchar(l) | to_uchar(r); return l; #endif } gsl_api inline gsl_constexpr byte operator|(byte l, byte r) gsl_noexcept { return to_byte(to_uchar(l) | to_uchar(r)); } gsl_api inline gsl_constexpr14 byte& operator&=(byte& l, byte r) gsl_noexcept { #if gsl_HAVE(ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE) return l = to_byte(to_uchar(l) & to_uchar(r)); #else l.v = to_uchar(l) & to_uchar(r); return l; #endif } gsl_api inline gsl_constexpr byte operator&(byte l, byte r)gsl_noexcept { return to_byte(to_uchar(l) & to_uchar(r)); } gsl_api inline gsl_constexpr14 byte& operator^=(byte& l, byte r) gsl_noexcept { #if gsl_HAVE(ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE) return l = to_byte(to_uchar(l) ^ to_uchar(r)); #else l.v = to_uchar(l) ^ to_uchar(r); return l; #endif } gsl_api inline gsl_constexpr byte operator^(byte l, byte r) gsl_noexcept { return to_byte(to_uchar(l) ^ to_uchar(r)); } gsl_api inline gsl_constexpr byte operator~(byte b) gsl_noexcept { return to_byte(~to_uchar(b)); } #if gsl_FEATURE_TO_STD(WITH_CONTAINER) // Tag to select span constructor taking a container (prevent ms-gsl warning C26426): struct with_container_t { gsl_constexpr with_container_t() gsl_noexcept {} }; const gsl_constexpr with_container_t with_container; #endif // // span<> - A 1D view of contiguous T's, replace (*,len). // template class span { template friend class span; public: typedef index index_type; typedef T element_type; typedef typename std11::remove_cv::type value_type; typedef T& reference; typedef T* pointer; typedef T const* const_pointer; typedef T const& const_reference; typedef pointer iterator; typedef const_pointer const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename std::iterator_traits::difference_type difference_type; // 26.7.3.2 Constructors, copy, and assignment [span.cons] gsl_api gsl_constexpr14 span() gsl_noexcept : first_(gsl_nullptr), last_(gsl_nullptr) { Expects(size() == 0); } #if !gsl_DEPRECATE_TO_LEVEL(5) #if gsl_HAVE(NULLPTR) gsl_api gsl_constexpr14 span(std::nullptr_t, index_type size_in) : first_(nullptr), last_(nullptr) { Expects(size_in == 0); } #endif #if gsl_HAVE(IS_DELETE) gsl_api gsl_constexpr span(reference data_in) : span(&data_in, 1) {} gsl_api gsl_constexpr span(element_type&&) = delete; #endif #endif // deprecate gsl_api gsl_constexpr14 span(pointer data_in, index_type size_in) : first_(data_in), last_(data_in + size_in) { Expects(size_in == 0 || (size_in > 0 && data_in != gsl_nullptr)); } gsl_api gsl_constexpr14 span(pointer first_in, pointer last_in) : first_(first_in), last_(last_in) { Expects(first_in <= last_in); } #if !gsl_DEPRECATE_TO_LEVEL(5) template gsl_api gsl_constexpr14 span(U*& data_in, index_type size_in) : first_(data_in), last_(data_in + size_in) { Expects(size_in == 0 || (size_in > 0 && data_in != gsl_nullptr)); } template gsl_api gsl_constexpr14 span(U* const& data_in, index_type size_in) : first_(data_in), last_(data_in + size_in) { Expects(size_in == 0 || (size_in > 0 && data_in != gsl_nullptr)); } #endif // deprecate #if !gsl_DEPRECATE_TO_LEVEL(5) template gsl_api gsl_constexpr span(U (&arr)[N]) gsl_noexcept : first_(gsl_ADDRESSOF(arr[0])), last_(gsl_ADDRESSOF(arr[0]) + N) {} #else template ::value)) #endif > gsl_api gsl_constexpr span(element_type (&arr)[N]) gsl_noexcept : first_(gsl_ADDRESSOF(arr[0])), last_(gsl_ADDRESSOF(arr[0]) + N) { } #endif // deprecate #if gsl_HAVE(ARRAY) #if !gsl_DEPRECATE_TO_LEVEL(5) template gsl_api gsl_constexpr span(std::array& arr) : first_(arr.data()), last_(arr.data() + N) {} template gsl_api gsl_constexpr span(std::array const& arr) : first_(arr.data()), last_(arr.data() + N) {} #else template ::value)) #endif > gsl_api gsl_constexpr span(std::array& arr) : first_(arr.data()), last_(arr.data() + N) { } template ::value)) #endif > gsl_api gsl_constexpr span(std::array const& arr) : first_(arr.data()), last_(arr.data() + N) { } #endif // deprecate #endif // gsl_HAVE( ARRAY ) #if gsl_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR) template ::value))> gsl_api gsl_constexpr span(Container& cont) : first_(std17::data(cont)), last_(std17::data(cont) + std17::size(cont)) {} template ::value && detail::is_compatible_container::value))> gsl_api gsl_constexpr span(Container const& cont) : first_(std17::data(cont)), last_(std17::data(cont) + std17::size(cont)) {} #elif gsl_HAVE(UNCONSTRAINED_SPAN_CONTAINER_CTOR) template gsl_api gsl_constexpr span(Container& cont) : first_(cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF(cont[0])), last_(cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF(cont[0]) + cont.size()) {} template gsl_api gsl_constexpr span(Container const& cont) : first_(cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF(cont[0])), last_(cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF(cont[0]) + cont.size()) {} #endif #if gsl_FEATURE_TO_STD(WITH_CONTAINER) template gsl_api gsl_constexpr span(with_container_t, Container& cont) : first_(cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF(cont[0])), last_(cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF(cont[0]) + cont.size()) {} template gsl_api gsl_constexpr span(with_container_t, Container const& cont) : first_(cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF(cont[0])), last_(cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF(cont[0]) + cont.size()) {} #endif #if !gsl_DEPRECATE_TO_LEVEL(4) // constructor taking shared_ptr deprecated since 0.29.0 #if gsl_HAVE(SHARED_PTR) gsl_api gsl_constexpr span(shared_ptr const& ptr) : first_(ptr.get()), last_(ptr.get() ? ptr.get() + 1 : gsl_nullptr) {} #endif // constructors taking unique_ptr deprecated since 0.29.0 #if gsl_HAVE(UNIQUE_PTR) #if gsl_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG) template ::type> #else template #endif gsl_api gsl_constexpr span(unique_ptr const& ptr, index_type count) : first_(ptr.get()), last_(ptr.get() + count) { } gsl_api gsl_constexpr span(unique_ptr const& ptr) : first_(ptr.get()), last_(ptr.get() ? ptr.get() + 1 : gsl_nullptr) {} #endif #endif // deprecate shared_ptr, unique_ptr #if gsl_HAVE(IS_DEFAULT) && !gsl_BETWEEN(gsl_COMPILER_GNUC_VERSION, 430, 600) gsl_constexpr span(span&&) gsl_noexcept = default; gsl_constexpr span(span const&) = default; #else gsl_api gsl_constexpr span(span const& other) : first_(other.begin()), last_(other.end()) {} #endif #if gsl_HAVE(IS_DEFAULT) ~span() = default; #else ~span() {} #endif #if gsl_HAVE(IS_DEFAULT) gsl_constexpr14 span& operator=(span&&) gsl_noexcept = default; gsl_constexpr14 span& operator=(span const&) gsl_noexcept = default; #else gsl_api span& operator=(span other) gsl_noexcept { other.swap(*this); return *this; } #endif template ::value)) #endif > gsl_api gsl_constexpr span(span const& other) : first_(other.begin()), last_(other.end()) { } #if 0 // Converting from other span ? template< class U > operator=(); #endif // 26.7.3.3 Subviews [span.sub] gsl_api gsl_constexpr14 span first(index_type count) const gsl_noexcept { Expects(count <= this->size()); return span(this->data(), count); } gsl_api gsl_constexpr14 span last(index_type count) const gsl_noexcept { Expects(count <= this->size()); return span(this->data() + this->size() - count, count); } gsl_api gsl_constexpr14 span subspan(index_type offset) const gsl_noexcept { Expects(offset <= this->size()); return span(this->data() + offset, this->size() - offset); } gsl_api gsl_constexpr14 span subspan(index_type offset, index_type count) const gsl_noexcept { Expects( offset <= this->size() && count <= this->size() - offset); return span(this->data() + offset, count); } // 26.7.3.4 Observers [span.obs] gsl_api gsl_constexpr index_type size() const gsl_noexcept { return narrow_cast(last_ - first_); } gsl_api gsl_constexpr std::ptrdiff_t ssize() const gsl_noexcept { return narrow_cast(last_ - first_); } gsl_api gsl_constexpr index_type size_bytes() const gsl_noexcept { return size() * narrow_cast(sizeof(element_type)); } gsl_api gsl_constexpr bool empty() const gsl_noexcept { return size() == 0; } // 26.7.3.5 Element access [span.elem] gsl_api gsl_constexpr reference operator[](index_type pos) const { return at(pos); } gsl_api gsl_constexpr reference operator()(index_type pos) const { return at(pos); } gsl_api gsl_constexpr14 reference at(index_type pos) const { Expects(pos < size()); return first_[pos]; } gsl_api gsl_constexpr pointer data() const gsl_noexcept { return first_; } // 26.7.3.6 Iterator support [span.iterators] gsl_api gsl_constexpr iterator begin() const gsl_noexcept { return iterator(first_); } gsl_api gsl_constexpr iterator end() const gsl_noexcept { return iterator(last_); } gsl_api gsl_constexpr const_iterator cbegin() const gsl_noexcept { #if gsl_CPP11_OR_GREATER return {begin()}; #else return const_iterator(begin()); #endif } gsl_api gsl_constexpr const_iterator cend() const gsl_noexcept { #if gsl_CPP11_OR_GREATER return {end()}; #else return const_iterator(end()); #endif } gsl_api gsl_constexpr reverse_iterator rbegin() const gsl_noexcept { return reverse_iterator(end()); } gsl_api gsl_constexpr reverse_iterator rend() const gsl_noexcept { return reverse_iterator(begin()); } gsl_api gsl_constexpr const_reverse_iterator crbegin() const gsl_noexcept { return const_reverse_iterator(cend()); } gsl_api gsl_constexpr const_reverse_iterator crend() const gsl_noexcept { return const_reverse_iterator(cbegin()); } gsl_api void swap(span& other) gsl_noexcept { using std::swap; swap(first_, other.first_); swap(last_, other.last_); } #if !gsl_DEPRECATE_TO_LEVEL(3) // member length() deprecated since 0.29.0 gsl_api gsl_constexpr index_type length() const gsl_noexcept { return size(); } // member length_bytes() deprecated since 0.29.0 gsl_api gsl_constexpr index_type length_bytes() const gsl_noexcept { return size_bytes(); } #endif #if !gsl_DEPRECATE_TO_LEVEL(2) // member as_bytes(), as_writeable_bytes deprecated since 0.17.0 gsl_api span as_bytes() const gsl_noexcept { return span(reinterpret_cast(data()), size_bytes()); // NOLINT } gsl_api span as_writeable_bytes() const gsl_noexcept { return span(reinterpret_cast(data()), size_bytes()); // NOLINT } #endif template gsl_api span as_span() const gsl_noexcept { Expects((this->size_bytes() % sizeof(U)) == 0); return span(reinterpret_cast(this->data()), this->size_bytes() / sizeof(U)); // NOLINT } private: pointer first_; pointer last_; }; // class template argument deduction guides: #if gsl_HAVE(DEDUCTION_GUIDES) // gsl_CPP17_OR_GREATER template span(T(&)[N])->span; template span(std::array&)->span; template span(std::array const&)->span; template span(Container&)->span; template span(Container const&)->span; #endif // gsl_HAVE( DEDUCTION_GUIDES ) // 26.7.3.7 Comparison operators [span.comparison] #if gsl_CONFIG(ALLOWS_NONSTRICT_SPAN_COMPARISON) template gsl_api inline gsl_constexpr bool operator==(span const& l, span const& r) { return l.size() == r.size() && (l.begin() == r.begin() || std::equal(l.begin(), l.end(), r.begin())); } template gsl_api inline gsl_constexpr bool operator<(span const& l, span const& r) { return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); } #else template gsl_api inline gsl_constexpr bool operator==(span const& l, span const& r) { return l.size() == r.size() && (l.begin() == r.begin() || std::equal(l.begin(), l.end(), r.begin())); } template gsl_api inline gsl_constexpr bool operator<(span const& l, span const& r) { return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); } #endif template gsl_api inline gsl_constexpr bool operator!=(span const& l, span const& r) { return !(l == r); } template gsl_api inline gsl_constexpr bool operator<=(span const& l, span const& r) { return !(r < l); } template gsl_api inline gsl_constexpr bool operator>(span const& l, span const& r) { return (r < l); } template gsl_api inline gsl_constexpr bool operator>=(span const& l, span const& r) { return !(l < r); } // span algorithms template gsl_api inline gsl_constexpr std::size_t size(span const& spn) { return static_cast(spn.size()); } template gsl_api inline gsl_constexpr std::ptrdiff_t ssize(span const& spn) { return spn.ssize(); } namespace detail { template gsl_api inline OI copy_n(II first, N count, OI result) { if (count > 0) { *result++ = *first; for (N i = 1; i < count; ++i) { *result++ = *++first; } } return result; } } // namespace detail template gsl_api inline void copy(span src, span dest) { #if gsl_CPP14_OR_GREATER // gsl_HAVE( TYPE_TRAITS ) (circumvent Travis clang 3.4) static_assert(std::is_assignable::value, "Cannot assign elements of source span to elements of destination span"); #endif Expects(dest.size() >= src.size()); detail::copy_n(src.data(), src.size(), dest.data()); } // span creator functions (see ctors) template gsl_api inline span as_bytes(span spn) gsl_noexcept { return span(reinterpret_cast(spn.data()), spn.size_bytes()); // NOLINT } template gsl_api inline span as_writeable_bytes(span spn) gsl_noexcept { return span(reinterpret_cast(spn.data()), spn.size_bytes()); // NOLINT } #if gsl_FEATURE_TO_STD(MAKE_SPAN) template gsl_api inline gsl_constexpr span make_span(T * ptr, typename span::index_type count) { return span(ptr, count); } template gsl_api inline gsl_constexpr span make_span(T * first, T * last) { return span(first, last); } template gsl_api inline gsl_constexpr span make_span(T(&arr)[N]) { return span(gsl_ADDRESSOF(arr[0]), N); } #if gsl_HAVE(ARRAY) template gsl_api inline gsl_constexpr span make_span(std::array & arr) { return span(arr); } template gsl_api inline gsl_constexpr span make_span(std::array const& arr) { return span(arr); } #endif #if gsl_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR) && gsl_HAVE(AUTO) template ()))> gsl_api inline gsl_constexpr auto make_span(Container & cont) ->span::type> { return span::type>(cont); } template ()))> gsl_api inline gsl_constexpr auto make_span(Container const& cont) ->span::type> { return span::type>(cont); } #else template gsl_api inline span make_span(std::vector & cont) { return span(with_container, cont); } template gsl_api inline span make_span(std::vector const& cont) { return span(with_container, cont); } #endif #if gsl_FEATURE_TO_STD(WITH_CONTAINER) template gsl_api inline gsl_constexpr span make_span(with_container_t, Container & cont) gsl_noexcept { return span(with_container, cont); } template gsl_api inline gsl_constexpr span make_span(with_container_t, Container const& cont) gsl_noexcept { return span(with_container, cont); } #endif // gsl_FEATURE_TO_STD( WITH_CONTAINER ) template gsl_api inline span make_span(Ptr & ptr) { return span(ptr); } template gsl_api inline span make_span(Ptr & ptr, typename span::index_type count) { return span(ptr, count); } #endif // gsl_FEATURE_TO_STD( MAKE_SPAN ) #if gsl_FEATURE_TO_STD(BYTE_SPAN) template gsl_api inline gsl_constexpr span byte_span(T & t) gsl_noexcept { return span(reinterpret_cast(&t), sizeof(T)); } template gsl_api inline gsl_constexpr span byte_span(T const& t) gsl_noexcept { return span(reinterpret_cast(&t), sizeof(T)); } #endif // gsl_FEATURE_TO_STD( BYTE_SPAN ) // // basic_string_span: // template class basic_string_span; namespace detail { template struct is_basic_string_span_oracle : std11::false_type {}; template struct is_basic_string_span_oracle > : std11::true_type {}; template struct is_basic_string_span : is_basic_string_span_oracle::type> {}; template gsl_api inline gsl_constexpr14 std::size_t string_length(T* ptr, std::size_t max) { if (ptr == gsl_nullptr || max <= 0) return 0; std::size_t len = 0; while (len < max && ptr[len]) // NOLINT ++len; return len; } } // namespace detail // // basic_string_span<> - A view of contiguous characters, replace (*,len). // template class basic_string_span { public: typedef T element_type; typedef span span_type; typedef typename span_type::index_type index_type; typedef typename span_type::difference_type difference_type; typedef typename span_type::pointer pointer; typedef typename span_type::reference reference; typedef typename span_type::iterator iterator; typedef typename span_type::const_iterator const_iterator; typedef typename span_type::reverse_iterator reverse_iterator; typedef typename span_type::const_reverse_iterator const_reverse_iterator; // construction: #if gsl_HAVE(IS_DEFAULT) gsl_constexpr basic_string_span() gsl_noexcept = default; #else gsl_api gsl_constexpr basic_string_span() gsl_noexcept {} #endif #if gsl_HAVE(NULLPTR) gsl_api gsl_constexpr basic_string_span(std::nullptr_t ptr) gsl_noexcept : span_(ptr, index_type(0)) {} #endif gsl_api gsl_constexpr basic_string_span(pointer ptr) : span_(remove_z(ptr, (std::numeric_limits::max)())) {} gsl_api gsl_constexpr basic_string_span(pointer ptr, index_type count) : span_(ptr, count) {} gsl_api gsl_constexpr basic_string_span(pointer firstElem, pointer lastElem) : span_(firstElem, lastElem) {} template gsl_api gsl_constexpr basic_string_span(element_type (&arr)[N]) : span_(remove_z(gsl_ADDRESSOF(arr[0]), N)) {} #if gsl_HAVE(ARRAY) template gsl_api gsl_constexpr basic_string_span(std::array::type, N>& arr) : span_(remove_z(arr)) {} template gsl_api gsl_constexpr basic_string_span(std::array::type, N> const& arr) : span_(remove_z(arr)) {} #endif #if gsl_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR) // Exclude: array, [basic_string,] basic_string_span template ::value && !detail::is_basic_string_span::value && std::is_convertible::value && std::is_convertible().data())>::value))> gsl_api gsl_constexpr basic_string_span(Container& cont) : span_((cont)) {} // Exclude: array, [basic_string,] basic_string_span template ::value && !detail::is_basic_string_span::value && std::is_convertible::value && std::is_convertible().data())>::value))> gsl_api gsl_constexpr basic_string_span(Container const& cont) : span_((cont)) {} #elif gsl_HAVE(UNCONSTRAINED_SPAN_CONTAINER_CTOR) template gsl_api gsl_constexpr basic_string_span(Container& cont) : span_(cont) {} template gsl_api gsl_constexpr basic_string_span(Container const& cont) : span_(cont) {} #else template gsl_api gsl_constexpr basic_string_span(span const& rhs) : span_(rhs) {} #endif #if gsl_FEATURE_TO_STD(WITH_CONTAINER) template gsl_api gsl_constexpr basic_string_span(with_container_t, Container& cont) : span_(with_container, cont) {} #endif #if gsl_HAVE(IS_DEFAULT) #if gsl_BETWEEN(gsl_COMPILER_GNUC_VERSION, 440, 600) gsl_constexpr basic_string_span(basic_string_span const& rhs) = default; gsl_constexpr basic_string_span(basic_string_span&& rhs) = default; #else gsl_constexpr basic_string_span(basic_string_span const& rhs) gsl_noexcept = default; gsl_constexpr basic_string_span(basic_string_span&& rhs) gsl_noexcept = default; #endif #endif template ::pointer, pointer>::value)) #endif > gsl_api gsl_constexpr basic_string_span(basic_string_span const& rhs) : span_(reinterpret_cast(rhs.data()), rhs.length()) // NOLINT { } #if gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120 template ::pointer, pointer>::value))> gsl_api gsl_constexpr basic_string_span(basic_string_span&& rhs) : span_(reinterpret_cast(rhs.data()), rhs.length()) // NOLINT {} #endif template gsl_api gsl_constexpr basic_string_span( std::basic_string::type, CharTraits, Allocator>& str) : span_(gsl_ADDRESSOF(str[0]), str.length()) {} template gsl_api gsl_constexpr basic_string_span( std::basic_string::type, CharTraits, Allocator> const& str) : span_(gsl_ADDRESSOF(str[0]), str.length()) {} // destruction, assignment: #if gsl_HAVE(IS_DEFAULT) ~basic_string_span() gsl_noexcept = default; basic_string_span& operator=(basic_string_span const& rhs) gsl_noexcept = default; basic_string_span& operator=(basic_string_span&& rhs) gsl_noexcept = default; #endif // sub span: gsl_api gsl_constexpr basic_string_span first(index_type count) const { return span_.first(count); } gsl_api gsl_constexpr basic_string_span last(index_type count) const { return span_.last(count); } gsl_api gsl_constexpr basic_string_span subspan(index_type offset) const { return span_.subspan(offset); } gsl_api gsl_constexpr basic_string_span subspan(index_type offset, index_type count) const { return span_.subspan(offset, count); } // observers: gsl_api gsl_constexpr index_type length() const gsl_noexcept { return span_.size(); } gsl_api gsl_constexpr index_type size() const gsl_noexcept { return span_.size(); } gsl_api gsl_constexpr index_type length_bytes() const gsl_noexcept { return span_.size_bytes(); } gsl_api gsl_constexpr index_type size_bytes() const gsl_noexcept { return span_.size_bytes(); } gsl_api gsl_constexpr bool empty() const gsl_noexcept { return size() == 0; } gsl_api gsl_constexpr reference operator[](index_type idx) const { return span_[idx]; } gsl_api gsl_constexpr reference operator()(index_type idx) const { return span_[idx]; } gsl_api gsl_constexpr pointer data() const gsl_noexcept { return span_.data(); } gsl_api iterator begin() const gsl_noexcept { return span_.begin(); } gsl_api iterator end() const gsl_noexcept { return span_.end(); } gsl_api reverse_iterator rbegin() const gsl_noexcept { return span_.rbegin(); } gsl_api reverse_iterator rend() const gsl_noexcept { return span_.rend(); } // const version not in p0123r2: gsl_api const_iterator cbegin() const gsl_noexcept { return span_.cbegin(); } gsl_api const_iterator cend() const gsl_noexcept { return span_.cend(); } gsl_api const_reverse_iterator crbegin() const gsl_noexcept { return span_.crbegin(); } gsl_api const_reverse_iterator crend() const gsl_noexcept { return span_.crend(); } private: gsl_api static gsl_constexpr14 span_type remove_z(pointer const& sz, std::size_t max) { return span_type(sz, detail::string_length(sz, max)); } #if gsl_HAVE(ARRAY) template gsl_api static gsl_constexpr14 span_type remove_z(std::array::type, N>& arr) { return remove_z(gsl_ADDRESSOF(arr[0]), narrow_cast(N)); } template gsl_api static gsl_constexpr14 span_type remove_z(std::array::type, N> const& arr) { return remove_z(gsl_ADDRESSOF(arr[0]), narrow_cast(N)); } #endif private: span_type span_; }; // basic_string_span comparison functions: #if gsl_CONFIG(ALLOWS_NONSTRICT_SPAN_COMPARISON) template gsl_api inline gsl_constexpr14 bool operator==(basic_string_span const& l, U const& u) gsl_noexcept { const basic_string_span::type> r(u); return l.size() == r.size() && std::equal(l.begin(), l.end(), r.begin()); } template gsl_api inline gsl_constexpr14 bool operator<(basic_string_span const& l, U const& u) gsl_noexcept { const basic_string_span::type> r(u); return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); } #if gsl_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG) template ::value))> gsl_api inline gsl_constexpr14 bool operator==(U const& u, basic_string_span const& r) gsl_noexcept { const basic_string_span::type> l(u); return l.size() == r.size() && std::equal(l.begin(), l.end(), r.begin()); } template ::value))> gsl_api inline gsl_constexpr14 bool operator<(U const& u, basic_string_span const& r) gsl_noexcept { const basic_string_span::type> l(u); return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); } #endif #else //gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template gsl_api inline gsl_constexpr14 bool operator==(basic_string_span const& l, basic_string_span const& r) gsl_noexcept { return l.size() == r.size() && std::equal(l.begin(), l.end(), r.begin()); } template gsl_api inline gsl_constexpr14 bool operator<(basic_string_span const& l, basic_string_span const& r) gsl_noexcept { return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); } #endif // gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template gsl_api inline gsl_constexpr14 bool operator!=(basic_string_span const& l, U const& r) gsl_noexcept { return !(l == r); } template gsl_api inline gsl_constexpr14 bool operator<=(basic_string_span const& l, U const& r) gsl_noexcept { #if gsl_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG) || !gsl_CONFIG(ALLOWS_NONSTRICT_SPAN_COMPARISON) return !(r < l); #else basic_string_span::type> rr(r); return !(rr < l); #endif } template gsl_api inline gsl_constexpr14 bool operator>(basic_string_span const& l, U const& r) gsl_noexcept { #if gsl_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG) || !gsl_CONFIG(ALLOWS_NONSTRICT_SPAN_COMPARISON) return (r < l); #else basic_string_span::type> rr(r); return (rr < l); #endif } template gsl_api inline gsl_constexpr14 bool operator>=(basic_string_span const& l, U const& r) gsl_noexcept { return !(l < r); } #if gsl_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG) template ::value))> gsl_api inline gsl_constexpr14 bool operator!=(U const& l, basic_string_span const& r) gsl_noexcept { return !(l == r); } template ::value))> gsl_api inline gsl_constexpr14 bool operator<=(U const& l, basic_string_span const& r) gsl_noexcept { return !(r < l); } template ::value))> gsl_api inline gsl_constexpr14 bool operator>(U const& l, basic_string_span const& r) gsl_noexcept { return (r < l); } template ::value))> gsl_api inline gsl_constexpr14 bool operator>=(U const& l, basic_string_span const& r) gsl_noexcept { return !(l < r); } #endif // gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) // convert basic_string_span to byte span: template gsl_api inline span as_bytes(basic_string_span spn) gsl_noexcept { return span(reinterpret_cast(spn.data()), spn.size_bytes()); // NOLINT } // // String types: // typedef char* zstring; typedef const char* czstring; #if gsl_HAVE(WCHAR) typedef wchar_t* zwstring; typedef const wchar_t* cwzstring; #endif typedef basic_string_span string_span; typedef basic_string_span cstring_span; #if gsl_HAVE(WCHAR) typedef basic_string_span wstring_span; typedef basic_string_span cwstring_span; #endif // to_string() allow (explicit) conversions from string_span to string #if 0 template< class T > gsl_api inline std::basic_string< typename std::remove_const::type > to_string( basic_string_span spn ) { std::string( spn.data(), spn.length() ); } #else gsl_api inline std::string to_string(string_span const& spn) { return std::string(spn.data(), spn.length()); } gsl_api inline std::string to_string(cstring_span const& spn) { return std::string(spn.data(), spn.length()); } #if gsl_HAVE(WCHAR) gsl_api inline std::wstring to_string(wstring_span const& spn) { return std::wstring(spn.data(), spn.length()); } gsl_api inline std::wstring to_string(cwstring_span const& spn) { return std::wstring(spn.data(), spn.length()); } #endif // gsl_HAVE( WCHAR ) #endif // to_string() // Disable stream support since Apple std lib is broken #if 0 // Apple stream // // Stream output for string_span types // namespace detail { #ifdef __APPLE__ using streamoff = long long; using streamsize = long long; #else using streamsize = std::streamsize; using streamoff = std::streamoff; #endif template gsl_api void write_padding(Stream& os, streamsize n) { for (streamsize i = 0; i < n; ++i) os.rdbuf()->sputc(os.fill()); } template gsl_api Stream& write_to_stream(Stream& os, Span const& spn) { typename Stream::sentry sentry(os); if (!os) return os; const streamsize length = narrow(spn.length()); // Whether, and how, to pad const bool pad = (length < os.width()); const bool left_pad = pad && (os.flags() & std::ios_base::adjustfield) == std::ios_base::right; if (left_pad) write_padding(os, os.width() - length); // Write span characters os.rdbuf()->sputn(spn.begin(), length); if (pad && !left_pad) write_padding(os, os.width() - length); // Reset output stream width os.width(0); return os; } } // namespace detail template gsl_api std::basic_ostream& operator<<(std::basic_ostream& os, string_span const& spn) { return detail::write_to_stream(os, spn); } template gsl_api std::basic_ostream& operator<<(std::basic_ostream& os, cstring_span const& spn) { return detail::write_to_stream(os, spn); } #if gsl_HAVE(WCHAR) template gsl_api std::basic_ostream& operator<<(std::basic_ostream& os, wstring_span const& spn) { return detail::write_to_stream(os, spn); } template gsl_api std::basic_ostream& operator<<(std::basic_ostream& os, cwstring_span const& spn) { return detail::write_to_stream(os, spn); } #endif // gsl_HAVE( WCHAR ) #endif // Apple stream // // ensure_sentinel() // // Provides a way to obtain a span from a contiguous sequence // that ends with a (non-inclusive) sentinel value. // // Will fail-fast if sentinel cannot be found before max elements are examined. // namespace detail { template gsl_api static span ensure_sentinel(T* seq, SizeType max = (std::numeric_limits::max)()) { typedef T* pointer; gsl_SUPPRESS_MSVC_WARNING(26429, "f.23: symbol 'cur' is never tested for nullness, it can be marked as not_null") pointer cur = seq; while (static_cast(cur - seq) < max && *cur != Sentinel) ++cur; Expects(*cur == Sentinel); return span(seq, narrow_cast::index_type>(cur - seq)); } } // namespace detail // // ensure_z - creates a string_span for a czstring or cwzstring. // Will fail fast if a null-terminator cannot be found before // the limit of size_type. // template gsl_api inline span ensure_z(T* const& sz, size_t max = (std::numeric_limits::max)()) { return detail::ensure_sentinel(sz, max); } template gsl_api inline span ensure_z(T(&sz)[N]) { return ensure_z(gsl_ADDRESSOF(sz[0]), N); } #if gsl_HAVE(TYPE_TRAITS) template gsl_api inline span::type> ensure_z(Container & cont) { return ensure_z(cont.data(), cont.length()); } #endif // // basic_zstring_span<> - A view of contiguous null-terminated characters, replace (*,len). // template class basic_zstring_span { public: typedef T element_type; typedef span span_type; typedef typename span_type::index_type index_type; typedef typename span_type::difference_type difference_type; typedef element_type* czstring_type; typedef basic_string_span string_span_type; gsl_api gsl_constexpr14 basic_zstring_span(span_type s) : span_(s) { // expects a zero-terminated span Expects(s[s.size() - 1] == '\0'); } #if gsl_HAVE(IS_DEFAULT) gsl_constexpr basic_zstring_span(basic_zstring_span const& other) = default; gsl_constexpr basic_zstring_span(basic_zstring_span&& other) = default; gsl_constexpr14 basic_zstring_span& operator=(basic_zstring_span const& other) = default; gsl_constexpr14 basic_zstring_span& operator=(basic_zstring_span&& other) = default; #else gsl_api gsl_constexpr basic_zstring_span(basic_zstring_span const& other) : span_(other.span_) {} gsl_api gsl_constexpr basic_zstring_span& operator=(basic_zstring_span const& other) { span_ = other.span_; return *this; } #endif gsl_api gsl_constexpr bool empty() const gsl_noexcept { return span_.size() == 0; } gsl_api gsl_constexpr string_span_type as_string_span() const gsl_noexcept { return string_span_type(span_.data(), span_.size() > 1 ? span_.size() - 1 : 0); } gsl_api gsl_constexpr string_span_type ensure_z() const { return gsl::ensure_z(span_.data(), span_.size()); } gsl_api gsl_constexpr czstring_type assume_z() const gsl_noexcept { return span_.data(); } private: span_type span_; }; // // zString types: // typedef basic_zstring_span zstring_span; typedef basic_zstring_span czstring_span; #if gsl_HAVE(WCHAR) typedef basic_zstring_span wzstring_span; typedef basic_zstring_span cwzstring_span; #endif } // namespace gsl #if gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120 namespace std { template <> struct hash { public: std::size_t operator()(gsl::byte v) const gsl_noexcept { return gsl::to_integer(v); } }; } // namespace std #endif gsl_RESTORE_MSVC_WARNINGS() #endif // GSL_GSL_LITE_HPP_INCLUDED // end of file