// // gsl-lite is based on GSL: Guidelines Support Library. // For more information see https://github.com/gsl-lite/gsl-lite // // Copyright (c) 2015-2019 Martin Moene // Copyright (c) 2019-2023 Moritz Beutel // 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. #ifndef GSL_GSL_LITE_HPP_INCLUDED #define GSL_GSL_LITE_HPP_INCLUDED #include // for exception, terminate(), uncaught_exceptions() #include #include // for addressof(), unique_ptr<>, shared_ptr<> #include // for basic_ostream<> #include // for ios_base, streamsize #include // for logic_error #include #include // for move(), forward<>(), swap() #include // for size_t, ptrdiff_t, nullptr_t #include // for abort() #define gsl_lite_MAJOR 0 #define gsl_lite_MINOR 41 #define gsl_lite_PATCH 0 #define gsl_lite_VERSION gsl_STRINGIFY(gsl_lite_MAJOR) "." gsl_STRINGIFY(gsl_lite_MINOR) "." gsl_STRINGIFY(gsl_lite_PATCH) #define gsl_STRINGIFY( x ) gsl_STRINGIFY_( x ) #define gsl_STRINGIFY_( x ) #x #define gsl_CONCAT_( a, b ) gsl_CONCAT2_( a, b ) #define gsl_CONCAT2_( a, b ) a##b #define gsl_EVALF_( f ) f() // configuration argument checking: #define gsl_DETAIL_CFG_TOGGLE_VALUE_1 1 #define gsl_DETAIL_CFG_TOGGLE_VALUE_0 1 #define gsl_DETAIL_CFG_DEFAULTS_VERSION_VALUE_1 1 #define gsl_DETAIL_CFG_DEFAULTS_VERSION_VALUE_0 1 #define gsl_DETAIL_CFG_STD_VALUE_98 1 #define gsl_DETAIL_CFG_STD_VALUE_3 1 #define gsl_DETAIL_CFG_STD_VALUE_03 1 #define gsl_DETAIL_CFG_STD_VALUE_11 1 #define gsl_DETAIL_CFG_STD_VALUE_14 1 #define gsl_DETAIL_CFG_STD_VALUE_17 1 #define gsl_DETAIL_CFG_STD_VALUE_20 1 #define gsl_DETAIL_CFG_NO_VALUE_ 1 #define gsl_DETAIL_CFG_NO_VALUE_1 1 // many compilers treat the command-line parameter "-Dfoo" as equivalent to "-Dfoo=1", so we tolerate that #define gsl_CHECK_CFG_TOGGLE_VALUE_( x ) gsl_CONCAT_( gsl_DETAIL_CFG_TOGGLE_VALUE_, x ) #define gsl_CHECK_CFG_DEFAULTS_VERSION_VALUE_( x ) gsl_CONCAT_( gsl_DETAIL_CFG_DEFAULTS_VERSION_VALUE_, x ) #define gsl_CHECK_CFG_STD_VALUE_( x ) gsl_CONCAT_( gsl_DETAIL_CFG_STD_VALUE_, x ) #define gsl_CHECK_CFG_NO_VALUE_( x ) gsl_CONCAT_( gsl_DETAIL_CFG_NO_VALUE, gsl_CONCAT_( _, x ) ) // gsl-lite backward compatibility: #if defined( gsl_CONFIG_DEFAULTS_VERSION ) # if ! gsl_CHECK_CFG_DEFAULTS_VERSION_VALUE_( gsl_CONFIG_DEFAULTS_VERSION ) # pragma message ("invalid configuration value gsl_CONFIG_DEFAULTS_VERSION=" gsl_STRINGIFY(gsl_CONFIG_DEFAULTS_VERSION) ", must be 0 or 1") # endif #else # define gsl_CONFIG_DEFAULTS_VERSION gsl_lite_MAJOR // default #endif # define gsl_CONFIG_DEFAULTS_VERSION_() gsl_CONFIG_DEFAULTS_VERSION #if defined( gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR ) # pragma message ("invalid configuration value gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR=" gsl_STRINGIFY(gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR) ", must be 0 or 1") # endif # 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; replace with gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR, or consider span(with_container, cont).") #endif #if defined( gsl_CONFIG_CONTRACT_LEVEL_ON ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_LEVEL_ON ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_LEVEL_ON=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_LEVEL_ON) "; macro must be defined without value") # endif # pragma message ("gsl_CONFIG_CONTRACT_LEVEL_ON is deprecated since gsl-lite 0.36; replace with gsl_CONFIG_CONTRACT_CHECKING_ON.") # define gsl_CONFIG_CONTRACT_CHECKING_ON #endif #if defined( gsl_CONFIG_CONTRACT_LEVEL_OFF ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_LEVEL_OFF ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_LEVEL_OFF=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_LEVEL_OFF) "; macro must be defined without value") # endif # pragma message ("gsl_CONFIG_CONTRACT_LEVEL_OFF is deprecated since gsl-lite 0.36; replace with gsl_CONFIG_CONTRACT_CHECKING_OFF.") # define gsl_CONFIG_CONTRACT_CHECKING_OFF #endif #if defined( gsl_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY) "; macro must be defined without value") # endif # pragma message ("gsl_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY is deprecated since gsl-lite 0.36; replace with gsl_CONFIG_CONTRACT_CHECKING_ENSURES_OFF and gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF.") # define gsl_CONFIG_CONTRACT_CHECKING_ON # define gsl_CONFIG_CONTRACT_CHECKING_ENSURES_OFF # define gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF #elif defined( gsl_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY) "; macro must be defined without value") # endif # pragma message ("gsl_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY is deprecated since gsl-lite 0.36; replace with gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF and gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF.") # define gsl_CONFIG_CONTRACT_CHECKING_ON # define gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF # define gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF #endif // M-GSL compatibility: #if defined( GSL_THROW_ON_CONTRACT_VIOLATION ) # if ! gsl_CHECK_CFG_NO_VALUE_( GSL_THROW_ON_CONTRACT_VIOLATION ) # pragma message ("invalid configuration value GSL_THROW_ON_CONTRACT_VIOLATION=" gsl_STRINGIFY(GSL_THROW_ON_CONTRACT_VIOLATION) "; macro must be defined without value") # endif # define gsl_CONFIG_CONTRACT_VIOLATION_THROWS #endif #if defined( GSL_TERMINATE_ON_CONTRACT_VIOLATION ) # if ! gsl_CHECK_CFG_NO_VALUE_( GSL_TERMINATE_ON_CONTRACT_VIOLATION ) # pragma message ("invalid configuration value GSL_TERMINATE_ON_CONTRACT_VIOLATION=" gsl_STRINGIFY(GSL_TERMINATE_ON_CONTRACT_VIOLATION) "; macro must be defined without value") # endif # define gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES #endif #if defined( GSL_UNENFORCED_ON_CONTRACT_VIOLATION ) # if ! gsl_CHECK_CFG_NO_VALUE_( GSL_UNENFORCED_ON_CONTRACT_VIOLATION ) # pragma message ("invalid configuration value GSL_UNENFORCED_ON_CONTRACT_VIOLATION=" gsl_STRINGIFY(GSL_UNENFORCED_ON_CONTRACT_VIOLATION) "; macro must be defined without value") # endif # define gsl_CONFIG_CONTRACT_CHECKING_OFF #endif // Configuration: Features #if defined( gsl_FEATURE_WITH_CONTAINER_TO_STD ) # if ! gsl_CHECK_CFG_STD_VALUE_( gsl_FEATURE_WITH_CONTAINER_TO_STD ) # pragma message ("invalid configuration value gsl_FEATURE_WITH_CONTAINER_TO_STD=" gsl_STRINGIFY(gsl_FEATURE_WITH_CONTAINER_TO_STD) ", must be 98, 3, 11, 14, 17, or 20") # endif #else # define gsl_FEATURE_WITH_CONTAINER_TO_STD 99 // default #endif #define gsl_FEATURE_WITH_CONTAINER_TO_STD_() gsl_FEATURE_WITH_CONTAINER_TO_STD #if defined( gsl_FEATURE_MAKE_SPAN_TO_STD ) # if ! gsl_CHECK_CFG_STD_VALUE_( gsl_FEATURE_MAKE_SPAN_TO_STD ) # pragma message ("invalid configuration value gsl_FEATURE_MAKE_SPAN_TO_STD=" gsl_STRINGIFY(gsl_FEATURE_MAKE_SPAN_TO_STD) ", must be 98, 3, 11, 14, 17, or 20") # endif #else # define gsl_FEATURE_MAKE_SPAN_TO_STD 99 // default #endif #define gsl_FEATURE_MAKE_SPAN_TO_STD_() gsl_FEATURE_MAKE_SPAN_TO_STD #if defined( gsl_FEATURE_BYTE_SPAN_TO_STD ) # if ! gsl_CHECK_CFG_STD_VALUE_( gsl_FEATURE_BYTE_SPAN_TO_STD ) # pragma message ("invalid configuration value gsl_FEATURE_BYTE_SPAN_TO_STD=" gsl_STRINGIFY(gsl_FEATURE_BYTE_SPAN_TO_STD) ", must be 98, 3, 11, 14, 17, or 20") # endif #else # define gsl_FEATURE_BYTE_SPAN_TO_STD 99 // default #endif #define gsl_FEATURE_BYTE_SPAN_TO_STD_() gsl_FEATURE_BYTE_SPAN_TO_STD #if defined( gsl_FEATURE_IMPLICIT_MACRO ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_FEATURE_IMPLICIT_MACRO ) # pragma message ("invalid configuration value gsl_FEATURE_IMPLICIT_MACRO=" gsl_STRINGIFY(gsl_FEATURE_IMPLICIT_MACRO) ", must be 0 or 1") # endif #else # define gsl_FEATURE_IMPLICIT_MACRO 0 // default #endif #define gsl_FEATURE_IMPLICIT_MACRO_() gsl_FEATURE_IMPLICIT_MACRO #if defined( gsl_FEATURE_OWNER_MACRO ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_FEATURE_OWNER_MACRO ) # pragma message ("invalid configuration value gsl_FEATURE_OWNER_MACRO=" gsl_STRINGIFY(gsl_FEATURE_OWNER_MACRO) ", must be 0 or 1") # endif #else # define gsl_FEATURE_OWNER_MACRO (gsl_CONFIG_DEFAULTS_VERSION == 0) // default #endif #define gsl_FEATURE_OWNER_MACRO_() gsl_FEATURE_OWNER_MACRO //#if defined( gsl_FEATURE_STRING_SPAN ) //# if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_FEATURE_STRING_SPAN ) //# pragma message ("invalid configuration value gsl_FEATURE_STRING_SPAN=" gsl_STRINGIFY(gsl_FEATURE_STRING_SPAN) ", must be 0 or 1") //# endif //#else //# define gsl_FEATURE_STRING_SPAN (gsl_CONFIG_DEFAULTS_VERSION == 0) // default //#endif //#define gsl_FEATURE_STRING_SPAN_() gsl_FEATURE_STRING_SPAN #if defined( gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD ) # pragma message ("invalid configuration value gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD=" gsl_STRINGIFY(gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD) ", must be 0 or 1") # endif #else # define gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD 0 // default #endif # define gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD_() gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD #if defined( gsl_FEATURE_GSL_LITE_NAMESPACE ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_FEATURE_GSL_LITE_NAMESPACE ) # pragma message ("invalid configuration value gsl_FEATURE_GSL_LITE_NAMESPACE=" gsl_STRINGIFY(gsl_FEATURE_GSL_LITE_NAMESPACE) ", must be 0 or 1") # endif #else # define gsl_FEATURE_GSL_LITE_NAMESPACE (gsl_CONFIG_DEFAULTS_VERSION >= 1) // default #endif #define gsl_FEATURE_GSL_LITE_NAMESPACE_() gsl_FEATURE_GSL_LITE_NAMESPACE // Configuration: Other #if defined( gsl_CONFIG_TRANSPARENT_NOT_NULL ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_TRANSPARENT_NOT_NULL ) # pragma message ("invalid configuration value gsl_CONFIG_TRANSPARENT_NOT_NULL=" gsl_STRINGIFY(gsl_CONFIG_TRANSPARENT_NOT_NULL) ", must be 0 or 1") # endif # if gsl_CONFIG_TRANSPARENT_NOT_NULL && defined( gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF ) # error configuration option gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF is meaningless if gsl_CONFIG_TRANSPARENT_NOT_NULL=1 # endif #else # define gsl_CONFIG_TRANSPARENT_NOT_NULL (gsl_CONFIG_DEFAULTS_VERSION >= 1) // default #endif # define gsl_CONFIG_TRANSPARENT_NOT_NULL_() gsl_CONFIG_TRANSPARENT_NOT_NULL #if ! defined( gsl_CONFIG_DEPRECATE_TO_LEVEL ) # if gsl_CONFIG_DEFAULTS_VERSION >= 1 # define gsl_CONFIG_DEPRECATE_TO_LEVEL 7 # else # define gsl_CONFIG_DEPRECATE_TO_LEVEL 0 # endif #endif #if ! defined( gsl_CONFIG_SPAN_INDEX_TYPE ) # define gsl_CONFIG_SPAN_INDEX_TYPE std::size_t #endif # define gsl_CONFIG_SPAN_INDEX_TYPE_() gsl_CONFIG_SPAN_INDEX_TYPE #if ! defined( gsl_CONFIG_INDEX_TYPE ) # if gsl_CONFIG_DEFAULTS_VERSION >= 1 // p0122r3 uses std::ptrdiff_t # define gsl_CONFIG_INDEX_TYPE std::ptrdiff_t # else # define gsl_CONFIG_INDEX_TYPE gsl_CONFIG_SPAN_INDEX_TYPE # endif #endif # define gsl_CONFIG_INDEX_TYPE_() gsl_CONFIG_INDEX_TYPE #if defined( gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR ) # pragma message ("invalid configuration value gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR=" gsl_STRINGIFY(gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR) ", must be 0 or 1") # endif #else # define gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR (gsl_CONFIG_DEFAULTS_VERSION >= 1) // default #endif #define gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR_() gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR #if defined( gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF ) # pragma message ("invalid configuration value gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF=" gsl_STRINGIFY(gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF) ", must be 0 or 1") # endif #else # define gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF 0 // default #endif #define gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF_() gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF #if defined( gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS ) # pragma message ("invalid configuration value gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS=" gsl_STRINGIFY(gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS) ", must be 0 or 1") # endif #else # define gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS 0 // default #endif #define gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS_() gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS #if defined( gsl_CONFIG_ALLOWS_SPAN_COMPARISON ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_ALLOWS_SPAN_COMPARISON ) # pragma message ("invalid configuration value gsl_CONFIG_ALLOWS_SPAN_COMPARISON=" gsl_STRINGIFY(gsl_CONFIG_ALLOWS_SPAN_COMPARISON) ", must be 0 or 1") # endif #else # define gsl_CONFIG_ALLOWS_SPAN_COMPARISON (gsl_CONFIG_DEFAULTS_VERSION == 0) // default #endif #define gsl_CONFIG_ALLOWS_SPAN_COMPARISON_() gsl_CONFIG_ALLOWS_SPAN_COMPARISON #if defined( gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON ) # pragma message ("invalid configuration value gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON=" gsl_STRINGIFY(gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON) ", must be 0 or 1") # endif #else # define gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON 1 // default #endif #define gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON_() gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON #if defined( gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR ) # pragma message ("invalid configuration value gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR=" gsl_STRINGIFY(gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR) ", must be 0 or 1") # endif #else # define gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR 0 // default #endif #define gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR_() gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR #if defined( gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION ) # pragma message ("invalid configuration value gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION=" gsl_STRINGIFY(gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION) ", must be 0 or 1") # endif #else # define gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION (gsl_CONFIG_DEFAULTS_VERSION >= 1) // default #endif #define gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION_() gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION #if defined( gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS ) # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS ) # pragma message ("invalid configuration value gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS=" gsl_STRINGIFY(gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS) ", must be 0 or 1") # endif #else # define gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS 1 // default #endif #define gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS_() gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS #if defined( gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_CHECKING_ENSURES_OFF ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_CHECKING_ENSURES_OFF ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_CHECKING_ENSURES_OFF=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_CHECKING_ENSURES_OFF) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_CHECKING_AUDIT ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_CHECKING_AUDIT ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_CHECKING_AUDIT=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_CHECKING_AUDIT) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_CHECKING_ON ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_CHECKING_ON ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_CHECKING_ON=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_CHECKING_ON) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_CHECKING_OFF ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_CHECKING_OFF ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_CHECKING_OFF=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_CHECKING_OFF) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_AUDIT ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_AUDIT ) # pragma message ("invalid configuration value gsl_CONFIG_DEVICE_CONTRACT_CHECKING_AUDIT=" gsl_STRINGIFY(gsl_CONFIG_DEVICE_CONTRACT_CHECKING_AUDIT) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_ON ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_ON ) # pragma message ("invalid configuration value gsl_CONFIG_DEVICE_CONTRACT_CHECKING_ON=" gsl_STRINGIFY(gsl_CONFIG_DEVICE_CONTRACT_CHECKING_ON) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_OFF ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_OFF ) # pragma message ("invalid configuration value gsl_CONFIG_DEVICE_CONTRACT_CHECKING_OFF=" gsl_STRINGIFY(gsl_CONFIG_DEVICE_CONTRACT_CHECKING_OFF) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_VIOLATION_THROWS=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_VIOLATION_THROWS) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_VIOLATION_TRAPS ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_VIOLATION_TRAPS ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_VIOLATION_TRAPS=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_VIOLATION_TRAPS) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER ) # pragma message ("invalid configuration value gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS ) # pragma message ("invalid configuration value gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS=" gsl_STRINGIFY(gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS ) # pragma message ("invalid configuration value gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS=" gsl_STRINGIFY(gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_CALLS_HANDLER ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_CALLS_HANDLER ) # pragma message ("invalid configuration value gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_CALLS_HANDLER=" gsl_STRINGIFY(gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_CALLS_HANDLER) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME ) # pragma message ("invalid configuration value gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME=" gsl_STRINGIFY(gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE ) # pragma message ("invalid configuration value gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE=" gsl_STRINGIFY(gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME ) # pragma message ("invalid configuration value gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME=" gsl_STRINGIFY(gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE ) # if ! gsl_CHECK_CFG_NO_VALUE_( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE ) # pragma message ("invalid configuration value gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE=" gsl_STRINGIFY(gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE) "; macro must be defined without value") # endif #endif #if defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_THROWS ) # error cannot use gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_THROWS because exceptions are not supported in device code; use gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS or gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS #endif #if defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TERMINATES ) # error gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TERMINATES is not supported; use gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS or gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS #endif #if 1 < defined( gsl_CONFIG_CONTRACT_CHECKING_AUDIT ) + defined( gsl_CONFIG_CONTRACT_CHECKING_ON ) + defined( gsl_CONFIG_CONTRACT_CHECKING_OFF ) # error only one of gsl_CONFIG_CONTRACT_CHECKING_AUDIT, gsl_CONFIG_CONTRACT_CHECKING_ON, and gsl_CONFIG_CONTRACT_CHECKING_OFF may be defined #endif #if 1 < defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_AUDIT ) + defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_ON ) + defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_OFF ) # error only one of gsl_CONFIG_DEVICE_CONTRACT_CHECKING_AUDIT, gsl_CONFIG_DEVICE_CONTRACT_CHECKING_ON, and gsl_CONFIG_DEVICE_CONTRACT_CHECKING_OFF may be defined #endif #if 1 < defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) + defined( gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES ) + defined( gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS ) + defined( gsl_CONFIG_CONTRACT_VIOLATION_TRAPS ) + defined( gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER ) # error only one of gsl_CONFIG_CONTRACT_VIOLATION_THROWS, gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES, gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS, gsl_CONFIG_CONTRACT_VIOLATION_TRAPS, and gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER may be defined #endif #if 1 < defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS ) + defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS ) + defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_CALLS_HANDLER ) # error only one of gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS, gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS, and gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_CALLS_HANDLER may be defined #endif #if 1 < defined( gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME ) + defined( gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE ) # error only one of gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME and gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE may be defined #endif #if 1 < defined( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME ) + defined( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE ) # error only one of gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME and gsl_CONFIG_UNENFORCED_DEVICE_CONTRACTS_ELIDE may be defined #endif #if 0 == defined( gsl_CONFIG_CONTRACT_CHECKING_AUDIT ) + defined( gsl_CONFIG_CONTRACT_CHECKING_ON ) + defined( gsl_CONFIG_CONTRACT_CHECKING_OFF ) // select default # define gsl_CONFIG_CONTRACT_CHECKING_ON #endif #if 0 == defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_AUDIT ) + defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_ON ) + defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_OFF ) // select default # if defined( gsl_CONFIG_CONTRACT_CHECKING_AUDIT ) # define gsl_CONFIG_DEVICE_CONTRACT_CHECKING_AUDIT # elif defined( gsl_CONFIG_CONTRACT_CHECKING_OFF ) # define gsl_CONFIG_DEVICE_CONTRACT_CHECKING_OFF # else # define gsl_CONFIG_DEVICE_CONTRACT_CHECKING_ON # endif #endif #if 0 == defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) + defined( gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES ) + defined( gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS ) + defined( gsl_CONFIG_CONTRACT_VIOLATION_TRAPS ) + defined( gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER ) // select default # define gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES #endif #if 0 == defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS ) + defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS ) + defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_CALLS_HANDLER ) // select default # if defined( gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER ) # define gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_CALLS_HANDLER # elif defined( gsl_CONFIG_CONTRACT_VIOLATION_TRAPS ) # define gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS # else # define gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS # endif #endif #if 0 == defined( gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME ) + defined( gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE ) // select default # define gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE #endif #if 0 == defined( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME ) + defined( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE ) // select default # if defined( gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME ) # define gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME # else # define gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE # endif #endif // C++ language version detection (C++23 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 // C++ standard library version: #ifndef gsl_CPLUSPLUS_STDLIB # define gsl_CPLUSPLUS_STDLIB gsl_CPLUSPLUS #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 >= 202002L ) #define gsl_CPP23_OR_GREATER ( gsl_CPLUSPLUS > 202002L ) // tentative // 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 gsl_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0) // MSVC++ 7.0 _MSC_VER == 1300 gsl_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002) // MSVC++ 7.1 _MSC_VER == 1310 gsl_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003) // MSVC++ 8.0 _MSC_VER == 1400 gsl_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005) // MSVC++ 9.0 _MSC_VER == 1500 gsl_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008) // MSVC++ 10.0 _MSC_VER == 1600 gsl_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010) // MSVC++ 11.0 _MSC_VER == 1700 gsl_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012) // MSVC++ 12.0 _MSC_VER == 1800 gsl_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013) // MSVC++ 14.0 _MSC_VER == 1900 gsl_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) // MSVC++ 14.1 _MSC_VER >= 1910 gsl_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) // MSVC++ 14.2 _MSC_VER >= 1920 gsl_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) // MSVC++ 14.3 _MSC_VER >= 1930 gsl_COMPILER_MSVC_VERSION == 143 (Visual Studio 2022) #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 ) ) ) # define gsl_COMPILER_MSVC_VERSION_FULL (_MSC_VER - 100 * ( 5 + (_MSC_VER < 1900 ) ) ) #else # define gsl_COMPILER_MSVC_VER 0 # define gsl_COMPILER_MSVC_VERSION 0 # define gsl_COMPILER_MSVC_VERSION_FULL 0 #endif #define gsl_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) // AppleClang 7.0.0 __apple_build_version__ == 7000172 gsl_COMPILER_APPLECLANG_VERSION == 700 (Xcode 7.0, 7.0.1) (LLVM 3.7.0) // AppleClang 7.0.0 __apple_build_version__ == 7000176 gsl_COMPILER_APPLECLANG_VERSION == 700 (Xcode 7.1) (LLVM 3.7.0) // AppleClang 7.0.2 __apple_build_version__ == 7000181 gsl_COMPILER_APPLECLANG_VERSION == 702 (Xcode 7.2, 7.2.1) (LLVM 3.7.0) // AppleClang 7.3.0 __apple_build_version__ == 7030029 gsl_COMPILER_APPLECLANG_VERSION == 730 (Xcode 7.3) (LLVM 3.8.0) // AppleClang 7.3.0 __apple_build_version__ == 7030031 gsl_COMPILER_APPLECLANG_VERSION == 730 (Xcode 7.3.1) (LLVM 3.8.0) // AppleClang 8.0.0 __apple_build_version__ == 8000038 gsl_COMPILER_APPLECLANG_VERSION == 800 (Xcode 8.0) (LLVM 3.9.0) // AppleClang 8.0.0 __apple_build_version__ == 8000042 gsl_COMPILER_APPLECLANG_VERSION == 800 (Xcode 8.1, 8.2, 8.2.1) (LLVM 3.9.0) // AppleClang 8.1.0 __apple_build_version__ == 8020038 gsl_COMPILER_APPLECLANG_VERSION == 810 (Xcode 8.3) (LLVM 3.9.0) // AppleClang 8.1.0 __apple_build_version__ == 8020041 gsl_COMPILER_APPLECLANG_VERSION == 810 (Xcode 8.3.1) (LLVM 3.9.0) // AppleClang 8.1.0 __apple_build_version__ == 8020042 gsl_COMPILER_APPLECLANG_VERSION == 810 (Xcode 8.3.2, 8.3.3) (LLVM 3.9.0) // AppleClang 9.0.0 __apple_build_version__ == 9000037 gsl_COMPILER_APPLECLANG_VERSION == 900 (Xcode 9.0) (LLVM 4.0.0) // AppleClang 9.0.0 __apple_build_version__ == 9000038 gsl_COMPILER_APPLECLANG_VERSION == 900 (Xcode 9.1) (LLVM 4.0.0) // AppleClang 9.0.0 __apple_build_version__ == 9000039 gsl_COMPILER_APPLECLANG_VERSION == 900 (Xcode 9.2) (LLVM 4.0.0) // AppleClang 9.1.0 __apple_build_version__ == 9020039 gsl_COMPILER_APPLECLANG_VERSION == 910 (Xcode 9.3, 9.3.1) (LLVM 5.0.2) // AppleClang 9.1.0 __apple_build_version__ == 9020039 gsl_COMPILER_APPLECLANG_VERSION == 910 (Xcode 9.4, 9.4.1) (LLVM 5.0.2) // AppleClang 10.0.0 __apple_build_version__ == 10001145 gsl_COMPILER_APPLECLANG_VERSION == 1000 (Xcode 10.0, 10.1) (LLVM 6.0.1) // AppleClang 10.0.1 __apple_build_version__ == 10010046 gsl_COMPILER_APPLECLANG_VERSION == 1001 (Xcode 10.2, 10.2.1, 10.3) (LLVM 7.0.0) // AppleClang 11.0.0 __apple_build_version__ == 11000033 gsl_COMPILER_APPLECLANG_VERSION == 1100 (Xcode 11.1, 11.2, 11.3, 11.3.1) (LLVM 8.0.0) // AppleClang 11.0.3 __apple_build_version__ == 11030032 gsl_COMPILER_APPLECLANG_VERSION == 1103 (Xcode 11.4, 11.4.1, 11.5, 11.6) (LLVM 9.0.0) // AppleClang 12.0.0 __apple_build_version__ == 12000032 gsl_COMPILER_APPLECLANG_VERSION == 1200 (Xcode 12.0–12.4) (LLVM 10.0.0) // AppleClang 12.0.5 __apple_build_version__ == 12050022 gsl_COMPILER_APPLECLANG_VERSION == 1205 (Xcode 12.5) (LLVM 11.1.0) // AppleClang 13.0.0 __apple_build_version__ == 13000029 gsl_COMPILER_APPLECLANG_VERSION == 1300 (Xcode 13.0–13.2.1) (LLVM 12.0.0) // AppleClang 13.1.6 __apple_build_version__ == 13160021 gsl_COMPILER_APPLECLANG_VERSION == 1316 (Xcode 13.3–13.4.1) (LLVM 13.0.0) // AppleClang 14.0.0 __apple_build_version__ == 14000029 gsl_COMPILER_APPLECLANG_VERSION == 1400 (Xcode 14.0–14.2) (LLVM 14.0.0) // AppleClang 14.0.3 __apple_build_version__ == 14030022 gsl_COMPILER_APPLECLANG_VERSION == 1403 (Xcode 14.3) (LLVM 15.0.0) #if defined( __apple_build_version__ ) # define gsl_COMPILER_APPLECLANG_VERSION gsl_COMPILER_VERSION( __clang_major__, __clang_minor__, __clang_patchlevel__ ) # define gsl_COMPILER_CLANG_VERSION 0 #elif defined( __clang__ ) # define gsl_COMPILER_APPLECLANG_VERSION 0 # define gsl_COMPILER_CLANG_VERSION gsl_COMPILER_VERSION( __clang_major__, __clang_minor__, __clang_patchlevel__ ) #else # define gsl_COMPILER_APPLECLANG_VERSION 0 # define gsl_COMPILER_CLANG_VERSION 0 #endif #if defined( __GNUC__ ) && ! defined( __clang__ ) && ! defined( __NVCOMPILER ) # define gsl_COMPILER_GNUC_VERSION gsl_COMPILER_VERSION( __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ ) #else # define gsl_COMPILER_GNUC_VERSION 0 #endif #if defined( __NVCC__ ) # define gsl_COMPILER_NVCC_VERSION ( __CUDACC_VER_MAJOR__ * 10 + __CUDACC_VER_MINOR__ ) #else # define gsl_COMPILER_NVCC_VERSION 0 #endif // NVHPC 21.2 gsl_COMPILER_NVHPC_VERSION == 2120 #if defined( __NVCOMPILER ) # define gsl_COMPILER_NVHPC_VERSION gsl_COMPILER_VERSION( __NVCOMPILER_MAJOR__, __NVCOMPILER_MINOR__, __NVCOMPILER_PATCHLEVEL__ ) #else # define gsl_COMPILER_NVHPC_VERSION 0 #endif #if defined( __ARMCC_VERSION ) # define gsl_COMPILER_ARMCC_VERSION ( __ARMCC_VERSION / 10000 ) # define gsl_COMPILER_ARMCC_VERSION_FULL __ARMCC_VERSION #else # define gsl_COMPILER_ARMCC_VERSION 0 # define gsl_COMPILER_ARMCC_VERSION_FULL 0 #endif // 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_EVALF_( gsl_FEATURE_##feature##_ ) #define gsl_CONFIG( feature ) gsl_EVALF_( gsl_CONFIG_##feature##_ ) #define gsl_HAVE( feature ) gsl_EVALF_( gsl_HAVE_##feature##_ ) // Presence of wide character support: #if defined(__DJGPP__) || (defined(_LIBCPP_VERSION) && defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)) # define gsl_HAVE_WCHAR 0 #else # define gsl_HAVE_WCHAR 1 #endif #define gsl_HAVE_WCHAR_() gsl_HAVE_WCHAR // Compiling device code: #if defined( __CUDACC__ ) && defined( __CUDA_ARCH__ ) # define gsl_DEVICE_CODE 1 #else # define gsl_DEVICE_CODE 0 #endif // Presence of language & library features: #if gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION # ifdef __OBJC__ // There are a bunch of inconsistencies about __EXCEPTIONS and __has_feature(cxx_exceptions) in Clang 3.4/3.5/3.6. // We're interested in C++ exceptions, which can be checked by __has_feature(cxx_exceptions) in 3.5+. // In pre-3.5, __has_feature(cxx_exceptions) can be true if ObjC exceptions are enabled, but C++ exceptions are disabled. // The recommended way to check is `__EXCEPTIONS && __has_feature(cxx_exceptions)`. // See https://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro // Note: this is only relevant in Objective-C++, thus the ifdef. # if __EXCEPTIONS && __has_feature(cxx_exceptions) # define gsl_HAVE_EXCEPTIONS 1 # else # define gsl_HAVE_EXCEPTIONS 0 # endif // __EXCEPTIONS && __has_feature(cxx_exceptions) # else // clang-cl doesn't define __EXCEPTIONS for MSVC compatibility (see https://reviews.llvm.org/D4065). // Neither does Clang in MS-compatiblity mode. // Let's hope no one tries to build Objective-C++ code using MS-compatibility mode or clang-cl. # if __has_feature(cxx_exceptions) # define gsl_HAVE_EXCEPTIONS 1 # else # define gsl_HAVE_EXCEPTIONS 0 # endif # endif #elif defined( __GNUC__ ) # if __GNUC__ < 5 # ifdef __EXCEPTIONS # define gsl_HAVE_EXCEPTIONS 1 # else # define gsl_HAVE_EXCEPTIONS 0 # endif // __EXCEPTIONS # else # ifdef __cpp_exceptions # define gsl_HAVE_EXCEPTIONS 1 # else # define gsl_HAVE_EXCEPTIONS 0 # endif // __cpp_exceptions # endif // __GNUC__ < 5 #elif gsl_COMPILER_MSVC_VERSION # ifdef _CPPUNWIND # define gsl_HAVE_EXCEPTIONS 1 # else # define gsl_HAVE_EXCEPTIONS 0 # endif // _CPPUNWIND #else // For all other compilers, assume exceptions are always enabled. # define gsl_HAVE_EXCEPTIONS 1 #endif #define gsl_HAVE_EXCEPTIONS_() gsl_HAVE_EXCEPTIONS #if defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) && ! gsl_HAVE_EXCEPTIONS # error Cannot use gsl_CONFIG_CONTRACT_VIOLATION_THROWS if exceptions are disabled. #endif // defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) && !gsl_HAVE( EXCEPTIONS ) #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_C99_PREPROCESSOR gsl_CPP11_140 #define gsl_HAVE_AUTO gsl_CPP11_100 #define gsl_HAVE_RVALUE_REFERENCE gsl_CPP11_100 #define gsl_HAVE_FUNCTION_REF_QUALIFIER ( gsl_CPP11_140 && ! gsl_BETWEEN( gsl_COMPILER_GNUC_VERSION, 1, 481 ) ) #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_VARIADIC_TEMPLATE gsl_CPP11_120 #define gsl_HAVE_IS_DELETE gsl_CPP11_120 #define gsl_HAVE_CONSTEXPR_11 gsl_CPP11_140 #define gsl_HAVE_IS_DEFAULT gsl_CPP11_140 #define gsl_HAVE_NOEXCEPT gsl_CPP11_140 #define gsl_HAVE_NORETURN ( gsl_CPP11_140 && ! gsl_BETWEEN( gsl_COMPILER_GNUC_VERSION, 1, 480 ) ) #define gsl_HAVE_EXPRESSION_SFINAE gsl_CPP11_140 #define gsl_HAVE_OVERRIDE_FINAL gsl_CPP11_110 #define gsl_HAVE_C99_PREPROCESSOR_() gsl_HAVE_C99_PREPROCESSOR #define gsl_HAVE_AUTO_() gsl_HAVE_AUTO #define gsl_HAVE_RVALUE_REFERENCE_() gsl_HAVE_RVALUE_REFERENCE #define gsl_HAVE_FUNCTION_REF_QUALIFIER_() gsl_HAVE_FUNCTION_REF_QUALIFIER #define gsl_HAVE_ENUM_CLASS_() gsl_HAVE_ENUM_CLASS #define gsl_HAVE_ALIAS_TEMPLATE_() gsl_HAVE_ALIAS_TEMPLATE #define gsl_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG_() gsl_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG #define gsl_HAVE_EXPLICIT_() gsl_HAVE_EXPLICIT #define gsl_HAVE_VARIADIC_TEMPLATE_() gsl_HAVE_VARIADIC_TEMPLATE #define gsl_HAVE_IS_DELETE_() gsl_HAVE_IS_DELETE #define gsl_HAVE_CONSTEXPR_11_() gsl_HAVE_CONSTEXPR_11 #define gsl_HAVE_IS_DEFAULT_() gsl_HAVE_IS_DEFAULT #define gsl_HAVE_NOEXCEPT_() gsl_HAVE_NOEXCEPT #define gsl_HAVE_NORETURN_() gsl_HAVE_NORETURN #define gsl_HAVE_EXPRESSION_SFINAE_() gsl_HAVE_EXPRESSION_SFINAE #define gsl_HAVE_OVERRIDE_FINAL_() gsl_HAVE_OVERRIDE_FINAL // Presence of C++14 language features: #define gsl_HAVE_CONSTEXPR_14 ( gsl_CPP14_000 && ! gsl_BETWEEN( gsl_COMPILER_GNUC_VERSION, 1, 600 ) ) #define gsl_HAVE_DECLTYPE_AUTO gsl_CPP14_140 #define gsl_HAVE_DEPRECATED ( gsl_CPP14_140 && ! gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 1, 142 ) ) #define gsl_HAVE_CONSTEXPR_14_() gsl_HAVE_CONSTEXPR_14 #define gsl_HAVE_DECLTYPE_AUTO_() gsl_HAVE_DECLTYPE_AUTO #define gsl_HAVE_DEPRECATED_() gsl_HAVE_DEPRECATED // 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_FULL, 1, 1414 ) ) #define gsl_HAVE_NODISCARD gsl_CPP17_000 #define gsl_HAVE_CONSTEXPR_17 gsl_CPP17_OR_GREATER #define gsl_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE_() gsl_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE #define gsl_HAVE_DEDUCTION_GUIDES_() gsl_HAVE_DEDUCTION_GUIDES #define gsl_HAVE_NODISCARD_() gsl_HAVE_NODISCARD #define gsl_HAVE_MAYBE_UNUSED_() gsl_CPP17_OR_GREATER #define gsl_HAVE_CONSTEXPR_17_() gsl_HAVE_CONSTEXPR_17 // Presence of C++20 language features: #define gsl_HAVE_CONSTEXPR_20 gsl_CPP20_OR_GREATER #define gsl_HAVE_CONSTEXPR_20_() gsl_HAVE_CONSTEXPR_20 // Presence of C++23 language features: #define gsl_HAVE_CONSTEXPR_23 gsl_CPP23_OR_GREATER #define gsl_HAVE_CONSTEXPR_23_() gsl_HAVE_CONSTEXPR_23 // Presence of C++ library features: #if gsl_BETWEEN( gsl_COMPILER_ARMCC_VERSION, 1, 600 ) // Some versions of the ARM compiler apparently ship without a C++11 standard library despite having some C++11 support. # define gsl_STDLIB_CPP98_OR_GREATER gsl_CPP98_OR_GREATER # define gsl_STDLIB_CPP11_OR_GREATER 0 # define gsl_STDLIB_CPP14_OR_GREATER 0 # define gsl_STDLIB_CPP17_OR_GREATER 0 # define gsl_STDLIB_CPP20_OR_GREATER 0 # define gsl_STDLIB_CPP23_OR_GREATER 0 #else # define gsl_STDLIB_CPP98_OR_GREATER gsl_CPP98_OR_GREATER # define gsl_STDLIB_CPP11_OR_GREATER gsl_CPP11_OR_GREATER # define gsl_STDLIB_CPP14_OR_GREATER gsl_CPP14_OR_GREATER # define gsl_STDLIB_CPP17_OR_GREATER gsl_CPP17_OR_GREATER # define gsl_STDLIB_CPP20_OR_GREATER gsl_CPP20_OR_GREATER # define gsl_STDLIB_CPP23_OR_GREATER gsl_CPP23_OR_GREATER #endif #define gsl_STDLIB_CPP11_100 (gsl_STDLIB_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1600) #define gsl_STDLIB_CPP11_110 (gsl_STDLIB_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1700) #define gsl_STDLIB_CPP11_120 (gsl_STDLIB_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1800) #define gsl_STDLIB_CPP11_140 (gsl_STDLIB_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1900) #define gsl_STDLIB_CPP14_000 (gsl_STDLIB_CPP14_OR_GREATER) #define gsl_STDLIB_CPP14_120 (gsl_STDLIB_CPP14_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1800) #define gsl_STDLIB_CPP14_140 (gsl_STDLIB_CPP14_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1900) #define gsl_STDLIB_CPP17_000 (gsl_STDLIB_CPP17_OR_GREATER) #define gsl_STDLIB_CPP17_140 (gsl_STDLIB_CPP17_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1900) #define gsl_STDLIB_CPP11_140_CPP0X_90 (gsl_STDLIB_CPP11_140 || (gsl_COMPILER_MSVC_VER >= 1500 && gsl_HAS_CPP0X)) #define gsl_STDLIB_CPP11_140_CPP0X_100 (gsl_STDLIB_CPP11_140 || (gsl_COMPILER_MSVC_VER >= 1600 && gsl_HAS_CPP0X)) #define gsl_HAVE_ADDRESSOF gsl_STDLIB_CPP17_000 #define gsl_HAVE_ARRAY gsl_STDLIB_CPP11_110 #define gsl_HAVE_TYPE_TRAITS gsl_STDLIB_CPP11_110 #define gsl_HAVE_TR1_TYPE_TRAITS gsl_STDLIB_CPP11_110 #define gsl_HAVE_CONTAINER_DATA_METHOD gsl_STDLIB_CPP11_140_CPP0X_90 #define gsl_HAVE_STD_DATA gsl_STDLIB_CPP17_000 #ifdef __cpp_lib_ssize # define gsl_HAVE_STD_SSIZE 1 #else # define gsl_HAVE_STD_SSIZE ( gsl_COMPILER_GNUC_VERSION >= 1000 && __cplusplus > 201703L ) #endif #define gsl_HAVE_HASH gsl_STDLIB_CPP11_120 #define gsl_HAVE_SIZED_TYPES gsl_STDLIB_CPP11_140 #define gsl_HAVE_MAKE_SHARED gsl_STDLIB_CPP11_140_CPP0X_100 #define gsl_HAVE_SHARED_PTR gsl_STDLIB_CPP11_140_CPP0X_100 #define gsl_HAVE_UNIQUE_PTR gsl_STDLIB_CPP11_140_CPP0X_100 #define gsl_HAVE_MAKE_UNIQUE gsl_STDLIB_CPP14_120 #define gsl_HAVE_MOVE_FORWARD gsl_STDLIB_CPP11_100 #define gsl_HAVE_NULLPTR gsl_STDLIB_CPP11_100 #define gsl_HAVE_UNCAUGHT_EXCEPTIONS gsl_STDLIB_CPP17_140 #define gsl_HAVE_ADD_CONST gsl_HAVE_TYPE_TRAITS #define gsl_HAVE_INITIALIZER_LIST gsl_STDLIB_CPP11_120 #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_REMOVE_CVREF gsl_STDLIB_CPP20_OR_GREATER #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 #define gsl_HAVE_ADDRESSOF_() gsl_HAVE_ADDRESSOF #define gsl_HAVE_ARRAY_() gsl_HAVE_ARRAY #define gsl_HAVE_TYPE_TRAITS_() gsl_HAVE_TYPE_TRAITS #define gsl_HAVE_TR1_TYPE_TRAITS_() gsl_HAVE_TR1_TYPE_TRAITS #define gsl_HAVE_CONTAINER_DATA_METHOD_() gsl_HAVE_CONTAINER_DATA_METHOD #define gsl_HAVE_HASH_() gsl_HAVE_HASH #define gsl_HAVE_STD_DATA_() gsl_HAVE_STD_DATA #define gsl_HAVE_STD_SSIZE_() gsl_HAVE_STD_SSIZE #define gsl_HAVE_SIZED_TYPES_() gsl_HAVE_SIZED_TYPES #define gsl_HAVE_MAKE_SHARED_() gsl_HAVE_MAKE_SHARED #define gsl_HAVE_MOVE_FORWARD_() gsl_HAVE_MOVE_FORWARD #define gsl_HAVE_NULLPTR_() gsl_HAVE_NULLPTR // It's a language feature but needs library support, so we list it as a library feature. #define gsl_HAVE_SHARED_PTR_() gsl_HAVE_SHARED_PTR #define gsl_HAVE_UNIQUE_PTR_() gsl_HAVE_UNIQUE_PTR #define gsl_HAVE_MAKE_UNIQUE_() gsl_HAVE_MAKE_UNIQUE #define gsl_HAVE_UNCAUGHT_EXCEPTIONS_() gsl_HAVE_UNCAUGHT_EXCEPTIONS #define gsl_HAVE_ADD_CONST_() gsl_HAVE_ADD_CONST #define gsl_HAVE_INITIALIZER_LIST_() gsl_HAVE_INITIALIZER_LIST // It's a language feature but needs library support, so we list it as a library feature. #define gsl_HAVE_INTEGRAL_CONSTANT_() gsl_HAVE_INTEGRAL_CONSTANT #define gsl_HAVE_REMOVE_CONST_() gsl_HAVE_REMOVE_CONST #define gsl_HAVE_REMOVE_REFERENCE_() gsl_HAVE_REMOVE_REFERENCE #define gsl_HAVE_REMOVE_CVREF_() gsl_HAVE_REMOVE_CVREF #define gsl_HAVE_TR1_ADD_CONST_() gsl_HAVE_TR1_ADD_CONST #define gsl_HAVE_TR1_INTEGRAL_CONSTANT_() gsl_HAVE_TR1_INTEGRAL_CONSTANT #define gsl_HAVE_TR1_REMOVE_CONST_() gsl_HAVE_TR1_REMOVE_CONST #define gsl_HAVE_TR1_REMOVE_REFERENCE_() gsl_HAVE_TR1_REMOVE_REFERENCE // 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( CONSTEXPR_17 ) # define gsl_constexpr17 constexpr #else # define gsl_constexpr17 /*constexpr*/ #endif #if gsl_HAVE( CONSTEXPR_20 ) # define gsl_constexpr20 constexpr #else # define gsl_constexpr20 /*constexpr*/ #endif #if gsl_HAVE( CONSTEXPR_23 ) # define gsl_constexpr23 constexpr #else # define gsl_constexpr23 /*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 ) # define gsl_noexcept noexcept # define gsl_noexcept_if( expr ) noexcept( expr ) #else # define gsl_noexcept throw() # define gsl_noexcept_if( expr ) /*noexcept( expr )*/ #endif #if defined( gsl_TESTING_ ) # define gsl_noexcept_not_testing #else # define gsl_noexcept_not_testing gsl_noexcept #endif #if gsl_HAVE( NULLPTR ) # define gsl_nullptr nullptr #else # define gsl_nullptr NULL #endif #if gsl_HAVE( NODISCARD ) # define gsl_NODISCARD [[nodiscard]] #else # define gsl_NODISCARD #endif #if gsl_HAVE( NORETURN ) # define gsl_NORETURN [[noreturn]] #elif defined(_MSC_VER) # define gsl_NORETURN __declspec(noreturn) #elif defined( __GNUC__ ) || gsl_COMPILER_ARMCC_VERSION # define gsl_NORETURN __attribute__((noreturn)) #else # define gsl_NORETURN #endif #if gsl_HAVE( MAYBE_UNUSED ) # define gsl_MAYBE_UNUSED [[maybe_unused]] # if gsl_COMPILER_GNUC_VERSION // GCC currently ignores the [[maybe_unused]] attribute on data members and warns accordingly (cf. https://stackoverflow.com/a/65633590). # define gsl_MAYBE_UNUSED_MEMBER # else // ! gsl_COMPILER_GNUC_VERSION # define gsl_MAYBE_UNUSED_MEMBER [[maybe_unused]] # endif // gsl_COMPILER_GNUC_VERSION #else # define gsl_MAYBE_UNUSED # define gsl_MAYBE_UNUSED_MEMBER #endif #if gsl_HAVE( DEPRECATED ) && ! defined( gsl_TESTING_ ) # define gsl_DEPRECATED [[deprecated]] # define gsl_DEPRECATED_MSG( msg ) [[deprecated( msg )]] #else # define gsl_DEPRECATED # define gsl_DEPRECATED_MSG( msg ) #endif #if gsl_HAVE( C99_PREPROCESSOR ) # if gsl_CPP20_OR_GREATER # define gsl_CONSTRAINT(...) __VA_ARGS__ # else # define gsl_CONSTRAINT(...) typename # endif #endif #if gsl_HAVE( TYPE_TRAITS ) # define gsl_STATIC_ASSERT_( cond, msg ) static_assert( cond, msg ) #else # define gsl_STATIC_ASSERT_( cond, msg ) ( ( void )sizeof( char[1 - 2*!!( cond ) ] ) ) #endif #if _MSC_VER >= 1900 // Visual Studio 2015 and newer, or Clang emulating a corresponding MSVC # define gsl_EMPTY_BASES_ __declspec(empty_bases) #else # define gsl_EMPTY_BASES_ #endif #if gsl_HAVE( TYPE_TRAITS ) #define gsl_DEFINE_ENUM_BITMASK_OPERATORS_( ENUM ) \ gsl_NODISCARD gsl_api inline gsl_constexpr ENUM \ operator~( ENUM val ) gsl_noexcept \ { \ typedef typename ::gsl::std11::underlying_type::type U; \ return ENUM( ~U( val ) ); \ } \ gsl_NODISCARD gsl_api inline gsl_constexpr ENUM \ operator|( ENUM lhs, ENUM rhs ) gsl_noexcept \ { \ typedef typename ::gsl::std11::underlying_type::type U; \ return ENUM( U( lhs ) | U( rhs ) ); \ } \ gsl_NODISCARD gsl_api inline gsl_constexpr ENUM \ operator&( ENUM lhs, ENUM rhs ) gsl_noexcept \ { \ typedef typename ::gsl::std11::underlying_type::type U; \ return ENUM( U( lhs ) & U( rhs ) ); \ } \ gsl_NODISCARD gsl_api inline gsl_constexpr ENUM \ operator^( ENUM lhs, ENUM rhs ) gsl_noexcept \ { \ typedef typename ::gsl::std11::underlying_type::type U; \ return ENUM( U( lhs ) ^ U( rhs ) ); \ } \ gsl_api inline gsl_constexpr14 ENUM & \ operator|=( ENUM & lhs, ENUM rhs ) gsl_noexcept \ { \ return lhs = lhs | rhs; \ } \ gsl_api inline gsl_constexpr14 ENUM & \ operator&=( ENUM & lhs, ENUM rhs ) gsl_noexcept \ { \ return lhs = lhs & rhs; \ } \ gsl_api inline gsl_constexpr14 ENUM & \ operator^=( ENUM & lhs, ENUM rhs ) gsl_noexcept \ { \ return lhs = lhs ^ rhs; \ } #define gsl_DEFINE_ENUM_RELATIONAL_OPERATORS_( ENUM ) \ gsl_NODISCARD gsl_api inline gsl_constexpr bool \ operator<( ENUM lhs, ENUM rhs ) gsl_noexcept \ { \ typedef typename ::gsl::std11::underlying_type::type U; \ return U( lhs ) < U( rhs ); \ } \ gsl_NODISCARD gsl_api inline gsl_constexpr bool \ operator>( ENUM lhs, ENUM rhs ) gsl_noexcept \ { \ typedef typename ::gsl::std11::underlying_type::type U; \ return U( lhs ) > U( rhs ); \ } \ gsl_NODISCARD gsl_api inline gsl_constexpr bool \ operator<=( ENUM lhs, ENUM rhs ) gsl_noexcept \ { \ typedef typename ::gsl::std11::underlying_type::type U; \ return U( lhs ) <= U( rhs ); \ } \ gsl_NODISCARD gsl_api inline gsl_constexpr bool \ operator>=( ENUM lhs, ENUM rhs ) gsl_noexcept \ { \ typedef typename ::gsl::std11::underlying_type::type U; \ return U( lhs ) >= U( rhs ); \ } // // Defines bitmask operators `|`, `&`, `^`, `~`, `|=`, `&=`, and `^=` for the given enum type. // // enum class Vegetables { tomato = 0b001, onion = 0b010, eggplant = 0b100 }; // gsl_DEFINE_ENUM_BITMASK_OPERATORS( Vegetables ) // #define gsl_DEFINE_ENUM_BITMASK_OPERATORS( ENUM ) gsl_DEFINE_ENUM_BITMASK_OPERATORS_( ENUM ) // // Defines relational operators `<`, `>`, `<=`, `>=` for the given enum type. // // enum class OperatorPrecedence { additive = 0, multiplicative = 1, power = 2 }; // gsl_DEFINE_ENUM_RELATIONAL_OPERATORS( OperatorPrecedence ) // #define gsl_DEFINE_ENUM_RELATIONAL_OPERATORS( ENUM ) gsl_DEFINE_ENUM_RELATIONAL_OPERATORS_( ENUM ) #endif // gsl_HAVE( TYPE_TRAITS ) #define gsl_DIMENSION_OF( a ) ( sizeof(a) / sizeof(0[a]) ) // Method enabling (C++98, VC120 (VS2013) cannot use __VA_ARGS__) #if gsl_HAVE( EXPRESSION_SFINAE ) # define gsl_TRAILING_RETURN_TYPE_(T) auto # define gsl_RETURN_DECLTYPE_(EXPR) -> decltype( EXPR ) #else # define gsl_TRAILING_RETURN_TYPE_(T) T # define gsl_RETURN_DECLTYPE_(EXPR) #endif // NOTE: When using SFINAE in gsl-lite, please note that overloads of function templates must always use SFINAE with non-type default arguments // as explained in https://en.cppreference.com/w/cpp/types/enable_if#Notes. `gsl_ENABLE_IF_()` implements graceful fallback to default // type arguments (for compilers that don't support non-type default arguments); please verify that this is appropriate in the given // situation, and add additional checks if necessary. // // Also, please note that `gsl_ENABLE_IF_()` doesn't enforce the constraint at all if no compiler/library support is available (i.e. pre-C++11). #if gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) # if !gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 1, 140 ) // VS 2013 seems to have trouble with SFINAE for default non-type arguments # define gsl_ENABLE_IF_(VA) , typename std::enable_if< ( VA ), int >::type = 0 # else # define gsl_ENABLE_IF_(VA) , typename = typename std::enable_if< ( VA ), ::gsl::detail::enabler >::type # endif #else # define gsl_ENABLE_IF_(VA) #endif // Other features: #define gsl_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR ( gsl_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG && gsl_HAVE_CONTAINER_DATA_METHOD ) #define gsl_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR_() gsl_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR #define gsl_HAVE_UNCONSTRAINED_SPAN_CONTAINER_CTOR ( gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR && gsl_COMPILER_NVCC_VERSION == 0 ) #define gsl_HAVE_UNCONSTRAINED_SPAN_CONTAINER_CTOR_() gsl_HAVE_UNCONSTRAINED_SPAN_CONTAINER_CTOR // GSL API (e.g. for CUDA platform): // Guidelines for using `gsl_api`: // // NVCC imposes the restriction that a function annotated `__host__ __device__` cannot call host-only or device-only functions. // This makes `gsl_api` inappropriate for generic functions that call unknown code, e.g. the template constructors of `span<>` // or functions like `finally()` which accept an arbitrary function object. // It is often preferable to annotate functions only with `gsl_constexpr` or `gsl_constexpr14`. The "extended constexpr" mode // of NVCC (currently an experimental feature) will implicitly consider constexpr functions `__host__ __device__` functions // but tolerates calls to host-only or device-only functions. #ifndef gsl_api # ifdef __CUDACC__ # define gsl_api __host__ __device__ # else # define gsl_api /*gsl_api*/ # endif #endif // Additional includes: #if ! gsl_CPP11_OR_GREATER # include // for swap() before C++11 #endif // ! gsl_CPP11_OR_GREATER #if gsl_HAVE( ARRAY ) # include // indirectly includes reverse_iterator<> #endif #if ! gsl_HAVE( ARRAY ) # include // for reverse_iterator<> #endif #if ! gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) || ! gsl_HAVE( AUTO ) # include #endif #if gsl_HAVE( INITIALIZER_LIST ) # include #endif #if defined( gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS ) || gsl_DEVICE_CODE # include #endif #if defined( gsl_CONFIG_CONTRACT_VIOLATION_TRAPS ) && gsl_COMPILER_MSVC_VERSION >= 110 // __fastfail() supported by VS 2012 and later # include #endif #if gsl_HAVE( ENUM_CLASS ) && ( gsl_COMPILER_ARMCC_VERSION || gsl_COMPILER_NVHPC_VERSION ) && !defined( _WIN32 ) # include #endif #if gsl_HAVE( TYPE_TRAITS ) # include // for enable_if<>, // add_const<>, add_pointer<>, common_type<>, make_signed<>, remove_cv<>, remove_const<>, remove_volatile<>, remove_reference<>, remove_cvref<>, remove_pointer<>, underlying_type<>, // is_assignable<>, is_constructible<>, is_const<>, is_convertible<>, is_integral<>, is_pointer<>, is_signed<>, // integral_constant<>, declval() #elif gsl_HAVE( TR1_TYPE_TRAITS ) # include // for add_const<>, remove_cv<>, remove_const<>, remove_volatile<>, remove_reference<>, integral_constant<> #endif #if gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) // Declare __cxa_get_globals() or equivalent in namespace gsl::detail for uncaught_exceptions(): # if ! gsl_HAVE( UNCAUGHT_EXCEPTIONS ) # if defined( _MSC_VER ) // MS-STL with either MSVC or clang-cl namespace gsl { namespace detail { extern "C" char * __cdecl _getptd(); } } # elif gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_GNUC_VERSION || gsl_COMPILER_APPLECLANG_VERSION || gsl_COMPILER_NVHPC_VERSION # if defined( __GLIBCXX__ ) || defined( __GLIBCPP__ ) // libstdc++: prototype from cxxabi.h # include # elif ! defined( BOOST_CORE_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED_ ) // libc++: prototype from Boost? # if defined( __FreeBSD__ ) || defined( __OpenBSD__ ) namespace __cxxabiv1 { struct __cxa_eh_globals; extern "C" __cxa_eh_globals * __cxa_get_globals(); } # else namespace __cxxabiv1 { struct __cxa_eh_globals; extern "C" __cxa_eh_globals * __cxa_get_globals() gsl_noexcept; } # endif # endif namespace gsl { namespace detail { using ::__cxxabiv1::__cxa_get_globals; } } # endif # endif // ! gsl_HAVE( UNCAUGHT_EXCEPTIONS ) #endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) // Warning suppression macros: #if gsl_COMPILER_MSVC_VERSION >= 140 && ! gsl_COMPILER_NVCC_VERSION # 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 // TODO: define for Clang # 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 // Warning suppressions: #if gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wweak-vtables" // because of `fail_fast` and `narrowing_error` #endif // gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION #if gsl_COMPILER_GNUC_VERSION # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wuseless-cast" // we use `static_cast<>()` in several places where it is possibly redundant depending on the configuration of the library #endif // gsl_COMPILER_GNUC_VERSION // Suppress the following MSVC GSL warnings: // - C26432: gsl::c.21 : if you define or delete any default operation in the type '...', define or delete them all // - 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::narrow // - C26439: gsl::f.6 : special function 'function' can be declared 'noexcept' // - C26440: gsl::f.6 : function 'function' can be declared 'noexcept' // - C26455: gsl::f.6 : default constructor may not throw. Declare it '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 // - C26434: gsl::c.128 : function 'symbol_1' hides a non-virtual function 'symbol_2' (false positive for compiler-generated functions such as constructors) // - C26456: gsl::c.128 : operator 'symbol_1' hides a non-virtual operator 'symbol_2' (false positive for compiler-generated operators) // - C26457: es.48 : (void) should not be used to ignore return values, use 'std::ignore =' instead gsl_DISABLE_MSVC_WARNINGS( 26432 26410 26415 26418 26472 26439 26440 26455 26473 26481 26482 26446 26490 26487 26434 26456 26457 ) #if gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 110, 140 ) // VS 2012 and 2013 # pragma warning(disable: 4127) // conditional expression is constant #endif // gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 110, 140 ) #if gsl_COMPILER_MSVC_VERSION == 140 // VS 2015 # pragma warning(disable: 4577) // 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc #endif // gsl_COMPILER_MSVC_VERSION == 140 namespace gsl { // forward declare span<>: template< class T > class span; // C++98 emulation: namespace detail { // We implement `equal()` and `lexicographical_compare()` here to avoid having to pull in the header. template< class InputIt1, class InputIt2 > bool equal( InputIt1 first1, InputIt1 last1, InputIt2 first2 ) { // Implementation borrowed from https://en.cppreference.com/w/cpp/algorithm/equal. for ( ; first1 != last1; ++first1, ++first2 ) { if ( ! (*first1 == *first2 ) ) return false; } return true; } template< class InputIt1, class InputIt2 > bool lexicographical_compare( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2 ) { // Implementation borrowed from https://en.cppreference.com/w/cpp/algorithm/lexicographical_compare. for ( ; first1 != last1 && first2 != last2; ++first1, static_cast< void >( ++first2 ) ) { if ( *first1 < *first2 ) return true; if ( *first2 < *first1 ) return false; } return first1 == last1 && first2 != last2; } } // namespace detail // 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< class T > struct add_const { typedef const T type; }; #endif // gsl_HAVE( ADD_CONST ) #if gsl_HAVE( REMOVE_CONST ) using std::remove_cv; using std::remove_const; using std::remove_volatile; #elif gsl_HAVE( TR1_REMOVE_CONST ) using std::tr1::remove_cv; using std::tr1::remove_const; using std::tr1::remove_volatile; #else template< class T > struct remove_const { typedef T type; }; template< class T > struct remove_const { typedef T type; }; template< class T > struct remove_volatile { typedef T type; }; template< class T > struct remove_volatile { typedef T type; }; template< class T > struct remove_cv { typedef typename remove_volatile::type>::type type; }; #endif // gsl_HAVE( REMOVE_CONST ) #if gsl_HAVE( REMOVE_REFERENCE ) using std::remove_reference; #elif gsl_HAVE( TR1_REMOVE_REFERENCE ) using std::tr1::remove_reference; #else template< class T > struct remove_reference { typedef T type; }; template< class T > struct remove_reference { typedef T type; }; # if gsl_HAVE( RVALUE_REFERENCE ) template< class T > struct remove_reference { typedef T type; }; # endif #endif // gsl_HAVE( REMOVE_REFERENCE ) #if gsl_HAVE( INTEGRAL_CONSTANT ) using std::integral_constant; using std::true_type; using std::false_type; #elif gsl_HAVE( TR1_INTEGRAL_CONSTANT ) using std::tr1::integral_constant; using std::tr1::true_type; using std::tr1::false_type; #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; #endif #if gsl_HAVE( TYPE_TRAITS ) using std::underlying_type; #elif gsl_HAVE( TR1_TYPE_TRAITS ) using std::tr1::underlying_type; #else // We could try to define `underlying_type<>` for pre-C++11 here, but let's not until someone actually needs it. #endif } // namespace std11 // C++14 emulation: namespace std14 { #if gsl_HAVE( UNIQUE_PTR ) # if gsl_HAVE( MAKE_UNIQUE ) using std::make_unique; # elif gsl_HAVE( VARIADIC_TEMPLATE ) template< class T, class... Args > gsl_NODISCARD std::unique_ptr make_unique( Args &&... args ) { # if gsl_HAVE( TYPE_TRAITS ) static_assert( !std::is_array::value, "make_unique() is not part of C++14" ); # endif return std::unique_ptr( new T( std::forward( args )... ) ); } # endif // gsl_HAVE( MAKE_UNIQUE ), gsl_HAVE( VARIADIC_TEMPLATE ) #endif // gsl_HAVE( UNIQUE_PTR ) } // namespace std14 namespace detail { #if gsl_HAVE( VARIADIC_TEMPLATE ) template < bool V0, class T0, class... Ts > struct conjunction_ { using type = T0; }; template < class T0, class T1, class... Ts > struct conjunction_ : conjunction_ { }; template < bool V0, class T0, class... Ts > struct disjunction_ { using type = T0; }; template < class T0, class T1, class... Ts > struct disjunction_ : disjunction_ { }; #endif template struct dependent_false : std11::integral_constant { }; } // namespace detail // C++17 emulation: namespace std17 { template< bool v > struct bool_constant : std11::integral_constant{}; #if gsl_CPP11_120 template < class... Ts > struct conjunction; template < > struct conjunction< > : std11::true_type { }; template < class T0, class... Ts > struct conjunction : detail::conjunction_::type { }; template < class... Ts > struct disjunction; template < > struct disjunction< > : std11::false_type { }; template < class T0, class... Ts > struct disjunction : detail::disjunction_::type { }; template < class T > struct negation : std11::integral_constant { }; # if gsl_CPP14_OR_GREATER template < class... Ts > constexpr bool conjunction_v = conjunction::value; template < class... Ts > constexpr bool disjunction_v = disjunction::value; template < class T > constexpr bool negation_v = negation::value; # endif // gsl_CPP14_OR_GREATER template< class... Ts > struct make_void { typedef void type; }; template< class... Ts > using void_t = typename make_void< Ts... >::type; #endif // gsl_CPP11_120 #if gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) template< class T, size_t N > gsl_NODISCARD gsl_api inline gsl_constexpr auto size( T const(&)[N] ) gsl_noexcept -> size_t { return N; } template< class C > gsl_NODISCARD inline gsl_constexpr auto size( C const & cont ) -> decltype( cont.size() ) { return cont.size(); } template< class T, size_t N > gsl_NODISCARD gsl_api inline gsl_constexpr auto data( T(&arr)[N] ) gsl_noexcept -> T* { return &arr[0]; } template< class C > gsl_NODISCARD inline gsl_constexpr auto data( C & cont ) -> decltype( cont.data() ) { return cont.data(); } template< class C > gsl_NODISCARD inline gsl_constexpr auto data( C const & cont ) -> decltype( cont.data() ) { return cont.data(); } template< class E > gsl_NODISCARD inline gsl_constexpr auto data( std::initializer_list il ) gsl_noexcept -> E const * { return il.begin(); } #endif // gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) } // namespace std17 // C++20 emulation: namespace std20 { #if gsl_CPP11_100 struct identity { template < class T > gsl_constexpr T && operator ()( T && arg ) const gsl_noexcept { return std::forward( arg ); } }; # if gsl_HAVE( ENUM_CLASS ) enum class endian { # if defined( _WIN32 ) little = 0, big = 1, native = little # elif gsl_COMPILER_GNUC_VERSION || gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION little = __ORDER_LITTLE_ENDIAN__, big = __ORDER_BIG_ENDIAN__, native = __BYTE_ORDER__ # elif gsl_COMPILER_ARMCC_VERSION || gsl_COMPILER_NVHPC_VERSION // from header file little = __LITTLE_ENDIAN, big = __BIG_ENDIAN, native = __BYTE_ORDER # else // Do not define any endianness constants for unknown compilers. # endif }; # endif // gsl_HAVE( ENUM_CLASS ) #endif // gsl_CPP11_100 template< class T > struct type_identity { typedef T type; }; #if gsl_HAVE( ALIAS_TEMPLATE ) template< class T > using type_identity_t = typename type_identity::type; #endif // gsl_HAVE( ALIAS_TEMPLATE ) #if gsl_HAVE( STD_SSIZE ) using std::ssize; #elif gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) template < class C > gsl_NODISCARD gsl_constexpr auto ssize( C const & c ) -> typename std::common_type::type>::type { using R = typename std::common_type::type>::type; return static_cast( c.size() ); } template gsl_NODISCARD gsl_constexpr auto ssize( T const(&)[N] ) gsl_noexcept -> std::ptrdiff_t { return std::ptrdiff_t( N ); } #endif // gsl_HAVE( STD_SSIZE ) #if gsl_HAVE( REMOVE_CVREF ) using std::remove_cvref; #else template< class T > struct remove_cvref { typedef typename std11::remove_cv< typename std11::remove_reference< T >::type >::type type; }; #endif // gsl_HAVE( REMOVE_CVREF ) } // namespace std20 // C++23 emulation: namespace std23 { } // namespace std23 namespace detail { /// for gsl_ENABLE_IF_() /*enum*/ class enabler{}; #if gsl_HAVE( TYPE_TRAITS ) template< class Q > struct is_span_oracle : std::false_type{}; template< class T> struct is_span_oracle< span > : std::true_type{}; template< class Q > struct is_span : is_span_oracle< typename std::remove_cv::type >{}; template< class Q > struct is_std_array_oracle : std::false_type{}; # if gsl_HAVE( ARRAY ) template< class T, std::size_t Extent > struct is_std_array_oracle< std::array > : std::true_type{}; # endif template< class Q > struct is_std_array : is_std_array_oracle< typename std::remove_cv::type >{}; template< class Q > struct is_array : std::false_type{}; template< class T > struct is_array : std::true_type{}; template< class T, std::size_t N > struct is_array : std::true_type{}; # if gsl_CPP11_140 && ! gsl_BETWEEN( gsl_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()) ), decltype( std17::data(std::declval()) ) > > : 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()) ), typename std::remove_pointer() ) )>::type(*)[] > > : std::is_convertible< typename std::remove_pointer() ) )>::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::value && is_compatible_element::value >{}; # else // ^^^ gsl_CPP11_140 && ! gsl_BETWEEN( gsl_COMPILER_GNUC_VERSION, 1, 500 ) ^^^ / vvv ! gsl_CPP11_140 || gsl_BETWEEN( gsl_COMPILER_GNUC_VERSION, 1, 500 ) vvv template< class C, class E , typename = typename std::enable_if< ! is_span< C >::value && ! is_array< C >::value && ! is_std_array< C >::value && ( std::is_convertible< typename std::remove_pointer() ) )>::type(*)[], E(*)[] >::value) // && has_size_and_data< C >::value , enabler>::type , class = decltype( std17::size(std::declval()) ) , class = decltype( std17::data(std::declval()) ) > # if gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 1, 140 ) // VS2013 has insufficient support for expression SFINAE; we cannot make `is_compatible_container<>` a proper type trait here struct is_compatible_container : std::true_type { }; # else struct is_compatible_container_r { is_compatible_container_r(int); }; template< class C, class E > std::true_type is_compatible_container_f( is_compatible_container_r ); template< class C, class E > std::false_type is_compatible_container_f( ... ); template< class C, class E > struct is_compatible_container : decltype( is_compatible_container_f< C, E >( 0 ) ) { }; # endif // gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 1, 140 ) # endif // gsl_CPP11_140 && ! gsl_BETWEEN( gsl_COMPILER_GNUC_VERSION, 1, 500 ) #endif // gsl_HAVE( TYPE_TRAITS ) } // namespace detail // // GSL.util: utilities // // Integer type for indices (e.g. in a loop). typedef gsl_CONFIG_INDEX_TYPE index; // Integer type for dimensions. typedef gsl_CONFIG_INDEX_TYPE dim; // Integer type for array strides. typedef gsl_CONFIG_INDEX_TYPE stride; // Integer type for pointer, iterator, or index differences. typedef gsl_CONFIG_INDEX_TYPE diff; // // GSL.owner: ownership pointers // #if gsl_HAVE( SHARED_PTR ) using std::unique_ptr; using std::shared_ptr; #endif #if gsl_HAVE( ALIAS_TEMPLATE ) template< class T #if gsl_HAVE( TYPE_TRAITS ) , typename = typename std::enable_if< std::is_pointer::value >::type #endif > using owner = T; #elif gsl_CONFIG( DEFAULTS_VERSION ) == 0 // TODO vNext: remove template< class T > struct owner { typedef T type; }; #endif #define gsl_HAVE_OWNER_TEMPLATE gsl_HAVE_ALIAS_TEMPLATE #define gsl_HAVE_OWNER_TEMPLATE_() gsl_HAVE_OWNER_TEMPLATE // TODO vNext: remove #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 ) && gsl_CONFIG( VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS ) # define gsl_ELIDE_( x ) static_assert( ::std::is_constructible::value, "argument of contract check must be convertible to bool" ) #else # define gsl_ELIDE_( x ) #endif #define gsl_NO_OP_() ( static_cast( 0 ) ) #if gsl_COMPILER_NVHPC_VERSION // Suppress "controlling expression is constant" warning when using `gsl_Expects()`, `gsl_Ensures()`, `gsl_Assert()`, etc. # define gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ _Pragma("diag_suppress 236") # define gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ _Pragma("diag_default 236") #else # define gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ # define gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ #endif #if gsl_DEVICE_CODE # if defined( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME ) # if gsl_COMPILER_NVCC_VERSION >= 113 # define gsl_ASSUME_( x ) ( __builtin_assume( !!( x ) ) ) # define gsl_ASSUME_UNREACHABLE_() __builtin_unreachable() # else // unknown device compiler # error gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME: gsl-lite does not know how to generate UB optimization hints in device code for this compiler; use gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE instead # endif # define gsl_CONTRACT_UNENFORCED_( x ) gsl_ASSUME_( x ) # else // defined( gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE ) [default] # define gsl_CONTRACT_UNENFORCED_( x ) gsl_ELIDE_( x ) # endif #else // host code # if defined( gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME ) # if gsl_COMPILER_MSVC_VERSION >= 140 # define gsl_ASSUME_( x ) __assume( x ) # define gsl_ASSUME_UNREACHABLE_() __assume( 0 ) # elif gsl_COMPILER_GNUC_VERSION # define gsl_ASSUME_( x ) ( ( x ) ? static_cast(0) : __builtin_unreachable() ) # define gsl_ASSUME_UNREACHABLE_() __builtin_unreachable() # elif defined(__has_builtin) # if __has_builtin(__builtin_unreachable) # define gsl_ASSUME_( x ) ( ( x ) ? static_cast(0) : __builtin_unreachable() ) # define gsl_ASSUME_UNREACHABLE_() __builtin_unreachable() # else # error gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME: gsl-lite does not know how to generate UB optimization hints for this compiler; use gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE instead # endif # else # error gsl_CONFIG_UNENFORCED_CONTRACTS_ASSUME: gsl-lite does not know how to generate UB optimization hints for this compiler; use gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE instead # endif # define gsl_CONTRACT_UNENFORCED_( x ) gsl_ASSUME_( x ) # else // defined( gsl_CONFIG_UNENFORCED_CONTRACTS_ELIDE ) [default] # define gsl_CONTRACT_UNENFORCED_( x ) gsl_ELIDE_( x ) # endif #endif // gsl_DEVICE_CODE #if gsl_DEVICE_CODE # if gsl_COMPILER_NVCC_VERSION # define gsl_TRAP_() __trap() # elif defined(__has_builtin) # if __has_builtin(__builtin_trap) # define gsl_TRAP_() __builtin_trap() # else # error gsl-lite does not know how to generate a trap instruction for this device compiler # endif # else # error gsl-lite does not know how to generate a trap instruction for this device compiler # endif # if defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_TRAPS ) # define gsl_CONTRACT_CHECK_( str, x ) ( gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ( x ) ? static_cast(0) : gsl_TRAP_() gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ) # define gsl_FAILFAST_() ( gsl_TRAP_() ) # elif defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_CALLS_HANDLER ) # define gsl_CONTRACT_CHECK_( str, x ) ( gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ( x ) ? static_cast(0) : ::gsl::fail_fast_assert_handler( #x, str, __FILE__, __LINE__ ) gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ) # define gsl_FAILFAST_() ( ::gsl::fail_fast_assert_handler( "", "GSL: failure", __FILE__, __LINE__ ), gsl_TRAP_() ) /* do not let the custom assertion handler continue execution */ # else // defined( gsl_CONFIG_DEVICE_CONTRACT_VIOLATION_ASSERTS ) [default] # if ! defined( NDEBUG ) # define gsl_CONTRACT_CHECK_( str, x ) assert( str && ( x ) ) # else # define gsl_CONTRACT_CHECK_( str, x ) ( ( x ) ? static_cast(0) : gsl_TRAP_() ) # endif # define gsl_FAILFAST_() ( gsl_TRAP_() ) # endif #else // host code # if defined( gsl_CONFIG_CONTRACT_VIOLATION_TRAPS ) # if gsl_COMPILER_MSVC_VERSION >= 110 // __fastfail() supported by VS 2012 and later # define gsl_TRAP_() __fastfail( 0 ) /* legacy failure code for buffer-overrun errors, cf. winnt.h, "Fast fail failure codes" */ # elif gsl_COMPILER_GNUC_VERSION # define gsl_TRAP_() __builtin_trap() # elif defined(__has_builtin) # if __has_builtin(__builtin_trap) # define gsl_TRAP_() __builtin_trap() # else # error gsl_CONFIG_CONTRACT_VIOLATION_TRAPS: gsl-lite does not know how to generate a trap instruction for this compiler; use gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES instead # endif # else # error gsl_CONFIG_CONTRACT_VIOLATION_TRAPS: gsl-lite does not know how to generate a trap instruction for this compiler; use gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES instead # endif # define gsl_CONTRACT_CHECK_( str, x ) ( gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ( x ) ? static_cast(0) : gsl_TRAP_() gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ) # if gsl_COMPILER_MSVC_VERSION # define gsl_FAILFAST_() ( gsl_TRAP_(), ::gsl::detail::fail_fast_terminate() ) # else # define gsl_FAILFAST_() ( gsl_TRAP_() ) # endif # elif defined( gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER ) # define gsl_CONTRACT_CHECK_( str, x ) ( gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ( x ) ? static_cast(0) : ::gsl::fail_fast_assert_handler( #x, str, __FILE__, __LINE__ ) gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ) # define gsl_FAILFAST_() ( ::gsl::fail_fast_assert_handler( "", "GSL: failure", __FILE__, __LINE__ ), ::gsl::detail::fail_fast_terminate() ) /* do not let the custom assertion handler continue execution */ # elif defined( gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS ) # if ! defined( NDEBUG ) # define gsl_CONTRACT_CHECK_( str, x ) ( gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ assert( str && ( x ) ) gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ) # define gsl_FAILFAST_() ( gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ assert( ! "GSL: failure" ) gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_, ::gsl::detail::fail_fast_abort() ) # else # define gsl_CONTRACT_CHECK_( str, x ) ( gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ( x ) ? static_cast(0) : ::gsl::detail::fail_fast_abort() gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ) # define gsl_FAILFAST_() ( ::gsl::detail::fail_fast_abort() ) # endif # elif defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) # define gsl_CONTRACT_CHECK_( str, x ) ( gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ( ( x ) ? static_cast(0) : ::gsl::detail::fail_fast_throw( str ": '" #x "' at " __FILE__ ":" gsl_STRINGIFY(__LINE__) ) ) gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ) # define gsl_FAILFAST_() ( ::gsl::detail::fail_fast_throw( "GSL: failure at " __FILE__ ":" gsl_STRINGIFY(__LINE__) ) ) # else // defined( gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES ) [default] # define gsl_CONTRACT_CHECK_( str, x ) ( gsl_SUPPRESS_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ( ( x ) ? static_cast(0) : ::gsl::detail::fail_fast_terminate() ) gsl_RESTORE_NVHPC_CONTROLLING_EXPRESSION_IS_CONSTANT_ ) # define gsl_FAILFAST_() ( ::gsl::detail::fail_fast_terminate() ) # endif #endif // gsl_DEVICE_CODE #if ( !gsl_DEVICE_CODE && defined( gsl_CONFIG_CONTRACT_CHECKING_OFF ) ) || ( gsl_DEVICE_CODE && defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_OFF ) ) # define gsl_CHECK_CONTRACTS_ 0 # define gsl_CHECK_DEBUG_CONTRACTS_ 0 # define gsl_CHECK_AUDIT_CONTRACTS_ 0 #elif ( !gsl_DEVICE_CODE && defined( gsl_CONFIG_CONTRACT_CHECKING_AUDIT ) ) || ( gsl_DEVICE_CODE && defined( gsl_CONFIG_DEVICE_CONTRACT_CHECKING_AUDIT ) ) # define gsl_CHECK_CONTRACTS_ 1 # define gsl_CHECK_DEBUG_CONTRACTS_ 1 # define gsl_CHECK_AUDIT_CONTRACTS_ 1 #else // gsl_CONFIG_[DEVICE_]CONTRACT_CHECKING_ON [default] # define gsl_CHECK_CONTRACTS_ 1 # if !defined( NDEBUG ) # define gsl_CHECK_DEBUG_CONTRACTS_ 1 # else // defined( NDEBUG ) # define gsl_CHECK_DEBUG_CONTRACTS_ 0 # endif # define gsl_CHECK_AUDIT_CONTRACTS_ 0 #endif #if gsl_CHECK_CONTRACTS_ && !defined( gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF ) # define gsl_Expects( x ) gsl_CONTRACT_CHECK_( "GSL: Precondition failure", x ) #else # define gsl_Expects( x ) gsl_CONTRACT_UNENFORCED_( x ) #endif #define Expects( x ) gsl_Expects( x ) #if gsl_CHECK_DEBUG_CONTRACTS_ && !defined( gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF ) # define gsl_ExpectsDebug( x ) gsl_CONTRACT_CHECK_( "GSL: Precondition failure (debug)", x ) #else # define gsl_ExpectsDebug( x ) gsl_ELIDE_( x ) #endif #if gsl_CHECK_AUDIT_CONTRACTS_ && !defined( gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF ) # define gsl_ExpectsAudit( x ) gsl_CONTRACT_CHECK_( "GSL: Precondition failure (audit)", x ) #else # define gsl_ExpectsAudit( x ) gsl_ELIDE_( x ) #endif #if gsl_CHECK_CONTRACTS_ && !defined( gsl_CONFIG_CONTRACT_CHECKING_ENSURES_OFF ) # define gsl_Ensures( x ) gsl_CONTRACT_CHECK_( "GSL: Postcondition failure", x ) #else # define gsl_Ensures( x ) gsl_CONTRACT_UNENFORCED_( x ) #endif #define Ensures( x ) gsl_Ensures( x ) #if gsl_CHECK_DEBUG_CONTRACTS_ && !defined( gsl_CONFIG_CONTRACT_CHECKING_ENSURES_OFF ) # define gsl_EnsuresDebug( x ) gsl_CONTRACT_CHECK_( "GSL: Postcondition failure (debug)", x ) #else # define gsl_EnsuresDebug( x ) gsl_ELIDE_( x ) #endif #if gsl_CHECK_AUDIT_CONTRACTS_ && !defined( gsl_CONFIG_CONTRACT_CHECKING_ENSURES_OFF ) # define gsl_EnsuresAudit( x ) gsl_CONTRACT_CHECK_( "GSL: Postcondition failure (audit)", x ) #else # define gsl_EnsuresAudit( x ) gsl_ELIDE_( x ) #endif #if gsl_CHECK_CONTRACTS_ && !defined( gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF ) # define gsl_Assert( x ) gsl_CONTRACT_CHECK_( "GSL: Assertion failure", x ) #else # define gsl_Assert( x ) gsl_CONTRACT_UNENFORCED_( x ) #endif #if gsl_CHECK_DEBUG_CONTRACTS_ && !defined( gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF ) # define gsl_AssertDebug( x ) gsl_CONTRACT_CHECK_( "GSL: Assertion failure (debug)", x ) #else # define gsl_AssertDebug( x ) gsl_ELIDE_( x ) #endif #if gsl_CHECK_AUDIT_CONTRACTS_ && !defined( gsl_CONFIG_CONTRACT_CHECKING_ASSERT_OFF ) # define gsl_AssertAudit( x ) gsl_CONTRACT_CHECK_( "GSL: Assertion failure (audit)", x ) #else # define gsl_AssertAudit( x ) gsl_ELIDE_( x ) #endif #define gsl_FailFast() gsl_FAILFAST_() #undef gsl_CHECK_CONTRACTS_ #undef gsl_CHECK_DEBUG_CONTRACTS_ #undef gsl_CHECK_AUDIT_CONTRACTS_ struct fail_fast : public std::logic_error { explicit fail_fast( char const * message ) : std::logic_error( message ) {} }; namespace detail { #if gsl_HAVE( EXCEPTIONS ) gsl_NORETURN inline void fail_fast_throw( char const * message ) { throw fail_fast( message ); } #endif // gsl_HAVE( EXCEPTIONS ) gsl_NORETURN inline void fail_fast_terminate() gsl_noexcept { std::terminate(); } gsl_NORETURN inline void fail_fast_abort() gsl_noexcept { std::abort(); } } // namespace detail // 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 ); #if defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) # if gsl_HAVE( EXCEPTIONS ) gsl_DEPRECATED_MSG("don't call gsl::fail_fast_assert() directly; use contract checking macros instead") gsl_constexpr14 inline void fail_fast_assert( bool cond, char const * const message ) { if ( !cond ) throw fail_fast( message ); } # endif // gsl_HAVE( EXCEPTIONS ) #elif defined( gsl_CONFIG_CONTRACT_VIOLATION_CALLS_HANDLER ) gsl_DEPRECATED_MSG("don't call gsl::fail_fast_assert() directly; use contract checking macros instead") gsl_api gsl_constexpr14 inline void fail_fast_assert( bool cond, char const * const expression, char const * const message, char const * const file, int line ) { if ( !cond ) ::gsl::fail_fast_assert_handler( expression, message, file, line ); } #else // defined( gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES ) [default] gsl_DEPRECATED_MSG("don't call gsl::fail_fast_assert() directly; use contract checking macros instead") gsl_constexpr14 inline void fail_fast_assert( bool cond ) gsl_noexcept { if ( !cond ) std::terminate(); } #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 std11 { # if gsl_HAVE( UNCAUGHT_EXCEPTIONS ) inline unsigned char uncaught_exceptions() gsl_noexcept { return static_cast( std::uncaught_exceptions() ); } # else // ! gsl_HAVE( UNCAUGHT_EXCEPTIONS ) # if defined( _MSC_VER ) // MS-STL with either MSVC or clang-cl inline unsigned char uncaught_exceptions() gsl_noexcept { return static_cast( *reinterpret_cast( detail::_getptd() + (sizeof(void *) == 8 ? 0x100 : 0x90 ) ) ); } # elif gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_GNUC_VERSION || gsl_COMPILER_APPLECLANG_VERSION || gsl_COMPILER_NVHPC_VERSION inline unsigned char uncaught_exceptions() gsl_noexcept { return static_cast( ( *reinterpret_cast( reinterpret_cast(detail::__cxa_get_globals()) + sizeof(void *) ) ) ); } # endif # endif } // namespace std11 #endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) #if gsl_STDLIB_CPP11_110 gsl_DISABLE_MSVC_WARNINGS( 4702 ) // unreachable code template< class F > class final_action { public: explicit final_action( F action ) gsl_noexcept : action_( std::move( action ) ) #if gsl_CONFIG_DEFAULTS_VERSION < 1 || ! gsl_CPP17_OR_GREATER , invoke_( true ) #endif { } // We only provide the move constructor for legacy defaults, or if we cannot rely on C++17 guaranteed copy elision. #if gsl_CONFIG_DEFAULTS_VERSION < 1 || ! gsl_CPP17_OR_GREATER final_action( final_action && other ) gsl_noexcept : action_( std::move( other.action_ ) ) , invoke_( other.invoke_ ) { other.invoke_ = false; } #endif // gsl_CONFIG_DEFAULTS_VERSION < 1 || ! gsl_CPP17_OR_GREATER gsl_SUPPRESS_MSGSL_WARNING(f.6) #if gsl_CONFIG_DEFAULTS_VERSION < 1 // we avoid the unnecessary virtual calls if modern defaults are selected virtual #endif ~final_action() gsl_noexcept { #if gsl_CONFIG_DEFAULTS_VERSION < 1 || ! gsl_CPP17_OR_GREATER if ( invoke_ ) #endif { action_(); } } gsl_is_delete_access: final_action( final_action const & ) gsl_is_delete; final_action & operator=( final_action const & ) gsl_is_delete; final_action & operator=( final_action && ) gsl_is_delete; #if gsl_CONFIG_DEFAULTS_VERSION < 1 protected: void dismiss() gsl_noexcept { invoke_ = false; } #endif // gsl_CONFIG_DEFAULTS_VERSION < 1 private: F action_; gsl_MAYBE_UNUSED_MEMBER bool invoke_; // member is defined unconditionally so as not to have ABI depend on C++ language support }; template< class F > gsl_NODISCARD inline final_action::type> finally( F && action ) gsl_noexcept { return final_action::type>( std::forward( action ) ); } # if gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) #if gsl_CONFIG_DEFAULTS_VERSION >= 1 template< class F > class final_action_return { public: explicit final_action_return( F action ) gsl_noexcept : action_( std::move( action ) ) , exception_count_( std11::uncaught_exceptions() ) { } // We only provide the move constructor if we cannot rely on C++17 guaranteed copy elision. #if ! gsl_CPP17_OR_GREATER final_action_return( final_action_return && other ) gsl_noexcept : action_( std::move( other.action_ ) ) , exception_count_( other.exception_count_ ) { other.exception_count_ = 0xFF; // abuse member as special "no-invoke" marker } #endif // ! gsl_CPP17_OR_GREATER gsl_SUPPRESS_MSGSL_WARNING(f.6) ~final_action_return() gsl_noexcept { #if ! gsl_CPP17_OR_GREATER if ( exception_count_ != 0xFF ) // abuse member as special "no-invoke" marker #endif { if ( std11::uncaught_exceptions() == exception_count_ ) { action_(); } } } gsl_is_delete_access: final_action_return( final_action_return const & ) gsl_is_delete; final_action_return & operator=( final_action_return const & ) gsl_is_delete; final_action_return & operator=( final_action_return && ) gsl_is_delete; private: F action_; unsigned char exception_count_; }; template< class F > class final_action_error { public: explicit final_action_error( F action ) gsl_noexcept : action_( std::move( action ) ) , exception_count_( std11::uncaught_exceptions() ) { } // We only provide the move constructor if we cannot rely on C++17 guaranteed copy elision. #if ! gsl_CPP17_OR_GREATER final_action_error( final_action_error && other ) gsl_noexcept : action_( std::move( other.action_ ) ) , exception_count_( other.exception_count_ ) { other.exception_count_ = 0xFF; // abuse member as special "no-invoke" marker } #endif // ! gsl_CPP17_OR_GREATER gsl_SUPPRESS_MSGSL_WARNING(f.6) ~final_action_error() gsl_noexcept { #if ! gsl_CPP17_OR_GREATER if ( exception_count_ != 0xFF ) // abuse member as special "no-invoke" marker #endif { if ( std11::uncaught_exceptions() != exception_count_ ) { action_(); } } } gsl_is_delete_access: final_action_error( final_action_error const & ) gsl_is_delete; final_action_error & operator=( final_action_error const & ) gsl_is_delete; final_action_error & operator=( final_action_error && ) gsl_is_delete; private: F action_; unsigned char exception_count_; }; #else // gsl_CONFIG_DEFAULTS_VERSION < 1 template< class F > class final_action_return : public final_action { public: explicit final_action_return( F && action ) gsl_noexcept : final_action( std::move( action ) ) , exception_count( std11::uncaught_exceptions() ) {} final_action_return( final_action_return && other ) gsl_noexcept : final_action( std::move( other ) ) , exception_count( std11::uncaught_exceptions() ) {} ~final_action_return() override { if ( std11::uncaught_exceptions() != exception_count ) this->dismiss(); } gsl_is_delete_access: final_action_return( final_action_return const & ) gsl_is_delete; final_action_return & operator=( final_action_return const & ) gsl_is_delete; private: unsigned char exception_count; }; template< class F > class final_action_error : public final_action { public: explicit final_action_error( F && action ) gsl_noexcept : final_action( std::move( action ) ) , exception_count( std11::uncaught_exceptions() ) {} final_action_error( final_action_error && other ) gsl_noexcept : final_action( std::move( other ) ) , exception_count( std11::uncaught_exceptions() ) {} ~final_action_error() override { if ( std11::uncaught_exceptions() == exception_count ) this->dismiss(); } gsl_is_delete_access: final_action_error( final_action_error const & ) gsl_is_delete; final_action_error & operator=( final_action_error const & ) gsl_is_delete; private: unsigned char exception_count; }; #endif // gsl_CONFIG_DEFAULTS_VERSION >= 1 template< class F > gsl_NODISCARD inline final_action_return::type> on_return( F && action ) gsl_noexcept { return final_action_return::type>( std::forward( action ) ); } template< class F > gsl_NODISCARD inline final_action_error::type> on_error( F && action ) gsl_noexcept { return final_action_error::type>( std::forward( action ) ); } # endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) gsl_RESTORE_MSVC_WARNINGS() #else // ! gsl_STDLIB_CPP11_110 # if gsl_DEPRECATE_TO_LEVEL( 8 ) gsl_DEPRECATED_MSG("final_action for pre-C++11 compilers is deprecated") # endif // gsl_DEPRECATE_TO_LEVEL( 8 ) class final_action { public: typedef void (*Action)(); final_action( Action action ) : action_( action ) , invoke_( true ) {} final_action( final_action const & other ) : action_( other.action_ ) , invoke_( other.invoke_ ) { other.invoke_ = false; } virtual ~final_action() { if ( invoke_ ) action_(); } protected: void dismiss() { invoke_ = false; } private: final_action & operator=( final_action const & ); private: Action action_; mutable bool invoke_; }; template< class F > # if gsl_DEPRECATE_TO_LEVEL( 8 ) gsl_DEPRECATED_MSG("finally() for pre-C++11 compilers is deprecated") # endif // gsl_DEPRECATE_TO_LEVEL( 8 ) inline final_action finally( F const & f ) { return final_action( f ); } # if gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) # if gsl_DEPRECATE_TO_LEVEL( 8 ) gsl_DEPRECATED_MSG("final_action_return for pre-C++11 compilers is deprecated") # endif // gsl_DEPRECATE_TO_LEVEL( 8 ) class final_action_return : public final_action { public: explicit final_action_return( Action action ) : final_action( action ) , exception_count( std11::uncaught_exceptions() ) {} ~final_action_return() { if ( std11::uncaught_exceptions() != exception_count ) this->dismiss(); } private: final_action_return & operator=( final_action_return const & ); private: unsigned char exception_count; }; template< class F > # if gsl_DEPRECATE_TO_LEVEL( 8 ) gsl_DEPRECATED_MSG("on_return() for pre-C++11 compilers is deprecated") # endif // gsl_DEPRECATE_TO_LEVEL( 8 ) inline final_action_return on_return( F const & action ) { return final_action_return( action ); } # if gsl_DEPRECATE_TO_LEVEL( 8 ) gsl_DEPRECATED_MSG("final_action_error for pre-C++11 compilers is deprecated") # endif // gsl_DEPRECATE_TO_LEVEL( 8 ) class final_action_error : public final_action { public: explicit final_action_error( Action action ) : final_action( action ) , exception_count( std11::uncaught_exceptions() ) {} ~final_action_error() { if ( std11::uncaught_exceptions() == exception_count ) this->dismiss(); } private: final_action_error & operator=( final_action_error const & ); private: unsigned char exception_count; }; template< class F > # if gsl_DEPRECATE_TO_LEVEL( 8 ) gsl_DEPRECATED_MSG("on_error() for pre-C++11 compilers is deprecated") # endif // gsl_DEPRECATE_TO_LEVEL( 8 ) inline final_action_error on_error( F const & action ) { return final_action_error( action ); } # endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) #endif // gsl_STDLIB_CPP11_110 #if gsl_STDLIB_CPP11_120 template< class T, class U > gsl_NODISCARD gsl_api inline gsl_constexpr T narrow_cast( U && u ) gsl_noexcept { return static_cast( std::forward( u ) ); } #else // ! gsl_STDLIB_CPP11_120 template< class T, class U > gsl_api inline T narrow_cast( U u ) gsl_noexcept { return static_cast( u ); } #endif // gsl_STDLIB_CPP11_120 struct narrowing_error : public std::exception { char const * what() const gsl_noexcept #if gsl_HAVE( OVERRIDE_FINAL ) override #endif { return "narrowing_error"; } }; #if gsl_HAVE( TYPE_TRAITS ) namespace detail { template< class T, class U > struct is_same_signedness : public std::integral_constant::value == std::is_signed::value> {}; # if gsl_COMPILER_NVCC_VERSION || gsl_COMPILER_NVHPC_VERSION // We do this to circumvent NVCC warnings about pointless unsigned comparisons with 0. template< class T > gsl_constexpr gsl_api bool is_negative( T value, std::true_type /*isSigned*/ ) gsl_noexcept { return value < T(); } template< class T > gsl_constexpr gsl_api bool is_negative( T /*value*/, std::false_type /*isUnsigned*/ ) gsl_noexcept { return false; } template< class T, class U > gsl_constexpr gsl_api bool have_same_sign( T, U, std::true_type /*isSameSignedness*/ ) gsl_noexcept { return true; } template< class T, class U > gsl_constexpr gsl_api bool have_same_sign( T t, U u, std::false_type /*isSameSignedness*/ ) gsl_noexcept { return detail::is_negative( t, std::is_signed() ) == detail::is_negative( u, std::is_signed() ); } # endif // gsl_COMPILER_NVCC_VERSION || gsl_COMPILER_NVHPC_VERSION } // namespace detail #endif template< class T, class U > gsl_NODISCARD gsl_constexpr14 #if !gsl_CONFIG( NARROW_THROWS_ON_TRUNCATION ) && !defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) gsl_api #endif inline T narrow( U u ) { #if gsl_CONFIG( NARROW_THROWS_ON_TRUNCATION ) && ! gsl_HAVE( EXCEPTIONS ) gsl_STATIC_ASSERT_( detail::dependent_false< T >::value, "According to the GSL specification, narrow<>() throws an exception of type narrowing_error on truncation. Therefore " "it cannot be used if exceptions are disabled. Consider using narrow_failfast<>() instead which raises a precondition " "violation if the given value cannot be represented in the target type." ); #endif T t = static_cast( u ); if ( static_cast( t ) != u ) { #if gsl_HAVE( EXCEPTIONS ) && ( gsl_CONFIG( NARROW_THROWS_ON_TRUNCATION ) || defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) ) throw narrowing_error(); #else std::terminate(); #endif } #if gsl_HAVE( TYPE_TRAITS ) # if gsl_COMPILER_NVCC_VERSION || gsl_COMPILER_NVHPC_VERSION if ( ! detail::have_same_sign( t, u, detail::is_same_signedness() ) ) # else gsl_SUPPRESS_MSVC_WARNING( 4127, "conditional expression is constant" ) if ( ! detail::is_same_signedness::value && ( t < T() ) != ( u < U() ) ) # endif #else // Don't assume T() works: gsl_SUPPRESS_MSVC_WARNING( 4127, "conditional expression is constant" ) # if gsl_COMPILER_NVHPC_VERSION // Suppress: pointless comparison of unsigned integer with zero. # pragma diag_suppress 186 # endif if ( ( t < 0 ) != ( u < 0 ) ) # if gsl_COMPILER_NVHPC_VERSION // Restore: pointless comparison of unsigned integer with zero. # pragma diag_default 186 # endif #endif { #if gsl_HAVE( EXCEPTIONS ) && ( gsl_CONFIG( NARROW_THROWS_ON_TRUNCATION ) || defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) ) throw narrowing_error(); #else std::terminate(); #endif } return t; } template< class T, class U > gsl_NODISCARD gsl_api gsl_constexpr14 inline T narrow_failfast( U u ) { T t = static_cast( u ); gsl_Expects( static_cast( t ) == u ); #if gsl_HAVE( TYPE_TRAITS ) # if gsl_COMPILER_NVCC_VERSION || gsl_COMPILER_NVHPC_VERSION gsl_Expects( ::gsl::detail::have_same_sign( t, u, ::gsl::detail::is_same_signedness() ) ); # else gsl_SUPPRESS_MSVC_WARNING( 4127, "conditional expression is constant" ) gsl_Expects( ( ::gsl::detail::is_same_signedness::value || ( t < T() ) == ( u < U() ) ) ); # endif #else // Don't assume T() works: gsl_SUPPRESS_MSVC_WARNING( 4127, "conditional expression is constant" ) # if gsl_COMPILER_NVHPC_VERSION // Suppress: pointless comparison of unsigned integer with zero. # pragma diag_suppress 186 # endif gsl_Expects( ( t < 0 ) == ( u < 0 ) ); # if gsl_COMPILER_NVHPC_VERSION // Restore: pointless comparison of unsigned integer with zero. # pragma diag_default 186 # endif #endif return t; } // // at() - Bounds-checked way of accessing static arrays, std::array, std::vector. // template< class T, size_t N > gsl_NODISCARD gsl_api inline gsl_constexpr14 T & at( T(&arr)[N], size_t pos ) { gsl_Expects( pos < N ); return arr[pos]; } template< class Container > gsl_NODISCARD gsl_api inline gsl_constexpr14 typename Container::value_type & at( Container & cont, size_t pos ) { gsl_Expects( pos < cont.size() ); return cont[pos]; } template< class Container > gsl_NODISCARD gsl_api inline gsl_constexpr14 typename Container::value_type const & at( Container const & cont, size_t pos ) { gsl_Expects( pos < cont.size() ); return cont[pos]; } #if gsl_HAVE( INITIALIZER_LIST ) template< class T > gsl_NODISCARD gsl_api inline const gsl_constexpr14 T at( std::initializer_list cont, size_t pos ) { gsl_Expects( pos < cont.size() ); return *( cont.begin() + pos ); } #endif template< class T > gsl_NODISCARD gsl_api inline gsl_constexpr14 T & at( span s, size_t pos ) { return s[ pos ]; } // // GSL.views: views // // // not_null<> - Wrap any indirection and enforce non-null. // template< class T > class not_null; namespace detail { // helper class to figure out the pointed-to type of a pointer #if gsl_STDLIB_CPP11_OR_GREATER template< class T, class E = void > struct element_type_helper { // For types without a member element_type (this could handle typed raw pointers but not `void*`) typedef typename std::remove_reference< decltype( *std::declval() ) >::type type; }; template< class T > struct element_type_helper< T, std17::void_t< typename T::element_type > > { // For types with a member element_type typedef typename T::element_type type; }; #else // ! gsl_STDLIB_CPP11_OR_GREATER // Pre-C++11, we cannot have decltype, so we cannot handle types without a member element_type template< class T, class E = void > struct element_type_helper { typedef typename T::element_type type; }; #endif // gsl_STDLIB_CPP11_OR_GREATER template< class T > struct element_type_helper< T* > { typedef T type; }; template< class T > struct is_not_null_or_bool_oracle : std11::false_type { }; template< class T > struct is_not_null_or_bool_oracle< not_null > : std11::true_type { }; template<> struct is_not_null_or_bool_oracle< bool > : std11::true_type { }; template< class T, bool IsCopyable > struct not_null_data; #if gsl_HAVE( MOVE_FORWARD ) template< class T > struct not_null_data< T, false > { T ptr_; gsl_api gsl_constexpr14 not_null_data( T && _ptr ) gsl_noexcept : ptr_( std::move( _ptr ) ) { } gsl_api gsl_constexpr14 not_null_data( not_null_data && other ) gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion : ptr_( std::move( other.ptr_ ) ) { gsl_Assert( ptr_ != gsl_nullptr ); } gsl_api gsl_constexpr14 not_null_data & operator=( not_null_data && other ) gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion { gsl_Assert( other.ptr_ != gsl_nullptr || &other == this ); ptr_ = std::move( other.ptr_ ); return *this; } gsl_is_delete_access: not_null_data( not_null_data const & ) gsl_is_delete; not_null_data & operator=( not_null_data const & ) gsl_is_delete; }; #endif // gsl_HAVE( MOVE_FORWARD ) template< class T > struct not_null_data< T, true > { T ptr_; gsl_api gsl_constexpr14 not_null_data( T const & _ptr ) gsl_noexcept : ptr_( _ptr ) { } #if gsl_HAVE( MOVE_FORWARD ) gsl_api gsl_constexpr14 not_null_data( T && _ptr ) gsl_noexcept : ptr_( std::move( _ptr ) ) { } gsl_api gsl_constexpr14 not_null_data( not_null_data && other ) gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion : ptr_( std::move( other.ptr_ ) ) { gsl_Assert( ptr_ != gsl_nullptr ); } gsl_api gsl_constexpr14 not_null_data & operator=( not_null_data && other ) gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion { gsl_Assert( other.ptr_ != gsl_nullptr || &other == this ); ptr_ = std::move( other.ptr_ ); return *this; } #endif // gsl_HAVE( MOVE_FORWARD ) gsl_api gsl_constexpr14 not_null_data( not_null_data const & other ) : ptr_( other.ptr_ ) { gsl_Assert( ptr_ != gsl_nullptr ); } gsl_api gsl_constexpr14 not_null_data & operator=( not_null_data const & other ) { gsl_Assert( other.ptr_ != gsl_nullptr ); ptr_ = other.ptr_; return *this; } }; template< class T > struct not_null_data< T *, true > { T * ptr_; gsl_api gsl_constexpr14 not_null_data( T * _ptr ) gsl_noexcept : ptr_( _ptr ) { } }; template< class T > struct is_copyable #if gsl_HAVE( TYPE_TRAITS ) : std11::integral_constant< bool, std::is_copy_constructible::value && std::is_copy_assignable::value > #else : std11::true_type #endif { }; #if gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( UNIQUE_PTR ) && gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 1, 140 ) // Type traits are buggy in VC++ 2013, so we explicitly declare `unique_ptr<>` non-copyable. template< class T, class Deleter > struct is_copyable< std::unique_ptr< T, Deleter > > : std11::false_type { }; #endif template< class T > struct not_null_accessor; template< class Derived, class T, bool IsVoidPtr > struct not_null_deref { typedef typename element_type_helper::type element_type; gsl_NODISCARD gsl_api gsl_constexpr14 element_type & operator*() const { return *not_null_accessor::get_checked( static_cast( *this ) ); } }; template< class Derived, class T > struct not_null_deref< Derived, T, true > { }; template< class T > struct is_void : std11::false_type { }; template< > struct is_void< void > : std11::true_type { }; template< class T > struct is_void_ptr : is_void< typename detail::element_type_helper< T >::type > { }; } // namespace detail template< class T > class gsl_EMPTY_BASES_ // not strictly needed, but will become necessary if we add more base classes not_null : public detail::not_null_deref< not_null< T >, T, detail::is_void_ptr< T >::value > { private: detail::not_null_data< T, detail::is_copyable< T >::value > data_; // need to access `not_null::data_` template< class U > friend struct detail::not_null_accessor; typedef detail::not_null_accessor accessor; public: typedef typename detail::element_type_helper::type element_type; #if gsl_HAVE( TYPE_TRAITS ) static_assert( ! std::is_reference::value, "T may not be a reference type" ); static_assert( ! std::is_const::value && ! std::is_volatile::value, "T may not be cv-qualified" ); static_assert( std::is_assignable::value, "T cannot be assigned nullptr" ); #endif #if gsl_CONFIG( NOT_NULL_EXPLICIT_CTOR ) # if gsl_HAVE( MOVE_FORWARD ) template< class U // In Clang 3.x, `is_constructible>, unique_ptr>` tries to instantiate the copy constructor of `unique_ptr<>`, triggering an error. // Note that Apple Clang's `__clang_major__` etc. are different from regular Clang. # if gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) // We *have* to use SFINAE with an NTTP arg here, otherwise the overload is ambiguous. , typename std::enable_if< ( std::is_constructible::value ), int >::type = 0 # endif > gsl_api gsl_constexpr14 explicit not_null( U other ) : data_( T( std::move( other ) ) ) { gsl_Expects( data_.ptr_ != gsl_nullptr ); } # else // a.k.a. ! gsl_HAVE( MOVE_FORWARD ) template< class U > gsl_api gsl_constexpr14 explicit not_null( U const& other ) : data_( T( other ) ) { gsl_Expects( data_.ptr_ != gsl_nullptr ); } # endif // gsl_HAVE( MOVE_FORWARD ) #else // a.k.a. !gsl_CONFIG( NOT_NULL_EXPLICIT_CTOR ) # if gsl_HAVE( MOVE_FORWARD ) // In Clang 3.x, `is_constructible>, unique_ptr>` tries to instantiate the copy constructor of `unique_ptr<>`, triggering an error. // Note that Apple Clang's `__clang_major__` etc. are different from regular Clang. # if gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) template< class U // We *have* to use SFINAE with an NTTP arg here, otherwise the overload is ambiguous. , typename std::enable_if< ( std::is_constructible::value && !std::is_convertible::value ), int >::type = 0 > gsl_api gsl_constexpr14 explicit not_null( U other ) : data_( T( std::move( other ) ) ) { gsl_Expects( data_.ptr_ != gsl_nullptr ); } template< class U // We *have* to use SFINAE with an NTTP arg here, otherwise the overload is ambiguous. , typename std::enable_if< ( std::is_convertible::value ), int >::type = 0 > gsl_api gsl_constexpr14 not_null( U other ) : data_( std::move( other ) ) { gsl_Expects( data_.ptr_ != gsl_nullptr ); } # else // a.k.a. !( gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) // If type_traits are not available, then we can't distinguish `is_convertible<>` and `is_constructible<>`, so we unconditionally permit implicit construction. template< class U > gsl_api gsl_constexpr14 not_null( U other ) : data_( T( std::move( other ) ) ) { gsl_Expects( data_.ptr_ != gsl_nullptr ); } # endif // gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) # else // a.k.a. ! gsl_HAVE( MOVE_FORWARD ) template< class U > gsl_api gsl_constexpr14 not_null( U const& other ) : data_( T( other ) ) { gsl_Expects( data_.ptr_ != gsl_nullptr ); } # endif // gsl_HAVE( MOVE_FORWARD ) #endif // gsl_CONFIG( NOT_NULL_EXPLICIT_CTOR ) #if gsl_HAVE( MOVE_FORWARD ) // In Clang 3.x, `is_constructible>, unique_ptr>` tries to instantiate the copy constructor of `unique_ptr<>`, triggering an error. // Note that Apple Clang's `__clang_major__` etc. are different from regular Clang. # if gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) template< class U // We *have* to use SFINAE with an NTTP arg here, otherwise the overload is ambiguous. , typename std::enable_if< ( std::is_constructible::value && !std::is_convertible::value ), int >::type = 0 > gsl_api gsl_constexpr14 explicit not_null( not_null other ) : data_( T( detail::not_null_accessor::get_checked( std::move( other ) ) ) ) { } template< class U // We *have* to use SFINAE with an NTTP arg here, otherwise the overload is ambiguous. , typename std::enable_if< ( std::is_convertible::value ), int >::type = 0 > gsl_api gsl_constexpr14 not_null( not_null other ) : data_( T( detail::not_null_accessor::get_checked( std::move( other ) ) ) ) { } # else // a.k.a. ! ( gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) // If type_traits are not available, then we can't distinguish `is_convertible<>` and `is_constructible<>`, so we unconditionally permit implicit construction. template< class U > gsl_api gsl_constexpr14 not_null( not_null other ) : data_( T( detail::not_null_accessor::get_checked( std::move( other ) ) ) ) { gsl_Expects( data_.ptr_ != gsl_nullptr ); } template< class U > gsl_api gsl_constexpr14 not_null& operator=( not_null other ) { data_.ptr_ = detail::not_null_accessor::get_checked( std::move( other ) ); return *this; } # endif // gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) #else // a.k.a. ! gsl_HAVE( MOVE_FORWARD ) template< class U > gsl_api gsl_constexpr14 not_null( not_null const& other ) : data_( T( detail::not_null_accessor::get_checked( other ) ) ) { } template< class U > gsl_api gsl_constexpr14 not_null& operator=( not_null const & other ) { data_.ptr_ = detail::not_null_accessor::get_checked( other ); return *this; } #endif // gsl_HAVE( MOVE_FORWARD ) #if gsl_CONFIG( TRANSPARENT_NOT_NULL ) gsl_NODISCARD gsl_api gsl_constexpr14 element_type * get() const { return accessor::get_checked( *this ).get(); } #else # if gsl_CONFIG( NOT_NULL_GET_BY_CONST_REF ) gsl_NODISCARD gsl_api gsl_constexpr14 T const & get() const { return accessor::get_checked( *this ); } # else gsl_NODISCARD gsl_api gsl_constexpr14 T get() const { return accessor::get_checked( *this ); } # endif #endif // We want an implicit conversion operator that can be used to convert from both lvalues (by // const reference or by copy) and rvalues (by move). So it seems like we could define // // template< class U > // operator U const &() const & { ... } // template< class U > // operator U &&() && { ... } // // However, having two conversion operators with different return types renders the assignment // operator of the result type ambiguous: // // not_null> p( ... ); // std::unique_ptr q; // q = std::move( p ); // ambiguous // // To avoid this ambiguity, we have both overloads of the conversion operator return `U` // rather than `U const &` or `U &&`. This implies that converting an lvalue always induces // a copy, which can cause unnecessary copies or even fail to compile in some situations: // // not_null> sp( ... ); // std::shared_ptr const & rs = sp; // unnecessary copy // std::unique_ptr const & ru = p; // error: cannot copy `unique_ptr` // // However, these situations are rather unusual, and the following, more frequent situations // remain unimpaired: // // std::shared_ptr vs = sp; // no extra copy // std::unique_ptr vu = std::move( p ); #if gsl_HAVE( MOVE_FORWARD ) && gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && gsl_HAVE( EXPLICIT ) // explicit conversion operator template< class U // We *have* to use SFINAE with an NTTP arg here, otherwise the overload is ambiguous. , typename std::enable_if< ( std::is_constructible::value && !std::is_convertible::value && !detail::is_not_null_or_bool_oracle::value ), int >::type = 0 > gsl_NODISCARD gsl_api gsl_constexpr14 explicit operator U() const # if gsl_HAVE( FUNCTION_REF_QUALIFIER ) & # endif { return U( accessor::get_checked( *this ) ); } # if gsl_HAVE( FUNCTION_REF_QUALIFIER ) template< class U // We *have* to use SFINAE with an NTTP arg here, otherwise the overload is ambiguous. , typename std::enable_if< ( std::is_constructible::value && !std::is_convertible::value && !detail::is_not_null_or_bool_oracle::value ), int >::type = 0 > gsl_NODISCARD gsl_api gsl_constexpr14 explicit operator U() && { return U( accessor::get_checked( std::move( *this ) ) ); } # endif // implicit conversion operator template< class U // We *have* to use SFINAE with an NTTP arg here, otherwise the overload is ambiguous. , typename std::enable_if< ( std::is_constructible::value && std::is_convertible::value && !detail::is_not_null_or_bool_oracle::value ), int >::type = 0 > gsl_NODISCARD gsl_api gsl_constexpr14 operator U() const # if gsl_HAVE( FUNCTION_REF_QUALIFIER ) & # endif { return accessor::get_checked( *this ); } # if gsl_HAVE( FUNCTION_REF_QUALIFIER ) template< class U // We *have* to use SFINAE with an NTTP arg here, otherwise the overload is ambiguous. , typename std::enable_if< ( std::is_convertible::value && !detail::is_not_null_or_bool_oracle::value ), int >::type = 0 > gsl_NODISCARD gsl_api gsl_constexpr14 operator U() && { return accessor::get_checked( std::move( *this ) ); } # endif #else // a.k.a. #if !( gsl_HAVE( MOVE_FORWARD ) && gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && gsl_HAVE( EXPLICIT ) ) template< class U > gsl_NODISCARD gsl_api gsl_constexpr14 operator U() const { return U( accessor::get_checked( *this ) ); } #endif // gsl_HAVE( MOVE_FORWARD ) && gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && gsl_HAVE( EXPLICIT ) gsl_NODISCARD gsl_api gsl_constexpr14 T const & operator->() const { return accessor::get_checked( *this ); } #if gsl_HAVE( MOVE_FORWARD ) // Visual C++ 2013 doesn't generate default move constructors, so we declare them explicitly. gsl_api gsl_constexpr14 not_null( not_null && other ) gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion : data_( std::move( other.data_ ) ) { } gsl_api gsl_constexpr14 not_null & operator=( not_null && other ) gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion { data_ = std::move( other.data_ ); return *this; } #endif // gsl_HAVE( MOVE_FORWARD ) #if gsl_HAVE( IS_DEFAULT ) gsl_constexpr14 not_null( not_null const & ) = default; gsl_constexpr14 not_null & operator=( not_null const & ) = default; #endif gsl_api gsl_constexpr20 friend void swap( not_null & lhs, not_null & rhs ) gsl_noexcept_not_testing // we want to be nothrow-swappable despite the precondition check { accessor::check( lhs ); accessor::check( rhs ); using std::swap; swap( lhs.data_.ptr_, rhs.data_.ptr_ ); } gsl_is_delete_access: not_null() gsl_is_delete; // prevent compilation when initialized with a nullptr or literal 0: #if gsl_HAVE( NULLPTR ) not_null( std::nullptr_t ) gsl_is_delete; not_null & operator=( std::nullptr_t ) gsl_is_delete; #else not_null( int ) gsl_is_delete; not_null & operator=( int ) gsl_is_delete; #endif // unwanted operators...pointers only point to single objects! not_null & operator++() gsl_is_delete; not_null & operator--() gsl_is_delete; not_null operator++( int ) gsl_is_delete; not_null operator--( int ) gsl_is_delete; not_null & operator+ ( size_t ) gsl_is_delete; not_null & operator+=( size_t ) gsl_is_delete; not_null & operator- ( size_t ) gsl_is_delete; not_null & operator-=( size_t ) gsl_is_delete; not_null & operator+=( std::ptrdiff_t ) gsl_is_delete; not_null & operator-=( std::ptrdiff_t ) gsl_is_delete; void operator[]( std::ptrdiff_t ) const gsl_is_delete; }; #if gsl_HAVE( DEDUCTION_GUIDES ) template< class U > not_null( U ) -> not_null; template< class U > not_null( not_null ) -> not_null; #endif #if gsl_HAVE( NULLPTR ) void make_not_null( std::nullptr_t ) gsl_is_delete; #endif // gsl_HAVE( NULLPTR ) #if gsl_HAVE( MOVE_FORWARD ) template< class U > gsl_NODISCARD gsl_api gsl_constexpr14 not_null make_not_null( U u ) { return not_null( std::move( u ) ); } template< class U > gsl_NODISCARD gsl_api gsl_constexpr14 not_null make_not_null( not_null u ) { return std::move( u ); } #else // a.k.a. ! gsl_HAVE( MOVE_FORWARD ) template< class U > gsl_NODISCARD gsl_api not_null make_not_null( U const & u ) { return not_null( u ); } template< class U > gsl_NODISCARD gsl_api not_null make_not_null( not_null const & u ) { return u; } #endif // gsl_HAVE( MOVE_FORWARD ) namespace detail { template< class T > struct as_nullable_helper { typedef T type; }; template< class T > struct as_nullable_helper< not_null > { }; template< class T > struct not_null_accessor { #if gsl_HAVE( MOVE_FORWARD ) static gsl_api T get( not_null&& p ) gsl_noexcept { return std::move( p.data_.ptr_ ); } static gsl_api T get_checked( not_null&& p ) { gsl_Assert( p.data_.ptr_ != gsl_nullptr ); return std::move( p.data_.ptr_ ); } #endif static gsl_api T const & get( not_null const & p ) gsl_noexcept { return p.data_.ptr_; } static gsl_api bool is_valid( not_null const & p ) gsl_noexcept { return p.data_.ptr_ != gsl_nullptr; } static gsl_api void check( not_null const & p ) { gsl_Assert( p.data_.ptr_ != gsl_nullptr ); } static gsl_api T const & get_checked( not_null const & p ) { gsl_Assert( p.data_.ptr_ != gsl_nullptr ); return p.data_.ptr_; } }; template< class T > struct not_null_accessor< T * > { static gsl_api T * const & get( not_null< T * > const & p ) gsl_noexcept { return p.data_.ptr_; } static gsl_api bool is_valid( not_null< T * > const & /*p*/ ) gsl_noexcept { return true; } static gsl_api void check( not_null< T * > const & /*p*/ ) { } static gsl_api T * const & get_checked( not_null< T * > const & p ) gsl_noexcept { return p.data_.ptr_; } }; namespace no_adl { #if gsl_HAVE( MOVE_FORWARD ) template< class T > gsl_NODISCARD gsl_api gsl_constexpr auto as_nullable( T && p ) gsl_noexcept_if( std::is_nothrow_move_constructible::value ) -> typename detail::as_nullable_helper::type>::type { return std::move( p ); } template< class T > gsl_NODISCARD gsl_api gsl_constexpr14 T as_nullable( not_null && p ) { return detail::not_null_accessor::get_checked( std::move( p ) ); } #else // ! gsl_HAVE( MOVE_FORWARD ) template< class T > gsl_NODISCARD gsl_api gsl_constexpr T const & as_nullable( T const & p ) gsl_noexcept { return p; } #endif // gsl_HAVE( MOVE_FORWARD ) template< class T > gsl_NODISCARD gsl_api gsl_constexpr14 T const & as_nullable( not_null const & p ) { return detail::not_null_accessor::get_checked( p ); } template< class T > gsl_NODISCARD gsl_api gsl_constexpr bool is_valid( not_null const & p ) { return detail::not_null_accessor::is_valid( p ); } } // namespace no_adl } // namespace detail using namespace detail::no_adl; // not_null with implicit constructor, allowing copy-initialization: template< class T > class not_null_ic : public not_null { public: template< class U gsl_ENABLE_IF_(( std::is_constructible::value )) > gsl_api gsl_constexpr14 #if gsl_HAVE( MOVE_FORWARD ) not_null_ic( U u ) : not_null( std::move( u ) ) #else // ! gsl_HAVE( MOVE_FORWARD ) not_null_ic( U const & u ) : not_null( u ) #endif // gsl_HAVE( MOVE_FORWARD ) {} }; // more not_null unwanted operators template< class T, class U > std::ptrdiff_t operator-( not_null const &, not_null const & ) gsl_is_delete; template< class T > not_null operator-( not_null const &, std::ptrdiff_t ) gsl_is_delete; template< class T > not_null operator+( not_null const &, std::ptrdiff_t ) gsl_is_delete; template< class T > not_null operator+( std::ptrdiff_t, not_null const & ) gsl_is_delete; // not_null comparisons #if gsl_HAVE( NULLPTR ) && gsl_HAVE( IS_DELETE ) template< class T > gsl_constexpr bool operator==( not_null const &, std::nullptr_t ) = delete; template< class T > gsl_constexpr bool operator==( std::nullptr_t , not_null const & ) = delete; template< class T > gsl_constexpr bool operator!=( not_null const &, std::nullptr_t ) = delete; template< class T > gsl_constexpr bool operator!=( std::nullptr_t , not_null const & ) = delete; #endif // gsl_HAVE( NULLPTR ) && gsl_HAVE( IS_DELETE ) template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator==( not_null const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( l.operator->() == r.operator->() ) { return l.operator->() == r.operator->(); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator==( not_null const & l, U const & r ) gsl_RETURN_DECLTYPE_(l.operator->() == r ) { return l.operator->() == r; } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator==( T const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( l == r.operator->() ) { return l == r.operator->(); } // The C++ Core Guidelines discourage the use of pointer arithmetic, and gsl-lite consequently refrains from defining operators // for pointer arithmetic or the subscript operator in `not_null<>`. However, comparison of `not_null<>` objects is supported; // although the standard does not mandate a certain ordering for objects with two exceptions (objects from the same array; // data members of the same class, as required for `offsetof()`), it does require that `operator<` establishes a total ordering // of pointers, as implied by https://eel.is/c++draft/expr.rel#5. Among other things, this guarantees that a list of pointers // can be sorted and searched, or that pointers can be used as a key in a relational container such as `std::map<>`. // Therefore, we also define relational comparison operators for `not_null<>`. template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator<( not_null const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( l.operator->() < r.operator->() ) { return l.operator->() < r.operator->(); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator<( not_null const & l, U const & r ) gsl_RETURN_DECLTYPE_( l.operator->() < r ) { return l.operator->() < r; } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator<( T const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( l < r.operator->() ) { return l < r.operator->(); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator!=( not_null const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( !( l == r ) ) { return !( l == r ); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator!=( not_null const & l, U const & r ) gsl_RETURN_DECLTYPE_( !( l == r ) ) { return !( l == r ); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator!=( T const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( !( l == r ) ) { return !( l == r ); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator<=( not_null const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( !( r < l ) ) { return !( r < l ); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator<=( not_null const & l, U const & r ) gsl_RETURN_DECLTYPE_( !( r < l ) ) { return !( r < l ); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator<=( T const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( !( r < l ) ) { return !( r < l ); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator>( not_null const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( r < l ) { return r < l; } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator>( not_null const & l, U const & r ) gsl_RETURN_DECLTYPE_( r < l ) { return r < l; } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator>( T const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( r < l ) { return r < l; } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator>=( not_null const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( !( l < r ) ) { return !( l < r ); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator>=( not_null const & l, U const & r ) gsl_RETURN_DECLTYPE_( !( l < r ) ) { return !( l < r ); } template< class T, class U > gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_( bool ) operator>=( T const & l, not_null const & r ) gsl_RETURN_DECLTYPE_( !( l < r ) ) { return !( l < r ); } // print not_null template< class CharType, class Traits, class T > std::basic_ostream< CharType, Traits > & operator<<( std::basic_ostream< CharType, Traits > & os, not_null const & p ) { return os << p.operator->(); } #if gsl_HAVE( VARIADIC_TEMPLATE ) # if gsl_HAVE( UNIQUE_PTR ) template< class T, class... Args > gsl_NODISCARD not_null> make_unique( Args &&... args ) { # if gsl_HAVE( TYPE_TRAITS ) static_assert( !std::is_array::value, "gsl::make_unique() returns `gsl::not_null>`, which is not " "defined for array types because the Core Guidelines advise against pointer arithmetic, cf. \"Bounds safety profile\"." ); # endif return not_null>( new T( std::forward( args )... ) ); } # endif // gsl_HAVE( UNIQUE_PTR ) # if gsl_HAVE( SHARED_PTR ) template< class T, class... Args > gsl_NODISCARD not_null> make_shared( Args &&... args ) { # if gsl_HAVE( TYPE_TRAITS ) static_assert( !std::is_array::value, "gsl::make_shared() returns `gsl::not_null>`, which is not " "defined for array types because the Core Guidelines advise against pointer arithmetic, cf. \"Bounds safety profile\"." ); # endif return not_null>( std::make_shared( std::forward( args )... ) ); } # endif // gsl_HAVE( SHARED_PTR ) #endif // gsl_HAVE( VARIADIC_TEMPLATE ) // // 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 template< class T > gsl_NODISCARD 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< class IntegerType gsl_ENABLE_IF_(( std::is_integral::value )) > gsl_NODISCARD 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_NODISCARD gsl_api inline gsl_constexpr unsigned char to_uchar( byte b ) gsl_noexcept { return to_integer( b ); } gsl_NODISCARD gsl_api inline gsl_constexpr unsigned char to_uchar( int i ) gsl_noexcept { return static_cast( i ); } template< class IntegerType gsl_ENABLE_IF_(( std::is_integral::value )) > gsl_api inline gsl_constexpr14 byte & operator<<=( byte & b, IntegerType shift ) gsl_noexcept { #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) return b = ::gsl::to_byte( ::gsl::to_uchar( b ) << shift ); #else b.v = ::gsl::to_uchar( b.v << shift ); return b; #endif } template< class IntegerType gsl_ENABLE_IF_(( std::is_integral::value )) > gsl_NODISCARD gsl_api inline gsl_constexpr byte operator<<( byte b, IntegerType shift ) gsl_noexcept { return ::gsl::to_byte( ::gsl::to_uchar( b ) << shift ); } template< class IntegerType gsl_ENABLE_IF_(( std::is_integral::value )) > gsl_NODISCARD gsl_api inline gsl_constexpr14 byte & operator>>=( byte & b, IntegerType shift ) gsl_noexcept { #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) return b = ::gsl::to_byte( ::gsl::to_uchar( b ) >> shift ); #else b.v = ::gsl::to_uchar( b.v >> shift ); return b; #endif } template< class IntegerType gsl_ENABLE_IF_(( std::is_integral::value )) > gsl_NODISCARD gsl_api inline gsl_constexpr byte operator>>( byte b, IntegerType shift ) gsl_noexcept { return ::gsl::to_byte( ::gsl::to_uchar( b ) >> shift ); } #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) gsl_DEFINE_ENUM_BITMASK_OPERATORS( byte ) gsl_DEFINE_ENUM_RELATIONAL_OPERATORS( byte ) #else // a.k.a. !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 ); } gsl_api inline gsl_constexpr14 byte & operator|=( byte & l, byte r ) gsl_noexcept { l.v |= r.v; return l; } gsl_api inline gsl_constexpr byte operator|( byte l, byte r ) gsl_noexcept { return ::gsl::to_byte( l.v | r.v ); } gsl_api inline gsl_constexpr14 byte & operator&=( byte & l, byte r ) gsl_noexcept { l.v &= r.v; return l; } gsl_api inline gsl_constexpr byte operator&( byte l, byte r ) gsl_noexcept { return ::gsl::to_byte( l.v & r.v ); } gsl_api inline gsl_constexpr14 byte & operator^=( byte & l, byte r ) gsl_noexcept { l.v ^= r.v; return l; } gsl_api inline gsl_constexpr byte operator^( byte l, byte r ) gsl_noexcept { return ::gsl::to_byte( l.v ^ r.v ); } gsl_api inline gsl_constexpr byte operator~( byte b ) gsl_noexcept { return ::gsl::to_byte( ~b.v ); } #endif // gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) #if gsl_FEATURE_TO_STD( WITH_CONTAINER ) // Tag to select span constructor taking a container: struct with_container_t { gsl_constexpr with_container_t( ) gsl_noexcept { } }; const gsl_constexpr with_container_t with_container; // TODO: this can lead to ODR violations because the symbol will be defined in multiple translation units #endif namespace detail { template< class T > gsl_api gsl_constexpr14 T * endptr( T * data, gsl_CONFIG_SPAN_INDEX_TYPE size ) { // Be sure to run the check before doing pointer arithmetics, which would be UB for `nullptr` and non-0 integers. gsl_Expects( size == 0 || data != gsl_nullptr ); return data + size; } } // namespace detail // // span<> - A 1D view of contiguous T's, replace (*,len). // template< class T > class span { template< class U > friend class span; public: typedef gsl_CONFIG_SPAN_INDEX_TYPE index_type; 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 pointer iterator; typedef const_pointer const_iterator; typedef std::reverse_iterator< iterator > reverse_iterator; typedef std::reverse_iterator< const_iterator > const_reverse_iterator; typedef gsl_CONFIG_SPAN_INDEX_TYPE size_type; typedef std::ptrdiff_t difference_type; // 26.7.3.2 Constructors, copy, and assignment [span.cons] gsl_api gsl_constexpr span() gsl_noexcept : first_( gsl_nullptr ) , last_ ( gsl_nullptr ) { } #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 ) { gsl_Expects( size_in == 0 ); } #endif #if gsl_HAVE( IS_DELETE ) gsl_DEPRECATED 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_( detail::endptr( data_in, size_in ) ) { } gsl_api gsl_constexpr14 span( pointer first_in, pointer last_in ) : first_( first_in ) , last_ ( last_in ) { gsl_Expects( first_in <= last_in ); } #if ! gsl_DEPRECATE_TO_LEVEL( 5 ) template< class U > gsl_api gsl_constexpr14 span( U * data_in, index_type size_in ) : first_( data_in ) , last_( detail::endptr( data_in, size_in ) ) { } #endif // deprecate #if ! gsl_DEPRECATE_TO_LEVEL( 5 ) template< class U, size_t N > gsl_api gsl_constexpr span( U (&arr)[N] ) gsl_noexcept : first_( gsl_ADDRESSOF( arr[0] ) ) , last_ ( gsl_ADDRESSOF( arr[0] ) + N ) {} #else template< size_t N gsl_ENABLE_IF_(( std::is_convertible::value )) > 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< class U, size_t N > gsl_api gsl_constexpr span( std::array< U, N > & arr ) : first_( arr.data() ) , last_ ( arr.data() + N ) {} template< class U, size_t N > gsl_api gsl_constexpr span( std::array< U, N > const & arr ) : first_( arr.data() ) , last_ ( arr.data() + N ) {} #else template< size_t N gsl_ENABLE_IF_(( std::is_convertible::value )) > gsl_constexpr span( std::array< value_type, N > & arr ) : first_( arr.data() ) , last_ ( arr.data() + N ) {} template< size_t N gsl_ENABLE_IF_(( std::is_convertible::value )) > gsl_constexpr span( std::array< value_type, N > const & arr ) : first_( arr.data() ) , last_ ( arr.data() + N ) {} #endif // deprecate #endif // gsl_HAVE( ARRAY ) #if gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) template< class Container gsl_ENABLE_IF_(( detail::is_compatible_container< Container, element_type >::value )) > gsl_api gsl_constexpr span( Container & cont ) gsl_noexcept : first_( std17::data( cont ) ) , last_ ( std17::data( cont ) + std17::size( cont ) ) {} template< class Container gsl_ENABLE_IF_(( std::is_const< element_type >::value && detail::is_compatible_container< Container, element_type >::value )) > gsl_api gsl_constexpr span( Container const & cont ) gsl_noexcept : first_( std17::data( cont ) ) , last_ ( std17::data( cont ) + std17::size( cont ) ) {} #elif gsl_HAVE( UNCONSTRAINED_SPAN_CONTAINER_CTOR ) template< class Container > 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< class Container > 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< class Container > gsl_constexpr span( with_container_t, Container & cont ) gsl_noexcept : first_( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) ) , last_ ( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) + cont.size() ) {} template< class Container > gsl_constexpr span( with_container_t, Container const & cont ) gsl_noexcept : 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_DEPRECATED 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< class ArrayElementType = typename std::add_pointer::type > # else template< class ArrayElementType > # endif gsl_DEPRECATED gsl_constexpr span( unique_ptr const & ptr, index_type count ) : first_( ptr.get() ) , last_ ( ptr.get() + count ) {} gsl_DEPRECATED 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 ) gsl_constexpr14 span & operator=( span && ) gsl_noexcept = default; gsl_constexpr14 span & operator=( span const & ) gsl_noexcept = default; #else gsl_constexpr14 span & operator=( span other ) gsl_noexcept { first_ = other.first_; last_ = other.last_; return *this; } #endif template< class U gsl_ENABLE_IF_(( std::is_convertible::value )) > 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_NODISCARD gsl_api gsl_constexpr14 span first( index_type count ) const { gsl_Expects( std::size_t( count ) <= std::size_t( this->size() ) ); return span( this->data(), count ); } gsl_NODISCARD gsl_api gsl_constexpr14 span last( index_type count ) const { gsl_Expects( std::size_t( count ) <= std::size_t( this->size() ) ); return span( this->data() + this->size() - count, count ); } gsl_NODISCARD gsl_api gsl_constexpr14 span subspan( index_type offset ) const { gsl_Expects( std::size_t( offset ) <= std::size_t( this->size() ) ); return span( this->data() + offset, this->size() - offset ); } gsl_NODISCARD gsl_api gsl_constexpr14 span subspan( index_type offset, index_type count ) const { gsl_Expects( std::size_t( offset ) <= std::size_t( this->size() ) && std::size_t( count ) <= std::size_t( this->size() - offset ) ); return span( this->data() + offset, count ); } // 26.7.3.4 Observers [span.obs] gsl_NODISCARD gsl_api gsl_constexpr index_type size() const gsl_noexcept { return narrow_cast( last_ - first_ ); } gsl_NODISCARD gsl_api gsl_constexpr std::ptrdiff_t ssize() const gsl_noexcept { return narrow_cast( last_ - first_ ); } gsl_NODISCARD gsl_api gsl_constexpr index_type size_bytes() const gsl_noexcept { return size() * narrow_cast( sizeof( element_type ) ); } gsl_NODISCARD gsl_api gsl_constexpr bool empty() const gsl_noexcept { return size() == 0; } // 26.7.3.5 Element access [span.elem] gsl_NODISCARD gsl_api gsl_constexpr14 reference operator[]( index_type pos ) const { gsl_Expects( pos < size() ); return first_[ pos ]; } #if ! gsl_DEPRECATE_TO_LEVEL( 6 ) gsl_DEPRECATED_MSG("use subscript indexing instead") gsl_api gsl_constexpr14 reference operator()( index_type pos ) const { return (*this)[ pos ]; } gsl_DEPRECATED_MSG("use subscript indexing instead") gsl_api gsl_constexpr14 reference at( index_type pos ) const { return (*this)[ pos ]; } #endif // deprecate gsl_NODISCARD gsl_api gsl_constexpr14 reference front() const { gsl_Expects( first_ != last_ ); return *first_; } gsl_NODISCARD gsl_api gsl_constexpr14 reference back() const { gsl_Expects( first_ != last_ ); return *(last_ - 1); } gsl_NODISCARD gsl_api gsl_constexpr pointer data() const gsl_noexcept { return first_; } // 26.7.3.6 Iterator support [span.iterators] gsl_NODISCARD gsl_api gsl_constexpr iterator begin() const gsl_noexcept { return iterator( first_ ); } gsl_NODISCARD gsl_api gsl_constexpr iterator end() const gsl_noexcept { return iterator( last_ ); } gsl_NODISCARD gsl_api gsl_constexpr const_iterator cbegin() const gsl_noexcept { #if gsl_CPP11_OR_GREATER return { begin() }; #else return const_iterator( begin() ); #endif } gsl_NODISCARD gsl_api gsl_constexpr const_iterator cend() const gsl_noexcept { #if gsl_CPP11_OR_GREATER return { end() }; #else return const_iterator( end() ); #endif } gsl_NODISCARD gsl_constexpr17 reverse_iterator rbegin() const gsl_noexcept { return reverse_iterator( end() ); } gsl_NODISCARD gsl_constexpr17 reverse_iterator rend() const gsl_noexcept { return reverse_iterator( begin() ); } gsl_NODISCARD gsl_constexpr17 const_reverse_iterator crbegin() const gsl_noexcept { return const_reverse_iterator( cend() ); } gsl_NODISCARD gsl_constexpr17 const_reverse_iterator crend() const gsl_noexcept { return const_reverse_iterator( cbegin() ); } gsl_constexpr14 void swap( span & other ) gsl_noexcept { std::swap( first_, other.first_ ); std::swap( last_ , other.last_ ); } #if ! gsl_DEPRECATE_TO_LEVEL( 3 ) // member length() deprecated since 0.29.0 gsl_DEPRECATED_MSG("use size() instead") gsl_api gsl_constexpr index_type length() const gsl_noexcept { return size(); } // member length_bytes() deprecated since 0.29.0 gsl_DEPRECATED_MSG("use size_bytes() instead") 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_DEPRECATED_MSG("use free function gsl::as_bytes() instead") gsl_api span< const byte > as_bytes() const gsl_noexcept { return span< const byte >( reinterpret_cast( data() ), size_bytes() ); // NOLINT } gsl_DEPRECATED_MSG("use free function gsl::as_writable_bytes() instead") gsl_api span< byte > as_writeable_bytes() const gsl_noexcept { return span< byte >( reinterpret_cast( data() ), size_bytes() ); // NOLINT } #endif template< class U > gsl_NODISCARD gsl_api span< U > as_span() const { gsl_Expects( ( this->size_bytes() % sizeof(U) ) == 0 ); return span< U >( 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< class T, size_t N > span( T (&)[N] ) -> span; template< class T, size_t N > span( std::array & ) -> span; template< class T, size_t N > span( std::array const & ) -> span; template< class Container > span( Container& ) -> span; template< class Container > span( Container const & ) -> span; #endif // gsl_HAVE( DEDUCTION_GUIDES ) // 26.7.3.7 Comparison operators [span.comparison] #if gsl_CONFIG( ALLOWS_SPAN_COMPARISON ) # if gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template< class T, class U > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr bool operator==( span const & l, span const & r ) { return l.size() == r.size() && (l.begin() == r.begin() || detail::equal( l.begin(), l.end(), r.begin() ) ); } template< class T, class U > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr bool operator< ( span const & l, span const & r ) { return detail::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); } # else // a.k.a. !gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template< class T > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr bool operator==( span const & l, span const & r ) { return l.size() == r.size() && (l.begin() == r.begin() || detail::equal( l.begin(), l.end(), r.begin() ) ); } template< class T > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr bool operator< ( span const & l, span const & r ) { return detail::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); } # endif // gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template< class T, class U > gsl_NODISCARD inline gsl_constexpr bool operator!=( span const & l, span const & r ) { return !( l == r ); } template< class T, class U > gsl_NODISCARD inline gsl_constexpr bool operator<=( span const & l, span const & r ) { return !( r < l ); } template< class T, class U > gsl_NODISCARD inline gsl_constexpr bool operator> ( span const & l, span const & r ) { return ( r < l ); } template< class T, class U > gsl_NODISCARD inline gsl_constexpr bool operator>=( span const & l, span const & r ) { return !( l < r ); } #endif // gsl_CONFIG( ALLOWS_SPAN_COMPARISON ) // span algorithms template< class T > gsl_NODISCARD gsl_api inline gsl_constexpr std::size_t size( span const & spn ) { return static_cast( spn.size() ); } template< class T > gsl_NODISCARD gsl_api inline gsl_constexpr std::ptrdiff_t ssize( span const & spn ) { return spn.ssize(); } namespace detail { template< class II, class N, class OI > gsl_api gsl_constexpr14 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; } } template< class T, class U > gsl_api gsl_constexpr14 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 gsl_Expects( dest.size() >= src.size() ); detail::copy_n( src.data(), src.size(), dest.data() ); } // span creator functions (see ctors) template< class T > gsl_NODISCARD gsl_api inline span< const byte > as_bytes( span spn ) gsl_noexcept { return span< const byte >( reinterpret_cast( spn.data() ), spn.size_bytes() ); // NOLINT } template< class T> gsl_NODISCARD gsl_api inline span< byte > as_writable_bytes( span spn ) gsl_noexcept { return span< byte >( reinterpret_cast( spn.data() ), spn.size_bytes() ); // NOLINT } #if ! gsl_DEPRECATE_TO_LEVEL( 6 ) template< class T> gsl_DEPRECATED_MSG("use as_writable_bytes() (different spelling) instead") gsl_api inline span< byte > as_writeable_bytes( span spn ) gsl_noexcept { return span< byte >( reinterpret_cast( spn.data() ), spn.size_bytes() ); // NOLINT } #endif // deprecate #if gsl_FEATURE_TO_STD( MAKE_SPAN ) template< class T > gsl_NODISCARD gsl_api inline gsl_constexpr span make_span( T * ptr, typename span::index_type count ) { return span( ptr, count ); } template< class T > gsl_NODISCARD gsl_api inline gsl_constexpr span make_span( T * first, T * last ) { return span( first, last ); } template< class T, size_t N > gsl_NODISCARD inline gsl_constexpr span make_span( T (&arr)[N] ) { return span( gsl_ADDRESSOF( arr[0] ), N ); } #if gsl_HAVE( ARRAY ) template< class T, size_t N > gsl_NODISCARD inline gsl_constexpr span make_span( std::array & arr ) { return span( arr ); } template< class T, size_t N > gsl_NODISCARD 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< class Container, class EP = decltype( std17::data(std::declval())) > gsl_NODISCARD inline gsl_constexpr auto make_span( Container & cont ) -> span< typename std::remove_pointer::type > { return span< typename std::remove_pointer::type >( cont ); } template< class Container, class EP = decltype( std17::data(std::declval())) > gsl_NODISCARD inline gsl_constexpr auto make_span( Container const & cont ) -> span< const typename std::remove_pointer::type > { return span< const typename std::remove_pointer::type >( cont ); } #else template< class T > inline span make_span( std::vector & cont ) { return span( with_container, cont ); } template< class T > inline span make_span( std::vector const & cont ) { return span( with_container, cont ); } #endif #if gsl_FEATURE_TO_STD( WITH_CONTAINER ) template< class Container > gsl_NODISCARD inline gsl_constexpr span make_span( with_container_t, Container & cont ) gsl_noexcept { return span< typename Container::value_type >( with_container, cont ); } template< class Container > gsl_NODISCARD inline gsl_constexpr span make_span( with_container_t, Container const & cont ) gsl_noexcept { return span< const typename Container::value_type >( with_container, cont ); } #endif // gsl_FEATURE_TO_STD( WITH_CONTAINER ) #if !gsl_DEPRECATE_TO_LEVEL( 4 ) template< class Ptr > gsl_DEPRECATED inline span make_span( Ptr & ptr ) { return span( ptr ); } #endif // !gsl_DEPRECATE_TO_LEVEL( 4 ) template< class Ptr > gsl_DEPRECATED 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< class T > gsl_NODISCARD gsl_api inline gsl_constexpr span byte_span( T & t ) gsl_noexcept { return span( reinterpret_cast( &t ), sizeof(T) ); } template< class T > gsl_NODISCARD 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 ) //#if gsl_FEATURE( STRING_SPAN ) // // basic_string_span: // template< class T > class basic_string_span; namespace detail { template< class T > struct is_basic_string_span_oracle : std11::false_type {}; template< class T > struct is_basic_string_span_oracle< basic_string_span > : std11::true_type {}; template< class T > struct is_basic_string_span : is_basic_string_span_oracle< typename std11::remove_cv::type > {}; template< class T > 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 T > class basic_string_span { public: typedef T element_type; typedef span span_type; typedef typename span_type::size_type size_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 ) gsl_noexcept : span_( nullptr, static_cast( 0 ) ) {} #endif #ifdef __CUDACC_RELAXED_CONSTEXPR__ gsl_api #endif // __CUDACC_RELAXED_CONSTEXPR__ #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( pointer ptr ) : span_( remove_z( ptr, (std::numeric_limits::max)() ) ) {} #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_api gsl_constexpr basic_string_span( pointer ptr, index_type count ) : span_( ptr, count ) {} #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_api gsl_constexpr basic_string_span( pointer firstElem, pointer lastElem ) : span_( firstElem, lastElem ) {} template< std::size_t N > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( element_type (&arr)[N] ) : span_( remove_z( gsl_ADDRESSOF( arr[0] ), N ) ) {} #if gsl_HAVE( ARRAY ) template< std::size_t N > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( std::array< typename std11::remove_const::type, N> & arr ) : span_( remove_z( arr ) ) {} template< std::size_t N > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( std::array< typename std11::remove_const::type, N> const & arr ) : span_( remove_z( arr ) ) {} #endif #if gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) // Exclude: array, [basic_string,] basic_string_span template< class Container gsl_ENABLE_IF_(( ! detail::is_std_array< Container >::value && ! detail::is_basic_string_span< Container >::value && std::is_convertible< typename Container::pointer, pointer >::value && std::is_convertible< typename Container::pointer, decltype(std::declval().data()) >::value )) > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( Container & cont ) : span_( ( cont ) ) {} // Exclude: array, [basic_string,] basic_string_span template< class Container gsl_ENABLE_IF_(( ! detail::is_std_array< Container >::value && ! detail::is_basic_string_span< Container >::value && std::is_convertible< typename Container::pointer, pointer >::value && std::is_convertible< typename Container::pointer, decltype(std::declval().data()) >::value )) > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( Container const & cont ) : span_( ( cont ) ) {} #elif gsl_HAVE( UNCONSTRAINED_SPAN_CONTAINER_CTOR ) template< class Container > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( Container & cont ) : span_( cont ) {} template< class Container > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( Container const & cont ) : span_( cont ) {} #else template< class U > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_api gsl_constexpr basic_string_span( span const & rhs ) : span_( rhs ) {} #endif #if gsl_FEATURE_TO_STD( WITH_CONTAINER ) template< class Container > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) 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 & ) = default; gsl_constexpr basic_string_span( basic_string_span && ) = default; # else gsl_constexpr basic_string_span( basic_string_span const & ) gsl_noexcept = default; gsl_constexpr basic_string_span( basic_string_span && ) gsl_noexcept = default; # endif #endif template< class U gsl_ENABLE_IF_(( std::is_convertible::pointer, pointer>::value )) > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_api gsl_constexpr basic_string_span( basic_string_span const & rhs ) : span_( reinterpret_cast( rhs.data() ), rhs.length() ) // NOLINT {} #if gsl_STDLIB_CPP11_120 template< class U gsl_ENABLE_IF_(( std::is_convertible::pointer, pointer>::value )) > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_api gsl_constexpr basic_string_span( basic_string_span && rhs ) : span_( reinterpret_cast( rhs.data() ), rhs.length() ) // NOLINT {} #endif // gsl_STDLIB_CPP11_120 template< class CharTraits, class Allocator > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( std::basic_string< typename std11::remove_const::type, CharTraits, Allocator > & str ) : span_( gsl_ADDRESSOF( str[0] ), str.length() ) {} template< class CharTraits, class Allocator > #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_constexpr basic_string_span( std::basic_string< typename std11::remove_const::type, CharTraits, Allocator > const & str ) : span_( gsl_ADDRESSOF( str[0] ), str.length() ) {} // assignment: #if gsl_HAVE( IS_DEFAULT ) gsl_constexpr14 basic_string_span & operator=( basic_string_span const & ) gsl_noexcept = default; gsl_constexpr14 basic_string_span & operator=( basic_string_span && ) gsl_noexcept = default; #endif // sub span: /*gsl_api*/ // currently disabled due to an apparent NVCC bug gsl_NODISCARD gsl_constexpr14 basic_string_span first( index_type count ) const { return span_.first( count ); } /*gsl_api*/ // currently disabled due to an apparent NVCC bug gsl_NODISCARD gsl_constexpr14 basic_string_span last( index_type count ) const { return span_.last( count ); } /*gsl_api*/ // currently disabled due to an apparent NVCC bug gsl_NODISCARD gsl_constexpr14 basic_string_span subspan( index_type offset ) const { return span_.subspan( offset ); } /*gsl_api*/ // currently disabled due to an apparent NVCC bug gsl_NODISCARD gsl_constexpr14 basic_string_span subspan( index_type offset, index_type count ) const { return span_.subspan( offset, count ); } // observers: gsl_NODISCARD gsl_api gsl_constexpr index_type length() const gsl_noexcept { return span_.size(); } gsl_NODISCARD gsl_api gsl_constexpr index_type size() const gsl_noexcept { return span_.size(); } gsl_NODISCARD gsl_api gsl_constexpr index_type length_bytes() const gsl_noexcept { return span_.size_bytes(); } gsl_NODISCARD gsl_api gsl_constexpr index_type size_bytes() const gsl_noexcept { return span_.size_bytes(); } gsl_NODISCARD gsl_api gsl_constexpr bool empty() const gsl_noexcept { return size() == 0; } gsl_NODISCARD gsl_api gsl_constexpr14 reference operator[]( index_type idx ) const { return span_[idx]; } #if ! gsl_DEPRECATE_TO_LEVEL( 6 ) gsl_DEPRECATED_MSG("use subscript indexing instead") gsl_api gsl_constexpr14 reference operator()( index_type idx ) const { return span_[idx]; } #endif // deprecate gsl_NODISCARD gsl_api gsl_constexpr14 reference front() const { return span_.front(); } gsl_NODISCARD gsl_api gsl_constexpr14 reference back() const { return span_.back(); } gsl_NODISCARD gsl_api gsl_constexpr pointer data() const gsl_noexcept { return span_.data(); } gsl_NODISCARD gsl_api gsl_constexpr iterator begin() const gsl_noexcept { return span_.begin(); } gsl_NODISCARD gsl_api gsl_constexpr iterator end() const gsl_noexcept { return span_.end(); } gsl_NODISCARD gsl_constexpr17 reverse_iterator rbegin() const gsl_noexcept { return span_.rbegin(); } gsl_NODISCARD gsl_constexpr17 reverse_iterator rend() const gsl_noexcept { return span_.rend(); } // const version not in p0123r2: gsl_NODISCARD gsl_api gsl_constexpr const_iterator cbegin() const gsl_noexcept { return span_.cbegin(); } gsl_NODISCARD gsl_api gsl_constexpr const_iterator cend() const gsl_noexcept { return span_.cend(); } gsl_NODISCARD gsl_constexpr17 const_reverse_iterator crbegin() const gsl_noexcept { return span_.crbegin(); } gsl_NODISCARD gsl_constexpr17 const_reverse_iterator crend() const gsl_noexcept { return span_.crend(); } private: gsl_api static gsl_constexpr14 span_type remove_z( pointer sz, std::size_t max ) { return span_type( sz, detail::string_length( sz, max ) ); } #if gsl_HAVE( ARRAY ) template< size_t N > gsl_NODISCARD static gsl_constexpr14 span_type remove_z( std::array::type, N> & arr ) { return remove_z( gsl_ADDRESSOF( arr[0] ), narrow_cast< std::size_t >( N ) ); } template< size_t N > gsl_NODISCARD static gsl_constexpr14 span_type remove_z( std::array::type, N> const & arr ) { return remove_z( gsl_ADDRESSOF( arr[0] ), narrow_cast< std::size_t >( N ) ); } #endif private: span_type span_; }; // basic_string_span comparison functions: #if gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template< class T, class U > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator==( basic_string_span const & l, U const & u ) gsl_noexcept { const basic_string_span< typename std11::add_const::type > r( u ); return l.size() == r.size() && detail::equal( l.begin(), l.end(), r.begin() ); } template< class T, class U > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator<( basic_string_span const & l, U const & u ) gsl_noexcept { const basic_string_span< typename std11::add_const::type > r( u ); return detail::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); } #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) template< class T, class U gsl_ENABLE_IF_(( !detail::is_basic_string_span::value )) > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator==( U const & u, basic_string_span const & r ) gsl_noexcept { const basic_string_span< typename std11::add_const::type > l( u ); return l.size() == r.size() && detail::equal( l.begin(), l.end(), r.begin() ); } template< class T, class U gsl_ENABLE_IF_(( !detail::is_basic_string_span::value )) > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator<( U const & u, basic_string_span const & r ) gsl_noexcept { const basic_string_span< typename std11::add_const::type > l( u ); return detail::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); } #endif #else //gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template< class T > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator==( basic_string_span const & l, basic_string_span const & r ) gsl_noexcept { return l.size() == r.size() && detail::equal( l.begin(), l.end(), r.begin() ); } template< class T > gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator<( basic_string_span const & l, basic_string_span const & r ) gsl_noexcept { return detail::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); } #endif // gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template< class T, class U > gsl_NODISCARD inline gsl_constexpr14 bool operator!=( basic_string_span const & l, U const & r ) gsl_noexcept { return !( l == r ); } template< class T, class U > gsl_NODISCARD 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< typename std11::add_const::type > rr( r ); return !( rr < l ); #endif } template< class T, class U > gsl_NODISCARD 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< typename std11::add_const::type > rr( r ); return ( rr < l ); #endif } template< class T, class U > gsl_NODISCARD 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< class T, class U gsl_ENABLE_IF_(( !detail::is_basic_string_span::value )) > gsl_NODISCARD inline gsl_constexpr14 bool operator!=( U const & l, basic_string_span const & r ) gsl_noexcept { return !( l == r ); } template< class T, class U gsl_ENABLE_IF_(( !detail::is_basic_string_span::value )) > gsl_NODISCARD inline gsl_constexpr14 bool operator<=( U const & l, basic_string_span const & r ) gsl_noexcept { return !( r < l ); } template< class T, class U gsl_ENABLE_IF_(( !detail::is_basic_string_span::value )) > gsl_NODISCARD inline gsl_constexpr14 bool operator>( U const & l, basic_string_span const & r ) gsl_noexcept { return ( r < l ); } template< class T, class U gsl_ENABLE_IF_(( !detail::is_basic_string_span::value )) > gsl_NODISCARD 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< class T > gsl_NODISCARD gsl_api inline span< const byte > as_bytes( basic_string_span spn ) gsl_noexcept { return span< const byte >( reinterpret_cast( spn.data() ), spn.size_bytes() ); // NOLINT } //#endif // gsl_FEATURE( STRING_SPAN ) // // String types: // typedef char * zstring; typedef const char * czstring; #if gsl_HAVE( WCHAR ) typedef wchar_t * wzstring; typedef const wchar_t * cwzstring; #endif //#if gsl_FEATURE( STRING_SPAN ) typedef basic_string_span< char > string_span; typedef basic_string_span< char const > cstring_span; #if gsl_HAVE( WCHAR ) typedef basic_string_span< wchar_t > wstring_span; typedef basic_string_span< wchar_t const > cwstring_span; #endif // to_string() allow (explicit) conversions from string_span to string #if 0 template< class T > inline std::basic_string< typename std::remove_const::type > to_string( basic_string_span spn ) { std::string( spn.data(), spn.length() ); } #else gsl_NODISCARD inline std::string to_string( string_span const & spn ) { return std::string( spn.data(), static_cast( spn.length() ) ); } gsl_NODISCARD inline std::string to_string( cstring_span const & spn ) { return std::string( spn.data(), static_cast( spn.length() ) ); } #if gsl_HAVE( WCHAR ) gsl_NODISCARD inline std::wstring to_string( wstring_span const & spn ) { return std::wstring( spn.data(), static_cast( spn.length() ) ); } gsl_NODISCARD inline std::wstring to_string( cwstring_span const & spn ) { return std::wstring( spn.data(), static_cast( spn.length() ) ); } #endif // gsl_HAVE( WCHAR ) #endif // to_string() // // Stream output for string_span types // namespace detail { template< class Stream > void write_padding( Stream & os, std::streamsize n ) { for ( std::streamsize i = 0; i < n; ++i ) os.rdbuf()->sputc( os.fill() ); } template< class Stream, class Span > Stream & write_to_stream( Stream & os, Span const & spn ) { typename Stream::sentry sentry( os ); if ( !os ) return os; const std::streamsize length = gsl::narrow_failfast( 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 ) detail::write_padding( os, os.width() - length ); // Write span characters os.rdbuf()->sputn( spn.begin(), length ); if ( pad && !left_pad ) detail::write_padding( os, os.width() - length ); // Reset output stream width os.width(0); return os; } } // namespace detail template< typename Traits > std::basic_ostream< char, Traits > & operator<<( std::basic_ostream< char, Traits > & os, string_span const & spn ) { return detail::write_to_stream( os, spn ); } template< typename Traits > std::basic_ostream< char, Traits > & operator<<( std::basic_ostream< char, Traits > & os, cstring_span const & spn ) { return detail::write_to_stream( os, spn ); } #if gsl_HAVE( WCHAR ) template< typename Traits > std::basic_ostream< wchar_t, Traits > & operator<<( std::basic_ostream< wchar_t, Traits > & os, wstring_span const & spn ) { return detail::write_to_stream( os, spn ); } template< typename Traits > std::basic_ostream< wchar_t, Traits > & operator<<( std::basic_ostream< wchar_t, Traits > & os, cwstring_span const & spn ) { return detail::write_to_stream( os, spn ); } #endif // gsl_HAVE( WCHAR ) //#endif // gsl_FEATURE( STRING_SPAN ) // // 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< class T, class SizeType, const T Sentinel > gsl_constexpr14 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; gsl_Expects( *cur == Sentinel ); return span( seq, gsl::narrow_cast< typename span::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< class T > gsl_NODISCARD inline gsl_constexpr14 span ensure_z( T * const & sz, size_t max = (std::numeric_limits::max)() ) { return detail::ensure_sentinel( sz, max ); } template< class T, size_t N > gsl_NODISCARD inline gsl_constexpr14 span ensure_z( T (&sz)[N] ) { return ::gsl::ensure_z( gsl_ADDRESSOF( sz[0] ), N ); } # if gsl_HAVE( TYPE_TRAITS ) template< class Container > gsl_NODISCARD inline gsl_constexpr14 span< typename std::remove_pointer::type > ensure_z( Container & cont ) { return ::gsl::ensure_z( cont.data(), cont.length() ); } # endif //#if gsl_FEATURE( STRING_SPAN ) // // 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; #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_zstring_span<> is deprecated") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_api gsl_constexpr14 basic_zstring_span( span_type s ) : span_( s ) { // expects a zero-terminated span gsl_Expects( s.back() == '\0' ); } #if gsl_HAVE( IS_DEFAULT ) gsl_constexpr basic_zstring_span( basic_zstring_span const & ) = default; gsl_constexpr basic_zstring_span( basic_zstring_span && ) = default; gsl_constexpr14 basic_zstring_span & operator=( basic_zstring_span const & ) = default; gsl_constexpr14 basic_zstring_span & operator=( basic_zstring_span && ) = 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_NODISCARD gsl_api gsl_constexpr bool empty() const gsl_noexcept { return false; } #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_zstring_span<> is deprecated") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_NODISCARD gsl_api gsl_constexpr string_span_type as_string_span() const gsl_noexcept { return string_span_type( span_.data(), span_.size() - 1 ); } #if gsl_DEPRECATE_TO_LEVEL( 7 ) gsl_DEPRECATED_MSG("basic_zstring_span<> is deprecated") #endif // gsl_DEPRECATE_TO_LEVEL( 7 ) /*gsl_api*/ // currently disabled due to an apparent NVCC bug gsl_NODISCARD gsl_constexpr string_span_type ensure_z() const { return ::gsl::ensure_z(span_.data(), span_.size()); } gsl_NODISCARD gsl_api gsl_constexpr czstring_type assume_z() const gsl_noexcept { return span_.data(); } private: span_type span_; }; // // zString types: // typedef basic_zstring_span< char > zstring_span; typedef basic_zstring_span< char const > czstring_span; #if gsl_HAVE( WCHAR ) typedef basic_zstring_span< wchar_t > wzstring_span; typedef basic_zstring_span< wchar_t const > cwzstring_span; #endif //#endif // gsl_FEATURE( STRING_SPAN ) } // namespace gsl #if gsl_HAVE( HASH ) // // std::hash specializations for GSL types // namespace gsl { namespace detail { // // Helper struct for std::hash specializations // template struct conditionally_enabled_hash { }; // disabled as described in [unord.hash] template<> struct conditionally_enabled_hash< false > { gsl_is_delete_access: conditionally_enabled_hash() gsl_is_delete; conditionally_enabled_hash( conditionally_enabled_hash const & ) gsl_is_delete; conditionally_enabled_hash( conditionally_enabled_hash && ) gsl_is_delete; conditionally_enabled_hash & operator=( conditionally_enabled_hash const & ) gsl_is_delete; conditionally_enabled_hash & operator=( conditionally_enabled_hash && ) gsl_is_delete; }; } // namespace detail } // namespace gsl namespace std { template< class T > struct hash< ::gsl::not_null< T > > : public ::gsl::detail::conditionally_enabled_hash>::value> { public: gsl_NODISCARD std::size_t operator()( ::gsl::not_null const & v ) const // hash function is not `noexcept` because `as_nullable()` has preconditions { return hash()( ::gsl::as_nullable( v ) ); } }; template< class T > struct hash< ::gsl::not_null< T* > > { public: gsl_NODISCARD std::size_t operator()( ::gsl::not_null< T* > const & v ) const gsl_noexcept { return hash()( ::gsl::as_nullable( v ) ); } }; template<> struct hash< ::gsl::byte > { public: gsl_NODISCARD std::size_t operator()( ::gsl::byte v ) const gsl_noexcept { #if gsl_CONFIG_DEFAULTS_VERSION >= 1 return std::hash{ }( ::gsl::to_uchar( v ) ); #else // gsl_CONFIG_DEFAULTS_VERSION < 1 // Keep the old hashing algorithm if legacy defaults are used. return ::gsl::to_integer( v ); #endif // gsl_CONFIG_DEFAULTS_VERSION >= 1 } }; } // namespace std #endif // gsl_HAVE( HASH ) #if gsl_FEATURE( GSL_LITE_NAMESPACE ) // gsl_lite namespace: // gsl-lite currently keeps all symbols in the namespace `gsl`. The `gsl_lite` namespace contains all the symbols in the // `gsl` namespace, plus some extensions that are not specified in the Core Guidelines. // // Going forward, we want to support coexistence of gsl-lite with M-GSL, so we want to encourage using the `gsl_lite` // namespace when consuming gsl-lite. Typical use in library code would be: // // #include // instead of // // namespace foo { // namespace gsl = ::gsl_lite; // convenience alias // double mean( gsl::span elements ) // { // gsl_Expects( ! elements.empty() ); // instead of Expects() // ... // } // } // namespace foo // // In a future version, the new header will only define the `gsl_lite` namespace and no // unprefixed `Expects()` and `Ensures()` macros to avoid collision with M-GSL. To ensure backward compatibility, the // old header will keep defining the `gsl` namespace and the `Expects()` and `Ensures()` macros. namespace gsl_lite { namespace std11 = ::gsl::std11; namespace std14 = ::gsl::std14; namespace std17 = ::gsl::std17; namespace std20 = ::gsl::std20; namespace std23 = ::gsl::std23; using namespace std11; //using namespace std14; // contains only make_unique<>(), which is superseded by `gsl::make_unique<>()` using namespace std17; using namespace std20; using namespace std23; using namespace ::gsl::detail::no_adl; # if gsl_HAVE( UNIQUE_PTR ) && gsl_HAVE( SHARED_PTR ) using std::unique_ptr; using std::shared_ptr; # if gsl_HAVE( VARIADIC_TEMPLATE ) using ::gsl::make_unique; using ::gsl::make_shared; # endif # endif using ::gsl::index; using ::gsl::dim; using ::gsl::stride; using ::gsl::diff; # if gsl_HAVE( ALIAS_TEMPLATE ) # if gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 1, 141 ) // VS 2015 and earlier have trouble with `using` for alias templates template< class T # if gsl_HAVE( TYPE_TRAITS ) , typename = typename std::enable_if< std::is_pointer::value >::type # endif > using owner = T; # else using ::gsl::owner; # endif # endif using ::gsl::fail_fast; using ::gsl::finally; # if gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) using ::gsl::on_return; using ::gsl::on_error; # endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) using ::gsl::narrow_cast; using ::gsl::narrowing_error; using ::gsl::narrow; using ::gsl::narrow_failfast; using ::gsl::at; using ::gsl::not_null; using ::gsl::not_null_ic; using ::gsl::make_not_null; using ::gsl::byte; using ::gsl::to_byte; using ::gsl::to_integer; using ::gsl::to_uchar; using ::gsl::to_string; using ::gsl::with_container_t; using ::gsl::with_container; using ::gsl::span; using ::gsl::make_span; using ::gsl::byte_span; using ::gsl::copy; using ::gsl::as_bytes; using ::gsl::as_writable_bytes; # if ! gsl_DEPRECATE_TO_LEVEL( 6 ) using ::gsl::as_writeable_bytes; # endif //# if gsl_FEATURE( STRING_SPAN ) using ::gsl::basic_string_span; using ::gsl::string_span; using ::gsl::cstring_span; using ::gsl::basic_zstring_span; using ::gsl::zstring_span; using ::gsl::czstring_span; //# endif // gsl_FEATURE( STRING_SPAN ) using ::gsl::zstring; using ::gsl::czstring; # if gsl_HAVE( WCHAR ) using ::gsl::wzstring; using ::gsl::cwzstring; //# if gsl_FEATURE( STRING_SPAN ) using ::gsl::wzstring_span; using ::gsl::cwzstring_span; //# endif // gsl_FEATURE( STRING_SPAN ) # endif // gsl_HAVE( WCHAR ) using ::gsl::ensure_z; } // namespace gsl_lite #endif // gsl_FEATURE( GSL_LITE_NAMESPACE ) gsl_RESTORE_MSVC_WARNINGS() #if gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION # pragma clang diagnostic pop #endif // gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION #if gsl_COMPILER_GNUC_VERSION # pragma GCC diagnostic pop #endif // gsl_COMPILER_GNUC_VERSION // #undef internal macros #undef gsl_STATIC_ASSERT_ #undef gsl_ENABLE_IF_ #undef gsl_TRAILING_RETURN_TYPE_ #undef gsl_RETURN_DECLTYPE_ #endif // GSL_GSL_LITE_HPP_INCLUDED // end of file