mirror of https://github.com/gnss-sdr/gnss-sdr
5580 lines
189 KiB
C++
5580 lines
189 KiB
C++
//
|
||
// 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-2021 Moritz Beutel
|
||
// Copyright (c) 2015-2018 Microsoft Corporation. All rights reserved.
|
||
//
|
||
// SPDX-License-Identifier: MIT
|
||
//
|
||
|
||
|
||
#ifndef GSL_GSL_LITE_HPP_INCLUDED
|
||
#define GSL_GSL_LITE_HPP_INCLUDED
|
||
|
||
#include <cstddef> // for size_t, ptrdiff_t, nullptr_t
|
||
#include <cstdlib> // for abort()
|
||
#include <exception> // for exception, terminate(), uncaught_exceptions()
|
||
#include <ios> // for ios_base, streamsize
|
||
#include <iosfwd> // for basic_ostream<>
|
||
#include <limits>
|
||
#include <memory> // for addressof(), unique_ptr<>, shared_ptr<>
|
||
#include <stdexcept> // for logic_error
|
||
#include <string>
|
||
#include <utility> // for move(), forward<>(), swap()
|
||
|
||
#define gsl_lite_MAJOR 0
|
||
#define gsl_lite_MINOR 40
|
||
#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_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 6
|
||
#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_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++20 is speculative):
|
||
// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
|
||
|
||
#ifndef gsl_CPLUSPLUS
|
||
#if defined(_MSVC_LANG) && !defined(__clang__)
|
||
#define gsl_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
|
||
#else
|
||
#define gsl_CPLUSPLUS __cplusplus
|
||
#endif
|
||
#endif
|
||
|
||
// 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 >= 202000L)
|
||
|
||
// C++ language version (represent 98 as 3):
|
||
|
||
#define gsl_CPLUSPLUS_V (gsl_CPLUSPLUS / 100 - (gsl_CPLUSPLUS > 200000 ? 2000 : 1994))
|
||
|
||
// half-open range [lo..hi):
|
||
#define gsl_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi))
|
||
|
||
// Compiler versions:
|
||
|
||
// MSVC++ 6.0 _MSC_VER == 1200 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)
|
||
|
||
#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) (LLVM 12.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:
|
||
|
||
#ifdef __DJGPP__
|
||
#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_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++ 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
|
||
#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
|
||
#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(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(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 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<ENUM>::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<ENUM>::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<ENUM>::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<ENUM>::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<ENUM>::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<ENUM>::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<ENUM>::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<ENUM>::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 <algorithm> // for swap() before C++11
|
||
#endif // ! gsl_CPP11_OR_GREATER
|
||
|
||
#if gsl_HAVE(ARRAY)
|
||
#include <array> // indirectly includes reverse_iterator<>
|
||
#endif
|
||
|
||
#if !gsl_HAVE(ARRAY)
|
||
#include <iterator> // for reverse_iterator<>
|
||
#endif
|
||
|
||
#if !gsl_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR) || !gsl_HAVE(AUTO)
|
||
#include <vector>
|
||
#endif
|
||
|
||
#if gsl_HAVE(INITIALIZER_LIST)
|
||
#include <initializer_list>
|
||
#endif
|
||
|
||
#if defined(gsl_CONFIG_CONTRACT_VIOLATION_ASSERTS) || gsl_DEVICE_CODE
|
||
#include <cassert>
|
||
#endif
|
||
|
||
#if defined(gsl_CONFIG_CONTRACT_VIOLATION_TRAPS) && gsl_COMPILER_MSVC_VERSION >= 110 // __fastfail() supported by VS 2012 and later
|
||
#include <intrin.h>
|
||
#endif
|
||
|
||
#if gsl_HAVE(ENUM_CLASS) && (gsl_COMPILER_ARMCC_VERSION || gsl_COMPILER_NVHPC_VERSION) && !defined(_WIN32)
|
||
#include <endian.h>
|
||
#endif
|
||
|
||
#if gsl_HAVE(TYPE_TRAITS)
|
||
#include <type_traits> // 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 <tr1/type_traits> // 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();
|
||
}
|
||
} // namespace gsl
|
||
#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 <cxxabi.h>
|
||
#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();
|
||
} // namespace __cxxabiv1
|
||
#else
|
||
namespace __cxxabiv1
|
||
{
|
||
struct __cxa_eh_globals;
|
||
extern "C" __cxa_eh_globals *__cxa_get_globals() gsl_noexcept;
|
||
} // namespace __cxxabiv1
|
||
#endif
|
||
#endif
|
||
namespace gsl
|
||
{
|
||
namespace detail
|
||
{
|
||
using ::__cxxabiv1::__cxa_get_globals;
|
||
}
|
||
} // namespace gsl
|
||
#endif
|
||
#endif // ! gsl_HAVE( UNCAUGHT_EXCEPTIONS )
|
||
#endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD )
|
||
|
||
|
||
// MSVC 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
|
||
|
||
// 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 '(<some number>'s result)' that may be invalid
|
||
// - 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 26457)
|
||
|
||
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 <algorithm> 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, (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_const;
|
||
using std::remove_cv;
|
||
using std::remove_volatile;
|
||
|
||
#elif gsl_HAVE(TR1_REMOVE_CONST)
|
||
|
||
using std::tr1::remove_const;
|
||
using std::tr1::remove_cv;
|
||
using std::tr1::remove_volatile;
|
||
|
||
#else
|
||
|
||
template <class T>
|
||
struct remove_const
|
||
{
|
||
typedef T type;
|
||
};
|
||
template <class T>
|
||
struct remove_const<T const>
|
||
{
|
||
typedef T type;
|
||
};
|
||
|
||
template <class T>
|
||
struct remove_volatile
|
||
{
|
||
typedef T type;
|
||
};
|
||
template <class T>
|
||
struct remove_volatile<T volatile>
|
||
{
|
||
typedef T type;
|
||
};
|
||
|
||
template <class T>
|
||
struct remove_cv
|
||
{
|
||
typedef typename remove_volatile<typename remove_const<T>::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<T &>
|
||
{
|
||
typedef T type;
|
||
};
|
||
#if gsl_HAVE(RVALUE_REFERENCE)
|
||
template <class T>
|
||
struct remove_reference<T &&>
|
||
{
|
||
typedef T type;
|
||
};
|
||
#endif
|
||
|
||
#endif // gsl_HAVE( REMOVE_REFERENCE )
|
||
|
||
|
||
#if gsl_HAVE(INTEGRAL_CONSTANT)
|
||
|
||
using std::false_type;
|
||
using std::integral_constant;
|
||
using std::true_type;
|
||
|
||
#elif gsl_HAVE(TR1_INTEGRAL_CONSTANT)
|
||
|
||
using std::tr1::false_type;
|
||
using std::tr1::integral_constant;
|
||
using std::tr1::true_type;
|
||
|
||
#else
|
||
|
||
template <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<T>
|
||
make_unique(Args &&...args)
|
||
{
|
||
#if gsl_HAVE(TYPE_TRAITS)
|
||
static_assert(!std::is_array<T>::value, "make_unique<T[]>() is not part of C++14");
|
||
#endif
|
||
return std::unique_ptr<T>(new T(std::forward<Args>(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_<true, T0, T1, Ts...> : conjunction_<T1::value, T1, Ts...>
|
||
{
|
||
};
|
||
template <bool V0, class T0, class... Ts>
|
||
struct disjunction_
|
||
{
|
||
using type = T0;
|
||
};
|
||
template <class T0, class T1, class... Ts>
|
||
struct disjunction_<false, T0, T1, Ts...> : disjunction_<T1::value, T1, Ts...>
|
||
{
|
||
};
|
||
|
||
#endif
|
||
|
||
template <typename>
|
||
struct dependent_false : std11::integral_constant<bool, false>
|
||
{
|
||
};
|
||
|
||
} // namespace detail
|
||
|
||
// C++17 emulation:
|
||
|
||
namespace std17
|
||
{
|
||
template <bool v>
|
||
struct bool_constant : std11::integral_constant<bool, v>
|
||
{
|
||
};
|
||
|
||
#if gsl_CPP11_120
|
||
|
||
template <class... Ts>
|
||
struct conjunction;
|
||
template <>
|
||
struct conjunction<> : std11::true_type
|
||
{
|
||
};
|
||
template <class T0, class... Ts>
|
||
struct conjunction<T0, Ts...> : detail::conjunction_<T0::value, T0, Ts...>::type
|
||
{
|
||
};
|
||
template <class... Ts>
|
||
struct disjunction;
|
||
template <>
|
||
struct disjunction<> : std11::false_type
|
||
{
|
||
};
|
||
template <class T0, class... Ts>
|
||
struct disjunction<T0, Ts...> : detail::disjunction_<T0::value, T0, Ts...>::type
|
||
{
|
||
};
|
||
template <class T>
|
||
struct negation : std11::integral_constant<bool, !T::value>
|
||
{
|
||
};
|
||
|
||
#if gsl_CPP14_OR_GREATER
|
||
|
||
template <class... Ts>
|
||
constexpr bool conjunction_v = conjunction<Ts...>::value;
|
||
template <class... Ts>
|
||
constexpr bool disjunction_v = disjunction<Ts...>::value;
|
||
template <class T>
|
||
constexpr bool negation_v = negation<T>::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<E> 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<T>(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 <endian.h> 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<T>::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<std::ptrdiff_t, typename std::make_signed<decltype(c.size())>::type>::type
|
||
{
|
||
using R = typename std::common_type<std::ptrdiff_t, typename std::make_signed<decltype(c.size())>::type>::type;
|
||
return static_cast<R>(c.size());
|
||
}
|
||
|
||
template <class T, std::size_t N>
|
||
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
|
||
|
||
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<T>> : std::true_type
|
||
{
|
||
};
|
||
|
||
template <class Q>
|
||
struct is_span : is_span_oracle<typename std::remove_cv<Q>::type>
|
||
{
|
||
};
|
||
|
||
template <class Q>
|
||
struct is_std_array_oracle : std::false_type
|
||
{
|
||
};
|
||
|
||
#if gsl_HAVE(ARRAY)
|
||
|
||
template <class T, std::size_t Extent>
|
||
struct is_std_array_oracle<std::array<T, Extent>> : std::true_type
|
||
{
|
||
};
|
||
|
||
#endif
|
||
|
||
template <class Q>
|
||
struct is_std_array : is_std_array_oracle<typename std::remove_cv<Q>::type>
|
||
{
|
||
};
|
||
|
||
template <class Q>
|
||
struct is_array : std::false_type
|
||
{
|
||
};
|
||
|
||
template <class T>
|
||
struct is_array<T[]> : std::true_type
|
||
{
|
||
};
|
||
|
||
template <class T, std::size_t N>
|
||
struct is_array<T[N]> : std::true_type
|
||
{
|
||
};
|
||
|
||
#if 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<C>())),
|
||
decltype(std17::data(std::declval<C>()))>> : std::true_type
|
||
{
|
||
};
|
||
|
||
template <class, class, class = void>
|
||
struct is_compatible_element : std::false_type
|
||
{
|
||
};
|
||
|
||
template <class C, class E>
|
||
struct is_compatible_element<
|
||
C, E, std17::void_t<decltype(std17::data(std::declval<C>())), typename std::remove_pointer<decltype(std17::data(std::declval<C &>()))>::type (*)[]>> : std::is_convertible<typename std::remove_pointer<decltype(std17::data(std::declval<C &>()))>::type (*)[], E (*)[]>
|
||
{
|
||
};
|
||
|
||
template <class C>
|
||
struct is_container : std17::bool_constant<
|
||
!is_span<C>::value && !is_array<C>::value && !is_std_array<C>::value && has_size_and_data<C>::value>
|
||
{
|
||
};
|
||
|
||
template <class C, class E>
|
||
struct is_compatible_container : std17::bool_constant<
|
||
is_container<C>::value && is_compatible_element<C, E>::value>
|
||
{
|
||
};
|
||
|
||
#else // ^^^ 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<decltype(std17::data(std::declval<C &>()))>::type (*)[], E (*)[]>::value)
|
||
// && has_size_and_data< C >::value
|
||
,
|
||
enabler>::type,
|
||
class = decltype(std17::size(std::declval<C>())), class = decltype(std17::data(std::declval<C>()))>
|
||
#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<C, E>);
|
||
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::shared_ptr;
|
||
using std::unique_ptr;
|
||
#endif
|
||
|
||
#if gsl_HAVE(ALIAS_TEMPLATE)
|
||
template <class T
|
||
#if gsl_HAVE(TYPE_TRAITS)
|
||
,
|
||
typename = typename std::enable_if<std::is_pointer<T>::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<t>
|
||
#else
|
||
#define Owner(t) ::gsl::owner<t>::type
|
||
#endif
|
||
#endif
|
||
|
||
//
|
||
// GSL.assert: assertions
|
||
//
|
||
|
||
#if gsl_HAVE(TYPE_TRAITS)
|
||
#define gsl_ELIDE_(x) static_assert(::std::is_constructible<bool, decltype(x)>::value, "argument of contract check must be convertible to bool")
|
||
#else
|
||
#define gsl_ELIDE_(x)
|
||
#endif
|
||
#define gsl_NO_OP_() (static_cast<void>(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) ((x) ? static_cast<void>(0) : __builtin_unreachable())
|
||
#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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<unsigned char>(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<unsigned char>(*reinterpret_cast<unsigned const *>(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<unsigned char>((*reinterpret_cast<unsigned const *>(reinterpret_cast<unsigned char const *>(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)),
|
||
invoke_(true)
|
||
{
|
||
}
|
||
|
||
final_action(final_action &&other) gsl_noexcept
|
||
: action_(std::move(other.action_)),
|
||
invoke_(other.invoke_)
|
||
{
|
||
other.invoke_ = false;
|
||
}
|
||
|
||
gsl_SUPPRESS_MSGSL_WARNING(f .6) virtual ~final_action() gsl_noexcept
|
||
{
|
||
if (invoke_)
|
||
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;
|
||
|
||
protected:
|
||
void dismiss() gsl_noexcept
|
||
{
|
||
invoke_ = false;
|
||
}
|
||
|
||
private:
|
||
F action_;
|
||
bool invoke_;
|
||
};
|
||
|
||
template <class F>
|
||
gsl_NODISCARD inline final_action<F>
|
||
finally(F const &action) gsl_noexcept
|
||
{
|
||
return final_action<F>(action);
|
||
}
|
||
|
||
template <class F>
|
||
gsl_NODISCARD inline final_action<F>
|
||
finally(F && action) gsl_noexcept
|
||
{
|
||
return final_action<F>(std::forward<F>(action));
|
||
}
|
||
|
||
#if gsl_FEATURE(EXPERIMENTAL_RETURN_GUARD)
|
||
|
||
template <class F>
|
||
class final_action_return : public final_action<F>
|
||
{
|
||
public:
|
||
explicit final_action_return(F &&action) gsl_noexcept
|
||
: final_action<F>(std::move(action)),
|
||
exception_count(std11::uncaught_exceptions())
|
||
{
|
||
}
|
||
|
||
final_action_return(final_action_return &&other) gsl_noexcept
|
||
: final_action<F>(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>
|
||
gsl_NODISCARD inline final_action_return<F>
|
||
on_return(F const &action) gsl_noexcept
|
||
{
|
||
return final_action_return<F>(action);
|
||
}
|
||
|
||
template <class F>
|
||
gsl_NODISCARD inline final_action_return<F>
|
||
on_return(F && action) gsl_noexcept
|
||
{
|
||
return final_action_return<F>(std::forward<F>(action));
|
||
}
|
||
|
||
template <class F>
|
||
class final_action_error : public final_action<F>
|
||
{
|
||
public:
|
||
explicit final_action_error(F &&action) gsl_noexcept
|
||
: final_action<F>(std::move(action)),
|
||
exception_count(std11::uncaught_exceptions())
|
||
{
|
||
}
|
||
|
||
final_action_error(final_action_error &&other) gsl_noexcept
|
||
: final_action<F>(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;
|
||
};
|
||
|
||
template <class F>
|
||
gsl_NODISCARD inline final_action_error<F>
|
||
on_error(F const &action) gsl_noexcept
|
||
{
|
||
return final_action_error<F>(action);
|
||
}
|
||
|
||
template <class F>
|
||
gsl_NODISCARD inline final_action_error<F>
|
||
on_error(F && action) gsl_noexcept
|
||
{
|
||
return final_action_error<F>(std::forward<F>(action));
|
||
}
|
||
|
||
#endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD )
|
||
|
||
gsl_RESTORE_MSVC_WARNINGS()
|
||
|
||
#else // ! gsl_STDLIB_CPP11_110
|
||
|
||
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>
|
||
inline final_action finally(F const &f)
|
||
{
|
||
return final_action((f));
|
||
}
|
||
|
||
#if gsl_FEATURE(EXPERIMENTAL_RETURN_GUARD)
|
||
|
||
class final_action_return : public final_action
|
||
{
|
||
public:
|
||
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>
|
||
inline final_action_return on_return(F const &action)
|
||
{
|
||
return final_action_return(action);
|
||
}
|
||
|
||
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>
|
||
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<T>(std::forward<U>(u));
|
||
}
|
||
|
||
#else // ! gsl_STDLIB_CPP11_120
|
||
|
||
template <class T, class U>
|
||
gsl_api inline T
|
||
narrow_cast(U u) gsl_noexcept
|
||
{
|
||
return static_cast<T>(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<bool, std::is_signed<T>::value == std::is_signed<U>::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<T>()) == detail::is_negative(u, std::is_signed<U>());
|
||
}
|
||
#endif // gsl_COMPILER_NVCC_VERSION || gsl_COMPILER_NVHPC_VERSION
|
||
|
||
} // namespace detail
|
||
|
||
#endif
|
||
|
||
template <class T, class U>
|
||
gsl_NODISCARD
|
||
#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<T>(u);
|
||
|
||
if (static_cast<U>(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<T, U>()))
|
||
#else
|
||
gsl_SUPPRESS_MSVC_WARNING(4127, "conditional expression is constant") if (!detail::is_same_signedness<T, U>::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 inline T
|
||
narrow_failfast(U u)
|
||
{
|
||
T t = static_cast<T>(u);
|
||
|
||
gsl_Expects(static_cast<U>(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<T, U>()));
|
||
#else
|
||
gsl_SUPPRESS_MSVC_WARNING(4127, "conditional expression is constant")
|
||
gsl_Expects((::gsl::detail::is_same_signedness<T, U>::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<T> 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<T> 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 will handle raw pointers)
|
||
typedef typename std::remove_reference<decltype(*std::declval<T>())>::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;
|
||
};
|
||
|
||
template <class T>
|
||
struct element_type_helper<T *>
|
||
{
|
||
typedef T type;
|
||
};
|
||
#endif // gsl_STDLIB_CPP11_OR_GREATER
|
||
|
||
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<T>> : std11::true_type
|
||
{
|
||
};
|
||
template <>
|
||
struct is_not_null_or_bool_oracle<bool> : std11::true_type
|
||
{
|
||
};
|
||
|
||
|
||
template <class T, bool IsCopyable = true>
|
||
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
|
||
: ptr_(std::move(other.ptr_))
|
||
{
|
||
}
|
||
gsl_api gsl_constexpr14 not_null_data &operator=(not_null_data &&other) gsl_noexcept
|
||
{
|
||
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;
|
||
};
|
||
#if gsl_CONFIG_DEFAULTS_VERSION >= 1
|
||
#endif // gsl_CONFIG_DEFAULTS_VERSION >= 1
|
||
#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
|
||
: ptr_(std::move(other.ptr_))
|
||
{
|
||
}
|
||
gsl_api gsl_constexpr14 not_null_data &operator=(not_null_data &&other) gsl_noexcept
|
||
{
|
||
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_Expects(ptr_ != gsl_nullptr);
|
||
}
|
||
gsl_api gsl_constexpr14 not_null_data &operator=(not_null_data const &other)
|
||
{
|
||
gsl_Expects(other.ptr_ != gsl_nullptr);
|
||
ptr_ = other.ptr_;
|
||
return *this;
|
||
}
|
||
};
|
||
#if gsl_CONFIG_DEFAULTS_VERSION >= 1
|
||
template <class T>
|
||
struct not_null_data<T *, true>
|
||
{
|
||
T *ptr_;
|
||
|
||
gsl_api gsl_constexpr14 not_null_data(T *_ptr) gsl_noexcept
|
||
: ptr_(_ptr)
|
||
{
|
||
}
|
||
};
|
||
#endif // gsl_CONFIG_DEFAULTS_VERSION >= 1
|
||
template <class T>
|
||
struct is_copyable
|
||
#if gsl_HAVE(TYPE_TRAITS)
|
||
: std11::integral_constant<bool, std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::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;
|
||
|
||
} // namespace detail
|
||
|
||
template <class T>
|
||
class not_null
|
||
{
|
||
private:
|
||
detail::not_null_data<T, detail::is_copyable<T>::value> data_;
|
||
|
||
// need to access `not_null<U>::data_`
|
||
template <class U>
|
||
friend class not_null;
|
||
|
||
template <class U>
|
||
friend struct detail::not_null_accessor;
|
||
|
||
public:
|
||
typedef typename detail::element_type_helper<T>::type element_type;
|
||
|
||
#if gsl_HAVE(TYPE_TRAITS)
|
||
static_assert(std::is_assignable<typename std::remove_const<typename std::remove_reference<T>::type>::type &, std::nullptr_t>::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<not_null<unique_ptr<X>>, unique_ptr<X>>` 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<T, U>::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<not_null<unique_ptr<X>>, unique_ptr<X>>` 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<T, U>::value && !std::is_convertible<U, T>::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<U, T>::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 )
|
||
|
||
public:
|
||
#if gsl_HAVE(MOVE_FORWARD)
|
||
// In Clang 3.x, `is_constructible<not_null<unique_ptr<X>>, unique_ptr<X>>` 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<T, U>::value && !std::is_convertible<U, T>::value), int>::type = 0>
|
||
gsl_api gsl_constexpr14 explicit not_null(not_null<U> other)
|
||
: data_(T(std::move(other.data_.ptr_)))
|
||
{
|
||
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<U, T>::value), int>::type = 0>
|
||
gsl_api gsl_constexpr14 not_null(not_null<U> other)
|
||
: data_(T(std::move(other.data_.ptr_)))
|
||
{
|
||
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(not_null<U> other)
|
||
: data_(T(std::move(other.data_.ptr_)))
|
||
{
|
||
gsl_Expects(data_.ptr_ != gsl_nullptr);
|
||
}
|
||
template <class U>
|
||
gsl_api gsl_constexpr14 not_null<T> &operator=(not_null<U> other)
|
||
{
|
||
gsl_Expects(other.data_.ptr_ != gsl_nullptr);
|
||
data_.ptr_ = std::move(other.data_.ptr_);
|
||
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<U> const &other)
|
||
: data_(T(other.data_.ptr_))
|
||
{
|
||
gsl_Expects(data_.ptr_ != gsl_nullptr);
|
||
}
|
||
template <class U>
|
||
gsl_api gsl_constexpr14 not_null<T> &operator=(not_null<U> const &other)
|
||
{
|
||
gsl_Expects(other.data_.ptr_ != gsl_nullptr);
|
||
data_.ptr_ = other.data_.ptr_;
|
||
return *this;
|
||
}
|
||
#endif // gsl_HAVE( MOVE_FORWARD )
|
||
|
||
#if gsl_CONFIG(TRANSPARENT_NOT_NULL)
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 element_type *
|
||
get() const
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return data_.ptr_.get();
|
||
}
|
||
#else
|
||
#if gsl_CONFIG(NOT_NULL_GET_BY_CONST_REF)
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 T const &
|
||
get() const
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return data_.ptr_;
|
||
}
|
||
#else
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 T
|
||
get() const
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return data_.ptr_;
|
||
}
|
||
#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<std::unique_ptr<T>> p( ... );
|
||
// std::unique_ptr<U> 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<std::shared_ptr<T>> sp( ... );
|
||
// std::shared_ptr<U> const & rs = sp; // unnecessary copy
|
||
// std::unique_ptr<U> const & ru = p; // error: cannot copy `unique_ptr<T>`
|
||
//
|
||
// However, these situations are rather unusual, and the following, more frequent situations
|
||
// remain unimpaired:
|
||
//
|
||
// std::shared_ptr<U> vs = sp; // no extra copy
|
||
// std::unique_ptr<U> 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<U, T const &>::value && !std::is_convertible<T, U>::value && !detail::is_not_null_or_bool_oracle<U>::value), int>::type = 0>
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 explicit
|
||
operator U() const
|
||
#if gsl_HAVE(FUNCTION_REF_QUALIFIER)
|
||
&
|
||
#endif
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return U(data_.ptr_);
|
||
}
|
||
#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<U, T>::value && !std::is_convertible<T, U>::value && !detail::is_not_null_or_bool_oracle<U>::value), int>::type = 0>
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 explicit
|
||
operator U() &&
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return U(std::move(data_.ptr_));
|
||
}
|
||
#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<U, T const &>::value && std::is_convertible<T, U>::value && !detail::is_not_null_or_bool_oracle<U>::value), int>::type = 0>
|
||
gsl_NODISCARD gsl_api gsl_constexpr14
|
||
operator U() const
|
||
#if gsl_HAVE(FUNCTION_REF_QUALIFIER)
|
||
&
|
||
#endif
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return data_.ptr_;
|
||
}
|
||
#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<T, U>::value && !detail::is_not_null_or_bool_oracle<U>::value), int>::type = 0>
|
||
gsl_NODISCARD gsl_api gsl_constexpr14
|
||
operator U() &&
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return std::move(data_.ptr_);
|
||
}
|
||
#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
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return U(data_.ptr_);
|
||
}
|
||
#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
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return data_.ptr_;
|
||
}
|
||
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 element_type &
|
||
operator*() const
|
||
{
|
||
gsl_Assert(data_.ptr_ != gsl_nullptr);
|
||
return *data_.ptr_;
|
||
}
|
||
|
||
#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 precondition check
|
||
: data_(std::move(other.data_))
|
||
{
|
||
gsl_Expects(data_.ptr_ != gsl_nullptr);
|
||
}
|
||
gsl_api gsl_constexpr14 not_null &operator=(not_null &&other)
|
||
gsl_noexcept_not_testing // we want to be nothrow-movable despite the precondition check
|
||
{
|
||
gsl_Expects(other.data_.ptr_ != gsl_nullptr || &other == this);
|
||
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
|
||
{
|
||
gsl_Expects(lhs.data_.ptr_ != gsl_nullptr && rhs.data_.ptr_ != gsl_nullptr);
|
||
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_CONFIG_DEFAULTS_VERSION >= 1
|
||
template <class T>
|
||
class not_null<T *>
|
||
{
|
||
private:
|
||
detail::not_null_data<T *, true> data_;
|
||
|
||
// need to access `not_null<U>::data_`
|
||
template <class U>
|
||
friend class not_null;
|
||
|
||
template <class U>
|
||
friend struct detail::not_null_accessor;
|
||
|
||
public:
|
||
typedef T element_type;
|
||
|
||
gsl_api gsl_constexpr14
|
||
#if gsl_CONFIG(NOT_NULL_EXPLICIT_CTOR)
|
||
explicit
|
||
#endif // gsl_CONFIG( NOT_NULL_EXPLICIT_CTOR )
|
||
not_null(T *other)
|
||
: data_(other)
|
||
{
|
||
gsl_Expects(data_.ptr_ != gsl_nullptr);
|
||
}
|
||
|
||
#if gsl_HAVE(MOVE_FORWARD)
|
||
// In Clang 3.x, `is_constructible<not_null<unique_ptr<X>>, unique_ptr<X>>` 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<T *, U>::value && !std::is_convertible<U, T *>::value), int>::type = 0>
|
||
gsl_api gsl_constexpr14 explicit not_null(not_null<U> other)
|
||
: data_(static_cast<T *>(std::move(other.data_.ptr_)))
|
||
{
|
||
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<U, T *>::value), int>::type = 0>
|
||
gsl_api gsl_constexpr14 not_null(not_null<U> other)
|
||
: data_(std::move(other.data_.ptr_))
|
||
{
|
||
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(not_null<U> other)
|
||
: data_(std::move(other.data_.ptr_))
|
||
{
|
||
gsl_Expects(data_.ptr_ != gsl_nullptr);
|
||
}
|
||
template <class U>
|
||
gsl_api gsl_constexpr14 not_null<T *> &operator=(not_null<U> other)
|
||
{
|
||
gsl_Expects(other.data_.ptr_ != gsl_nullptr);
|
||
data_.ptr_ = std::move(other.data_.ptr_);
|
||
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<U> const &other)
|
||
: data_(other.data_.ptr_)
|
||
{
|
||
gsl_Expects(data_.ptr_ != gsl_nullptr);
|
||
}
|
||
template <class U>
|
||
gsl_api gsl_constexpr14 not_null<T *> &operator=(not_null<U> const &other)
|
||
{
|
||
gsl_Expects(other.data_.ptr_ != gsl_nullptr);
|
||
data_.ptr_ = other.data_.ptr_;
|
||
return *this;
|
||
}
|
||
#endif // gsl_HAVE( MOVE_FORWARD )
|
||
|
||
#if !gsl_CONFIG(TRANSPARENT_NOT_NULL)
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 T *
|
||
get() const
|
||
{
|
||
return data_.ptr_;
|
||
}
|
||
#endif
|
||
|
||
#if 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<U, T *>::value && !std::is_convertible<T *, U>::value && !detail::is_not_null_or_bool_oracle<U>::value), int>::type = 0>
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 explicit
|
||
operator U() const
|
||
{
|
||
return U(data_.ptr_);
|
||
}
|
||
|
||
// 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<U, T *>::value && std::is_convertible<T *, U>::value && !detail::is_not_null_or_bool_oracle<U>::value), int>::type = 0>
|
||
gsl_NODISCARD gsl_api gsl_constexpr14
|
||
operator U() const
|
||
{
|
||
return data_.ptr_;
|
||
}
|
||
#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 data_.ptr_;
|
||
}
|
||
#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 *
|
||
operator->() const
|
||
{
|
||
return data_.ptr_;
|
||
}
|
||
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 element_type &
|
||
operator*() const
|
||
{
|
||
return *data_.ptr_;
|
||
}
|
||
|
||
#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
|
||
{
|
||
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;
|
||
};
|
||
#endif // gsl_CONFIG_DEFAULTS_VERSION >= 1
|
||
#if gsl_HAVE(DEDUCTION_GUIDES)
|
||
template <class U>
|
||
not_null(U) -> not_null<U>;
|
||
template <class U>
|
||
not_null(not_null<U>) -> not_null<U>;
|
||
#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<U>
|
||
make_not_null(U u)
|
||
{
|
||
return not_null<U>(std::move(u));
|
||
}
|
||
template <class U>
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 not_null<U>
|
||
make_not_null(not_null<U> u)
|
||
{
|
||
return std::move(u);
|
||
}
|
||
#else // a.k.a. ! gsl_HAVE( MOVE_FORWARD )
|
||
template <class U>
|
||
gsl_NODISCARD gsl_api not_null<U>
|
||
make_not_null(U const &u)
|
||
{
|
||
return not_null<U>(u);
|
||
}
|
||
template <class U>
|
||
gsl_NODISCARD gsl_api not_null<U>
|
||
make_not_null(not_null<U> 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<T>>
|
||
{
|
||
};
|
||
|
||
template <class T>
|
||
struct not_null_accessor
|
||
{
|
||
#if gsl_HAVE(MOVE_FORWARD)
|
||
static gsl_api T get(not_null<T> &&p) gsl_noexcept
|
||
{
|
||
return std::move(p.data_.ptr_);
|
||
}
|
||
#endif
|
||
static gsl_api T const &get(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<T>::value)
|
||
-> typename detail::as_nullable_helper<typename std20::remove_cvref<T>::type>::type
|
||
{
|
||
return std::move(p);
|
||
}
|
||
template <class T>
|
||
gsl_NODISCARD gsl_api gsl_constexpr14 T as_nullable(not_null<T> &&p)
|
||
{
|
||
T result = detail::not_null_accessor<T>::get(std::move(p));
|
||
gsl_Expects(result != gsl_nullptr);
|
||
return result;
|
||
}
|
||
#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<T> const &p)
|
||
{
|
||
T const &result = detail::not_null_accessor<T>::get(p);
|
||
gsl_Expects(result != gsl_nullptr);
|
||
return result;
|
||
}
|
||
template <class T>
|
||
gsl_NODISCARD gsl_api gsl_constexpr T *
|
||
as_nullable(not_null<T *> p) gsl_noexcept
|
||
{
|
||
return detail::not_null_accessor<T *>::get(p);
|
||
}
|
||
|
||
template <class T>
|
||
gsl_NODISCARD gsl_api gsl_constexpr bool
|
||
is_valid(not_null<T> const &p)
|
||
{
|
||
return detail::not_null_accessor<T>::get(p) != gsl_nullptr;
|
||
}
|
||
template <class T>
|
||
gsl_NODISCARD gsl_api gsl_constexpr bool
|
||
is_valid(not_null<T *> const &)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
} // 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<T>
|
||
{
|
||
public:
|
||
template <class U
|
||
gsl_ENABLE_IF_((std::is_constructible<T, U>::value))>
|
||
gsl_api gsl_constexpr14
|
||
#if gsl_HAVE(MOVE_FORWARD)
|
||
not_null_ic(U &&u)
|
||
: not_null<T>(std::forward<U>(u))
|
||
#else // ! gsl_HAVE( MOVE_FORWARD )
|
||
not_null_ic(U const &u)
|
||
: not_null<T>(u)
|
||
#endif // gsl_HAVE( MOVE_FORWARD )
|
||
{
|
||
}
|
||
};
|
||
|
||
// more not_null unwanted operators
|
||
|
||
template <class T, class U>
|
||
std::ptrdiff_t operator-(not_null<T> const &, not_null<U> const &) gsl_is_delete;
|
||
|
||
template <class T>
|
||
not_null<T> operator-(not_null<T> const &, std::ptrdiff_t) gsl_is_delete;
|
||
|
||
template <class T>
|
||
not_null<T> operator+(not_null<T> const &, std::ptrdiff_t) gsl_is_delete;
|
||
|
||
template <class T>
|
||
not_null<T> operator+(std::ptrdiff_t, not_null<T> const &) gsl_is_delete;
|
||
|
||
// not_null comparisons
|
||
|
||
#if gsl_HAVE(NULLPTR) && gsl_HAVE(IS_DELETE)
|
||
template <class T>
|
||
gsl_constexpr bool
|
||
operator==(not_null<T> const &, std::nullptr_t) = delete;
|
||
template <class T>
|
||
gsl_constexpr bool
|
||
operator==(std::nullptr_t, not_null<T> const &) = delete;
|
||
template <class T>
|
||
gsl_constexpr bool
|
||
operator!=(not_null<T> const &, std::nullptr_t) = delete;
|
||
template <class T>
|
||
gsl_constexpr bool
|
||
operator!=(std::nullptr_t, not_null<T> 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<T> const &l, not_null<U> 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<T> 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<U> 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<T> const &l, not_null<U> 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<T> 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<U> 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<T> const &l, not_null<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!=(not_null<T> 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<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<=(not_null<T> const &l, not_null<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<=(not_null<T> 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<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>(not_null<T> const &l, not_null<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>(not_null<T> 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<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>=(not_null<T> const &l, not_null<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>=(not_null<T> 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<U> 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<T> 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<std::unique_ptr<T>>
|
||
make_unique(Args && ...args)
|
||
{
|
||
#if gsl_HAVE(TYPE_TRAITS)
|
||
static_assert(!std::is_array<T>::value,
|
||
"gsl::make_unique<T>() returns `gsl::not_null<std::unique_ptr<T>>`, which is not "
|
||
"defined for array types because the Core Guidelines advise against pointer arithmetic, cf. \"Bounds safety profile\".");
|
||
#endif
|
||
return not_null<std::unique_ptr<T>>(new T(std::forward<Args>(args)...));
|
||
}
|
||
#endif // gsl_HAVE( UNIQUE_PTR )
|
||
#if gsl_HAVE(SHARED_PTR)
|
||
template <class T, class... Args>
|
||
gsl_NODISCARD not_null<std::shared_ptr<T>>
|
||
make_shared(Args && ...args)
|
||
{
|
||
#if gsl_HAVE(TYPE_TRAITS)
|
||
static_assert(!std::is_array<T>::value,
|
||
"gsl::make_shared<T>() returns `gsl::not_null<std::shared_ptr<T>>`, which is not "
|
||
"defined for array types because the Core Guidelines advise against pointer arithmetic, cf. \"Bounds safety profile\".");
|
||
#endif
|
||
return not_null<std::shared_ptr<T>>(std::make_shared<T>(std::forward<Args>(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<byte>(v);
|
||
#elif gsl_HAVE(CONSTEXPR_11)
|
||
return {static_cast<typename byte::type>(v)};
|
||
#else
|
||
byte b = {static_cast<typename byte::type>(v)};
|
||
return b;
|
||
#endif
|
||
}
|
||
|
||
template <class IntegerType gsl_ENABLE_IF_((std::is_integral<IntegerType>::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<typename std::underlying_type<byte>::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<unsigned char>(b);
|
||
}
|
||
|
||
gsl_NODISCARD gsl_api inline gsl_constexpr unsigned char
|
||
to_uchar(int i) gsl_noexcept
|
||
{
|
||
return static_cast<unsigned char>(i);
|
||
}
|
||
|
||
template <class IntegerType gsl_ENABLE_IF_((std::is_integral<IntegerType>::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<IntegerType>::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<IntegerType>::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<IntegerType>::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_type (*)[], element_type (*)[]>::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_type (*)[], element_type (*)[]>::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_type (*)[], element_type (*)[]>::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<element_type> 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<element_type>::type>
|
||
#else
|
||
template <class ArrayElementType>
|
||
#endif
|
||
gsl_DEPRECATED
|
||
gsl_constexpr
|
||
span(unique_ptr<ArrayElementType> const &ptr, index_type count)
|
||
: first_(ptr.get()), last_(ptr.get() + count)
|
||
{
|
||
}
|
||
|
||
gsl_DEPRECATED
|
||
gsl_constexpr
|
||
span(unique_ptr<element_type> 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<U (*)[], element_type (*)[]>::value))>
|
||
gsl_api gsl_constexpr span(span<U> 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<index_type>(last_ - first_);
|
||
}
|
||
|
||
gsl_NODISCARD gsl_api gsl_constexpr std::ptrdiff_t
|
||
ssize() const gsl_noexcept
|
||
{
|
||
return narrow_cast<std::ptrdiff_t>(last_ - first_);
|
||
}
|
||
|
||
gsl_NODISCARD gsl_api gsl_constexpr index_type
|
||
size_bytes() const gsl_noexcept
|
||
{
|
||
return size() * narrow_cast<index_type>(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<const byte *>(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<byte *>(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<U *>(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<T /*, N*/>;
|
||
|
||
template <class T, size_t N>
|
||
span(std::array<T, N> &) -> span<T /*, N*/>;
|
||
|
||
template <class T, size_t N>
|
||
span(std::array<T, N> const &) -> span<const T /*, N*/>;
|
||
|
||
template <class Container>
|
||
span(Container &) -> span<typename Container::value_type>;
|
||
|
||
template <class Container>
|
||
span(Container const &) -> span<const typename Container::value_type>;
|
||
|
||
#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<T> const &l, span<U> 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<T> const &l, span<U> 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<T> const &l, span<T> 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<T> const &l, span<T> 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<T> const &l, span<U> const &r)
|
||
{
|
||
return !(l == r);
|
||
}
|
||
|
||
template <class T, class U>
|
||
gsl_NODISCARD inline gsl_constexpr bool operator<=(span<T> const &l, span<U> const &r)
|
||
{
|
||
return !(r < l);
|
||
}
|
||
|
||
template <class T, class U>
|
||
gsl_NODISCARD inline gsl_constexpr bool operator>(span<T> const &l, span<U> const &r)
|
||
{
|
||
return (r < l);
|
||
}
|
||
|
||
template <class T, class U>
|
||
gsl_NODISCARD inline gsl_constexpr bool operator>=(span<T> const &l, span<U> 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<T> const &spn)
|
||
{
|
||
return static_cast<std::size_t>(spn.size());
|
||
}
|
||
|
||
template <class T>
|
||
gsl_NODISCARD gsl_api inline gsl_constexpr std::ptrdiff_t
|
||
ssize(span<T> 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;
|
||
}
|
||
} // namespace detail
|
||
|
||
template <class T, class U>
|
||
gsl_api gsl_constexpr14 inline void copy(span<T> src, span<U> dest)
|
||
{
|
||
#if gsl_CPP14_OR_GREATER // gsl_HAVE( TYPE_TRAITS ) (circumvent Travis clang 3.4)
|
||
static_assert(std::is_assignable<U &, T const &>::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<T> spn) gsl_noexcept
|
||
{
|
||
return span<const byte>(reinterpret_cast<const byte *>(spn.data()), spn.size_bytes()); // NOLINT
|
||
}
|
||
|
||
template <class T>
|
||
gsl_NODISCARD gsl_api inline span<byte>
|
||
as_writable_bytes(span<T> spn) gsl_noexcept
|
||
{
|
||
return span<byte>(reinterpret_cast<byte *>(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<T> spn) gsl_noexcept
|
||
{
|
||
return span<byte>(reinterpret_cast<byte *>(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<T>
|
||
make_span(T * ptr, typename span<T>::index_type count)
|
||
{
|
||
return span<T>(ptr, count);
|
||
}
|
||
|
||
template <class T>
|
||
gsl_NODISCARD gsl_api inline gsl_constexpr span<T>
|
||
make_span(T * first, T * last)
|
||
{
|
||
return span<T>(first, last);
|
||
}
|
||
|
||
template <class T, size_t N>
|
||
gsl_NODISCARD inline gsl_constexpr span<T>
|
||
make_span(T(&arr)[N])
|
||
{
|
||
return span<T>(gsl_ADDRESSOF(arr[0]), N);
|
||
}
|
||
|
||
#if gsl_HAVE(ARRAY)
|
||
|
||
template <class T, size_t N>
|
||
gsl_NODISCARD inline gsl_constexpr span<T>
|
||
make_span(std::array<T, N> & arr)
|
||
{
|
||
return span<T>(arr);
|
||
}
|
||
|
||
template <class T, size_t N>
|
||
gsl_NODISCARD inline gsl_constexpr span<const T>
|
||
make_span(std::array<T, N> const &arr)
|
||
{
|
||
return span<const T>(arr);
|
||
}
|
||
#endif
|
||
|
||
#if gsl_HAVE(CONSTRAINED_SPAN_CONTAINER_CTOR) && gsl_HAVE(AUTO)
|
||
|
||
template <class Container, class EP = decltype(std17::data(std::declval<Container &>()))>
|
||
gsl_NODISCARD inline gsl_constexpr auto
|
||
make_span(Container & cont)
|
||
->span<typename std::remove_pointer<EP>::type>
|
||
{
|
||
return span<typename std::remove_pointer<EP>::type>(cont);
|
||
}
|
||
|
||
template <class Container, class EP = decltype(std17::data(std::declval<Container &>()))>
|
||
gsl_NODISCARD inline gsl_constexpr auto
|
||
make_span(Container const &cont)
|
||
->span<const typename std::remove_pointer<EP>::type>
|
||
{
|
||
return span<const typename std::remove_pointer<EP>::type>(cont);
|
||
}
|
||
|
||
#else
|
||
|
||
template <class T>
|
||
inline span<T>
|
||
make_span(std::vector<T> & cont)
|
||
{
|
||
return span<T>(with_container, cont);
|
||
}
|
||
|
||
template <class T>
|
||
inline span<const T>
|
||
make_span(std::vector<T> const &cont)
|
||
{
|
||
return span<const T>(with_container, cont);
|
||
}
|
||
#endif
|
||
|
||
#if gsl_FEATURE_TO_STD(WITH_CONTAINER)
|
||
|
||
template <class Container>
|
||
gsl_NODISCARD inline gsl_constexpr span<typename Container::value_type>
|
||
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<const typename Container::value_type>
|
||
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<typename Ptr::element_type>
|
||
make_span(Ptr & ptr)
|
||
{
|
||
return span<typename Ptr::element_type>(ptr);
|
||
}
|
||
#endif // !gsl_DEPRECATE_TO_LEVEL( 4 )
|
||
|
||
template <class Ptr>
|
||
gsl_DEPRECATED inline span<typename Ptr::element_type>
|
||
make_span(Ptr & ptr, typename span<typename Ptr::element_type>::index_type count)
|
||
{
|
||
return span<typename Ptr::element_type>(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>
|
||
byte_span(T & t) gsl_noexcept
|
||
{
|
||
return span<byte>(reinterpret_cast<byte *>(&t), sizeof(T));
|
||
}
|
||
|
||
template <class T>
|
||
gsl_NODISCARD gsl_api inline gsl_constexpr span<const byte>
|
||
byte_span(T const &t) gsl_noexcept
|
||
{
|
||
return span<const byte>(reinterpret_cast<byte const *>(&t), sizeof(T));
|
||
}
|
||
|
||
#endif // gsl_FEATURE_TO_STD( BYTE_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<T>> : std11::true_type
|
||
{
|
||
};
|
||
|
||
template <class T>
|
||
struct is_basic_string_span : is_basic_string_span_oracle<typename std11::remove_cv<T>::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<T> 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<index_type>(0))
|
||
{
|
||
}
|
||
#endif
|
||
|
||
#ifdef __CUDACC_RELAXED_CONSTEXPR__
|
||
gsl_api
|
||
#endif // __CUDACC_RELAXED_CONSTEXPR__
|
||
gsl_constexpr
|
||
basic_string_span(pointer ptr)
|
||
: span_(remove_z(ptr, (std::numeric_limits<index_type>::max)()))
|
||
{
|
||
}
|
||
|
||
gsl_api gsl_constexpr basic_string_span(pointer ptr, index_type count)
|
||
: span_(ptr, count)
|
||
{
|
||
}
|
||
|
||
gsl_api gsl_constexpr basic_string_span(pointer firstElem, pointer lastElem)
|
||
: span_(firstElem, lastElem)
|
||
{
|
||
}
|
||
|
||
template <std::size_t N>
|
||
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>
|
||
gsl_constexpr basic_string_span(std::array<typename std11::remove_const<element_type>::type, N> &arr)
|
||
: span_(remove_z(arr))
|
||
{
|
||
}
|
||
|
||
template <std::size_t N>
|
||
gsl_constexpr basic_string_span(std::array<typename std11::remove_const<element_type>::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<Container>().data())>::value))>
|
||
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<Container const &>().data())>::value))>
|
||
gsl_constexpr basic_string_span(Container const &cont)
|
||
: span_((cont))
|
||
{
|
||
}
|
||
|
||
#elif gsl_HAVE(UNCONSTRAINED_SPAN_CONTAINER_CTOR)
|
||
|
||
template <class Container>
|
||
gsl_constexpr basic_string_span(Container &cont)
|
||
: span_(cont)
|
||
{
|
||
}
|
||
|
||
template <class Container>
|
||
gsl_constexpr basic_string_span(Container const &cont)
|
||
: span_(cont)
|
||
{
|
||
}
|
||
|
||
#else
|
||
|
||
template <class U>
|
||
gsl_api gsl_constexpr basic_string_span(span<U> const &rhs)
|
||
: span_(rhs)
|
||
{
|
||
}
|
||
|
||
#endif
|
||
|
||
#if gsl_FEATURE_TO_STD(WITH_CONTAINER)
|
||
|
||
template <class Container>
|
||
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<typename basic_string_span<U>::pointer, pointer>::value))>
|
||
gsl_api gsl_constexpr basic_string_span(basic_string_span<U> const &rhs)
|
||
: span_(reinterpret_cast<pointer>(rhs.data()), rhs.length()) // NOLINT
|
||
{
|
||
}
|
||
|
||
#if gsl_STDLIB_CPP11_120
|
||
template <class U
|
||
gsl_ENABLE_IF_((std::is_convertible<typename basic_string_span<U>::pointer, pointer>::value))>
|
||
gsl_api gsl_constexpr basic_string_span(basic_string_span<U> &&rhs)
|
||
: span_(reinterpret_cast<pointer>(rhs.data()), rhs.length()) // NOLINT
|
||
{
|
||
}
|
||
#endif // gsl_STDLIB_CPP11_120
|
||
|
||
template <class CharTraits, class Allocator>
|
||
gsl_constexpr basic_string_span(
|
||
std::basic_string<typename std11::remove_const<element_type>::type, CharTraits, Allocator> &str)
|
||
: span_(gsl_ADDRESSOF(str[0]), str.length())
|
||
{
|
||
}
|
||
|
||
template <class CharTraits, class Allocator>
|
||
gsl_constexpr basic_string_span(
|
||
std::basic_string<typename std11::remove_const<element_type>::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<typename std11::remove_const<element_type>::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<typename std11::remove_const<element_type>::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<T> const &l, U const &u) gsl_noexcept
|
||
{
|
||
const basic_string_span<typename std11::add_const<T>::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<T> const &l, U const &u) gsl_noexcept
|
||
{
|
||
const basic_string_span<typename std11::add_const<T>::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<U>::value))>
|
||
gsl_SUPPRESS_MSGSL_WARNING(stl .1)
|
||
gsl_NODISCARD inline gsl_constexpr14 bool
|
||
operator==(U const &u, basic_string_span<T> const &r) gsl_noexcept
|
||
{
|
||
const basic_string_span<typename std11::add_const<T>::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<U>::value))>
|
||
gsl_SUPPRESS_MSGSL_WARNING(stl .1)
|
||
gsl_NODISCARD inline gsl_constexpr14 bool
|
||
operator<(U const &u, basic_string_span<T> const &r) gsl_noexcept
|
||
{
|
||
const basic_string_span<typename std11::add_const<T>::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<T> const &l, basic_string_span<T> 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<T> const &l, basic_string_span<T> 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<T> 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<T> 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<T>::type> rr(r);
|
||
return !(rr < l);
|
||
#endif
|
||
}
|
||
|
||
template <class T, class U>
|
||
gsl_NODISCARD inline gsl_constexpr14 bool
|
||
operator>(basic_string_span<T> 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<T>::type> rr(r);
|
||
return (rr < l);
|
||
#endif
|
||
}
|
||
|
||
template <class T, class U>
|
||
gsl_NODISCARD inline gsl_constexpr14 bool
|
||
operator>=(basic_string_span<T> 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<U>::value))>
|
||
gsl_NODISCARD inline gsl_constexpr14 bool
|
||
operator!=(U const &l, basic_string_span<T> const &r) gsl_noexcept
|
||
{
|
||
return !(l == r);
|
||
}
|
||
|
||
template <class T, class U
|
||
gsl_ENABLE_IF_((!detail::is_basic_string_span<U>::value))>
|
||
gsl_NODISCARD inline gsl_constexpr14 bool
|
||
operator<=(U const &l, basic_string_span<T> const &r) gsl_noexcept
|
||
{
|
||
return !(r < l);
|
||
}
|
||
|
||
template <class T, class U
|
||
gsl_ENABLE_IF_((!detail::is_basic_string_span<U>::value))>
|
||
gsl_NODISCARD inline gsl_constexpr14 bool
|
||
operator>(U const &l, basic_string_span<T> const &r) gsl_noexcept
|
||
{
|
||
return (r < l);
|
||
}
|
||
|
||
template <class T, class U
|
||
gsl_ENABLE_IF_((!detail::is_basic_string_span<U>::value))>
|
||
gsl_NODISCARD inline gsl_constexpr14 bool
|
||
operator>=(U const &l, basic_string_span<T> 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<T> spn) gsl_noexcept
|
||
{
|
||
return span<const byte>(reinterpret_cast<const byte *>(spn.data()), spn.size_bytes()); // NOLINT
|
||
}
|
||
|
||
//
|
||
// String types:
|
||
//
|
||
|
||
typedef char *zstring;
|
||
typedef const char *czstring;
|
||
|
||
#if gsl_HAVE(WCHAR)
|
||
typedef wchar_t *wzstring;
|
||
typedef const wchar_t *cwzstring;
|
||
#endif
|
||
|
||
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<T>::type > to_string( basic_string_span<T> 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<std::size_t>(spn.length()));
|
||
}
|
||
|
||
gsl_NODISCARD inline std::string
|
||
to_string(cstring_span const &spn)
|
||
{
|
||
return std::string(spn.data(), static_cast<std::size_t>(spn.length()));
|
||
}
|
||
|
||
#if gsl_HAVE(WCHAR)
|
||
|
||
gsl_NODISCARD inline std::wstring
|
||
to_string(wstring_span const &spn)
|
||
{
|
||
return std::wstring(spn.data(), static_cast<std::size_t>(spn.length()));
|
||
}
|
||
|
||
gsl_NODISCARD inline std::wstring
|
||
to_string(cwstring_span const &spn)
|
||
{
|
||
return std::wstring(spn.data(), static_cast<std::size_t>(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<std::streamsize>(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 )
|
||
|
||
//
|
||
// 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<T> ensure_sentinel(T *seq, SizeType max = (std::numeric_limits<SizeType>::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<SizeType>(cur - seq) < max && *cur != Sentinel)
|
||
++cur;
|
||
|
||
gsl_Expects(*cur == Sentinel);
|
||
|
||
return span<T>(seq, gsl::narrow_cast<typename span<T>::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<T>
|
||
ensure_z(T *const &sz, size_t max = (std::numeric_limits<size_t>::max)())
|
||
{
|
||
return detail::ensure_sentinel<T, size_t, 0>(sz, max);
|
||
}
|
||
|
||
template <class T, size_t N>
|
||
gsl_NODISCARD inline gsl_constexpr14 span<T>
|
||
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<typename Container::pointer>::type>
|
||
ensure_z(Container & cont)
|
||
{
|
||
return ::gsl::ensure_z(cont.data(), cont.length());
|
||
}
|
||
#endif
|
||
|
||
//
|
||
// basic_zstring_span<> - A view of contiguous null-terminated characters, replace (*,len).
|
||
//
|
||
|
||
template <typename T>
|
||
class basic_zstring_span
|
||
{
|
||
public:
|
||
typedef T element_type;
|
||
typedef span<T> 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<element_type> string_span_type;
|
||
|
||
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;
|
||
}
|
||
|
||
gsl_NODISCARD gsl_api gsl_constexpr string_span_type
|
||
as_string_span() const gsl_noexcept
|
||
{
|
||
return string_span_type(span_.data(), span_.size() - 1);
|
||
}
|
||
|
||
/*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
|
||
|
||
} // namespace gsl
|
||
|
||
#if gsl_HAVE(HASH)
|
||
|
||
//
|
||
// std::hash specializations for GSL types
|
||
//
|
||
|
||
namespace gsl
|
||
{
|
||
namespace detail
|
||
{
|
||
//
|
||
// Helper struct for std::hash specializations
|
||
//
|
||
|
||
template <bool Condition>
|
||
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<is_default_constructible<hash<T>>::value>
|
||
{
|
||
public:
|
||
gsl_NODISCARD gsl_constexpr std::size_t
|
||
operator()(::gsl::not_null<T> const &v) const
|
||
// hash function is not `noexcept` because `as_nullable()` has preconditions
|
||
{
|
||
return hash<T>()(::gsl::as_nullable(v));
|
||
}
|
||
};
|
||
template <class T>
|
||
struct hash<::gsl::not_null<T *>>
|
||
{
|
||
public:
|
||
gsl_NODISCARD gsl_constexpr std::size_t
|
||
operator()(::gsl::not_null<T *> const &v) const gsl_noexcept
|
||
{
|
||
return hash<T *>()(::gsl::as_nullable(v));
|
||
}
|
||
};
|
||
|
||
template <>
|
||
struct hash<::gsl::byte>
|
||
{
|
||
public:
|
||
gsl_NODISCARD gsl_constexpr std::size_t operator()(::gsl::byte v) const gsl_noexcept
|
||
{
|
||
return ::gsl::to_integer<std::size_t>(v);
|
||
}
|
||
};
|
||
|
||
} // 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 <gsl-lite/gsl-lite.hpp> // instead of <gsl/gsl-lite.hpp>
|
||
//
|
||
// namespace foo {
|
||
// namespace gsl = ::gsl_lite; // convenience alias
|
||
// double mean( gsl::span<double const> elements )
|
||
// {
|
||
// gsl_Expects( ! elements.empty() ); // instead of Expects()
|
||
// ...
|
||
// }
|
||
// } // namespace foo
|
||
//
|
||
// In a future version, the new <gsl-lite/gsl-lite.hpp> 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 <gsl/gsl-lite.hpp> 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;
|
||
|
||
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 ::gsl::detail::no_adl;
|
||
|
||
#if gsl_HAVE(UNIQUE_PTR) && gsl_HAVE(SHARED_PTR)
|
||
using std::shared_ptr;
|
||
using std::unique_ptr;
|
||
#if gsl_HAVE(VARIADIC_TEMPLATE)
|
||
using ::gsl::make_shared;
|
||
using ::gsl::make_unique;
|
||
#endif
|
||
#endif
|
||
|
||
using ::gsl::diff;
|
||
using ::gsl::dim;
|
||
using ::gsl::index;
|
||
using ::gsl::stride;
|
||
|
||
#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<T>::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_error;
|
||
using ::gsl::on_return;
|
||
#endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD )
|
||
|
||
using ::gsl::narrow;
|
||
using ::gsl::narrow_cast;
|
||
using ::gsl::narrow_failfast;
|
||
using ::gsl::narrowing_error;
|
||
|
||
using ::gsl::at;
|
||
|
||
using ::gsl::make_not_null;
|
||
using ::gsl::not_null;
|
||
using ::gsl::not_null_ic;
|
||
|
||
using ::gsl::byte;
|
||
|
||
using ::gsl::to_byte;
|
||
using ::gsl::to_integer;
|
||
using ::gsl::to_string;
|
||
using ::gsl::to_uchar;
|
||
|
||
using ::gsl::with_container;
|
||
using ::gsl::with_container_t;
|
||
|
||
using ::gsl::as_bytes;
|
||
using ::gsl::as_writable_bytes;
|
||
using ::gsl::byte_span;
|
||
using ::gsl::copy;
|
||
using ::gsl::make_span;
|
||
using ::gsl::span;
|
||
#if !gsl_DEPRECATE_TO_LEVEL(6)
|
||
using ::gsl::as_writeable_bytes;
|
||
#endif
|
||
|
||
using ::gsl::basic_string_span;
|
||
using ::gsl::cstring_span;
|
||
using ::gsl::string_span;
|
||
|
||
using ::gsl::basic_zstring_span;
|
||
using ::gsl::czstring_span;
|
||
using ::gsl::zstring_span;
|
||
|
||
using ::gsl::czstring;
|
||
using ::gsl::zstring;
|
||
|
||
#if gsl_HAVE(WCHAR)
|
||
using ::gsl::cwzstring;
|
||
using ::gsl::wzstring;
|
||
|
||
using ::gsl::cwzstring_span;
|
||
using ::gsl::wzstring_span;
|
||
#endif // gsl_HAVE( WCHAR )
|
||
|
||
using ::gsl::ensure_z;
|
||
|
||
} // namespace gsl_lite
|
||
|
||
#endif // gsl_FEATURE( GSL_LITE_NAMESPACE )
|
||
|
||
gsl_RESTORE_MSVC_WARNINGS()
|
||
|
||
// #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
|