diff options
author | Jordan Maples [MSFT] <49793787+JordanMaples@users.noreply.github.com> | 2020-10-30 03:38:48 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-30 03:38:48 +0300 |
commit | a150aaa4ed355e88834877c9f39eadd4526e3b8f (patch) | |
tree | 44e9501ca637ff643f5a69c6bdcad49aa6abf5ca | |
parent | e8978c01abe375ec2f704411fdab02401ea63ae5 (diff) |
renaming main logic files. Added warning message of the removal and include passthrough. Renamed includes in the source files. Ran Clang-Format (#946)
Header rename
-rw-r--r-- | include/gsl/algorithm | 63 | ||||
-rw-r--r-- | include/gsl/assert | 135 | ||||
-rw-r--r-- | include/gsl/byte | 213 | ||||
-rw-r--r-- | include/gsl/gsl | 18 | ||||
-rw-r--r-- | include/gsl/gsl_algorithm | 64 | ||||
-rw-r--r-- | include/gsl/gsl_assert | 136 | ||||
-rw-r--r-- | include/gsl/gsl_byte | 212 | ||||
-rw-r--r-- | include/gsl/gsl_narrow | 55 | ||||
-rw-r--r-- | include/gsl/gsl_util | 132 | ||||
-rw-r--r-- | include/gsl/multi_span | 238 | ||||
-rw-r--r-- | include/gsl/narrow | 49 | ||||
-rw-r--r-- | include/gsl/pointers | 75 | ||||
-rw-r--r-- | include/gsl/span | 117 | ||||
-rw-r--r-- | include/gsl/span_ext | 5 | ||||
-rw-r--r-- | include/gsl/string_span | 13 | ||||
-rw-r--r-- | include/gsl/util | 145 | ||||
-rw-r--r-- | tests/algorithm_tests.cpp | 2 | ||||
-rw-r--r-- | tests/assertion_tests.cpp | 2 | ||||
-rw-r--r-- | tests/at_tests.cpp | 2 | ||||
-rw-r--r-- | tests/byte_tests.cpp | 2 | ||||
-rw-r--r-- | tests/multi_span_tests.cpp | 4 | ||||
-rw-r--r-- | tests/span_compatibility_tests.cpp | 2 | ||||
-rw-r--r-- | tests/span_ext_tests.cpp | 2 | ||||
-rw-r--r-- | tests/span_tests.cpp | 4 | ||||
-rw-r--r-- | tests/strided_span_tests.cpp | 4 | ||||
-rw-r--r-- | tests/string_span_tests.cpp | 2 | ||||
-rw-r--r-- | tests/utils_tests.cpp | 4 |
27 files changed, 934 insertions, 766 deletions
diff --git a/include/gsl/algorithm b/include/gsl/algorithm new file mode 100644 index 0000000..b27475d --- /dev/null +++ b/include/gsl/algorithm @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GSL_ALGORITHM_H +#define GSL_ALGORITHM_H + +#include <gsl/assert> // for Expects +#include <gsl/span> // for dynamic_extent, span + +#include <algorithm> // for copy_n +#include <cstddef> // for ptrdiff_t +#include <type_traits> // for is_assignable + +#ifdef _MSC_VER +#pragma warning(push) + +// turn off some warnings that are noisy about our Expects statements +#pragma warning(disable : 4127) // conditional expression is constant +#pragma warning(disable : 4996) // unsafe use of std::copy_n + +#endif // _MSC_VER + +namespace gsl +{ +// Note: this will generate faster code than std::copy using span iterator in older msvc+stl +// not necessary for msvc since VS2017 15.8 (_MSC_VER >= 1915) +template <class SrcElementType, std::size_t SrcExtent, class DestElementType, + std::size_t DestExtent> +void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest) +{ + static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value, + "Elements of source span can not be assigned to elements of destination span"); + static_assert(SrcExtent == dynamic_extent || DestExtent == dynamic_extent || + (SrcExtent <= DestExtent), + "Source range is longer than target range"); + + Expects(dest.size() >= src.size()); + // clang-format off + GSL_SUPPRESS(stl.1) // NO-FORMAT: attribute + // clang-format on + std::copy_n(src.data(), src.size(), dest.data()); +} + +} // namespace gsl + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +#endif // GSL_ALGORITHM_H diff --git a/include/gsl/assert b/include/gsl/assert new file mode 100644 index 0000000..0cc54f6 --- /dev/null +++ b/include/gsl/assert @@ -0,0 +1,135 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GSL_CONTRACTS_H +#define GSL_CONTRACTS_H + +// +// Temporary until MSVC STL supports no-exceptions mode. +// Currently terminate is a no-op in this mode, so we add termination behavior back +// +#if defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)) + +#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND +#include <intrin.h> +#define RANGE_CHECKS_FAILURE 0 + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winvalid-noreturn" +#endif // defined(__clang__) + +#else // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && + // !_HAS_EXCEPTIONS)) + +#include <exception> + +#endif // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && + // !_HAS_EXCEPTIONS)) + +// +// make suppress attributes parse for some compilers +// Hopefully temporary until suppression standardization occurs +// +#if defined(__clang__) +#define GSL_SUPPRESS(x) [[gsl::suppress("x")]] +#else +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] +#else +#define GSL_SUPPRESS(x) +#endif // _MSC_VER +#endif // __clang__ + +#define GSL_STRINGIFY_DETAIL(x) #x +#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x) + +#if defined(__clang__) || defined(__GNUC__) +#define GSL_LIKELY(x) __builtin_expect(!!(x), 1) +#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0) + +#else + +#define GSL_LIKELY(x) (!!(x)) +#define GSL_UNLIKELY(x) (!!(x)) +#endif // defined(__clang__) || defined(__GNUC__) + +// +// GSL_ASSUME(cond) +// +// Tell the optimizer that the predicate cond must hold. It is unspecified +// whether or not cond is actually evaluated. +// +#ifdef _MSC_VER +#define GSL_ASSUME(cond) __assume(cond) +#elif defined(__GNUC__) +#define GSL_ASSUME(cond) ((cond) ? static_cast<void>(0) : __builtin_unreachable()) +#else +#define GSL_ASSUME(cond) static_cast<void>((cond) ? 0 : 0) +#endif + +// +// GSL.assert: assertions +// + +namespace gsl +{ + +namespace details +{ +#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) + + typedef void(__cdecl* terminate_handler)(); + + // clang-format off + GSL_SUPPRESS(f.6) // NO-FORMAT: attribute + // clang-format on + [[noreturn]] inline void __cdecl default_terminate_handler() + { + __fastfail(RANGE_CHECKS_FAILURE); + } + + inline gsl::details::terminate_handler& get_terminate_handler() noexcept + { + static terminate_handler handler = &default_terminate_handler; + return handler; + } + +#endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) + + [[noreturn]] inline void terminate() noexcept + { +#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) + (*gsl::details::get_terminate_handler())(); +#else + std::terminate(); +#endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) + } + +} // namespace details +} // namespace gsl + +#define GSL_CONTRACT_CHECK(type, cond) \ + (GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate()) + +#define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond) +#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond) + +#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) && defined(__clang__) +#pragma clang diagnostic pop +#endif + +#endif // GSL_CONTRACTS_H diff --git a/include/gsl/byte b/include/gsl/byte new file mode 100644 index 0000000..9231340 --- /dev/null +++ b/include/gsl/byte @@ -0,0 +1,213 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GSL_BYTE_H +#define GSL_BYTE_H + +// +// make suppress attributes work for some compilers +// Hopefully temporary until suppression standardization occurs +// +#if defined(__clang__) +#define GSL_SUPPRESS(x) [[gsl::suppress("x")]] +#else +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] +#else +#define GSL_SUPPRESS(x) +#endif // _MSC_VER +#endif // __clang__ + +#include <type_traits> + +// VS2017 15.8 added support for the __cpp_lib_byte definition +// To do: drop _HAS_STD_BYTE when support for pre 15.8 expires +#ifdef _MSC_VER + +#pragma warning(push) + +// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool. +#pragma warning(disable : 26493) // don't use c-style casts // TODO: MSVC suppression in templates + // does not always work + +#ifndef GSL_USE_STD_BYTE +// this tests if we are under MSVC and the standard lib has std::byte and it is enabled +#if (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || \ + (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603) + +#define GSL_USE_STD_BYTE 1 + +#else // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= + // 201603) + +#define GSL_USE_STD_BYTE 0 + +#endif // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= + // 201603) +#endif // GSL_USE_STD_BYTE + +#else // _MSC_VER + +#ifndef GSL_USE_STD_BYTE +#include <cstddef> /* __cpp_lib_byte */ +// this tests if we are under GCC or Clang with enough -std=c++1z power to get us std::byte +// also check if libc++ version is sufficient (> 5.0) or libstdc++ actually contains std::byte +#if defined(__cplusplus) && (__cplusplus >= 201703L) && \ + (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) || \ + defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000)) + +#define GSL_USE_STD_BYTE 1 + +#else // defined(__cplusplus) && (__cplusplus >= 201703L) && + // (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) || + // defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000)) + +#define GSL_USE_STD_BYTE 0 + +#endif // defined(__cplusplus) && (__cplusplus >= 201703L) && + // (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) || + // defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000)) +#endif // GSL_USE_STD_BYTE + +#endif // _MSC_VER + +// Use __may_alias__ attribute on gcc and clang +#if defined __clang__ || (defined(__GNUC__) && __GNUC__ > 5) +#define byte_may_alias __attribute__((__may_alias__)) +#else // defined __clang__ || defined __GNUC__ +#define byte_may_alias +#endif // defined __clang__ || defined __GNUC__ + +#if GSL_USE_STD_BYTE +#include <cstddef> +#endif + +namespace gsl +{ +#if GSL_USE_STD_BYTE + +using std::byte; +using std::to_integer; + +#else // GSL_USE_STD_BYTE + +// This is a simple definition for now that allows +// use of byte within span<> to be standards-compliant +enum class byte_may_alias byte : unsigned char +{ +}; + +template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> +constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept +{ + return b = byte(static_cast<unsigned char>(b) << shift); +} + +template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> +constexpr byte operator<<(byte b, IntegerType shift) noexcept +{ + return byte(static_cast<unsigned char>(b) << shift); +} + +template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> +constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept +{ + return b = byte(static_cast<unsigned char>(b) >> shift); +} + +template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> +constexpr byte operator>>(byte b, IntegerType shift) noexcept +{ + return byte(static_cast<unsigned char>(b) >> shift); +} + +constexpr byte& operator|=(byte& l, byte r) noexcept +{ + return l = byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r)); +} + +constexpr byte operator|(byte l, byte r) noexcept +{ + return byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r)); +} + +constexpr byte& operator&=(byte& l, byte r) noexcept +{ + return l = byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r)); +} + +constexpr byte operator&(byte l, byte r) noexcept +{ + return byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r)); +} + +constexpr byte& operator^=(byte& l, byte r) noexcept +{ + return l = byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r)); +} + +constexpr byte operator^(byte l, byte r) noexcept +{ + return byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r)); +} + +constexpr byte operator~(byte b) noexcept { return byte(~static_cast<unsigned char>(b)); } + +template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> +constexpr IntegerType to_integer(byte b) noexcept +{ + return static_cast<IntegerType>(b); +} + +#endif // GSL_USE_STD_BYTE + +template <bool E, typename T> +constexpr byte to_byte_impl(T t) noexcept +{ + static_assert( + E, "gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. " + "If you are calling to_byte with an integer contant use: gsl::to_byte<t>() version."); + return static_cast<byte>(t); +} +template <> +// NOTE: need suppression since c++14 does not allow "return {t}" +// GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: suppression does not work +constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept +{ + return byte(t); +} + +template <typename T> +constexpr byte to_byte(T t) noexcept +{ + return to_byte_impl<std::is_same<T, unsigned char>::value, T>(t); +} + +template <int I> +constexpr byte to_byte() noexcept +{ + static_assert(I >= 0 && I <= 255, + "gsl::byte only has 8 bits of storage, values must be in range 0-255"); + return static_cast<byte>(I); +} + +} // namespace gsl + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +#endif // GSL_BYTE_H diff --git a/include/gsl/gsl b/include/gsl/gsl index 4ce0eb9..2e22c5a 100644 --- a/include/gsl/gsl +++ b/include/gsl/gsl @@ -17,17 +17,17 @@ #ifndef GSL_GSL_H #define GSL_GSL_H -#include <gsl/gsl_algorithm> // copy -#include <gsl/gsl_assert> // Ensures/Expects -#include <gsl/gsl_byte> // byte -#include <gsl/gsl_util> // finally()/narrow_cast()... -#include <gsl/multi_span> // multi_span, strided_span... -#include <gsl/pointers> // owner, not_null -#include <gsl/span> // span -#include <gsl/string_span> // zstring, string_span, zstring_builder... +#include <gsl/algorithm> // copy +#include <gsl/assert> // Ensures/Expects +#include <gsl/byte> // byte +#include <gsl/pointers> // owner, not_null +#include <gsl/span> // multi_span, strided_span... +#include <gsl/span> // span +#include <gsl/string_span> // zstring, string_span, zstring_builder... +#include <gsl/util> // finally()/narrow_cast()... #ifdef __cpp_exceptions -#include <gsl/gsl_narrow> // narrow() +#include <gsl/narrow> // narrow() #endif #endif // GSL_GSL_H diff --git a/include/gsl/gsl_algorithm b/include/gsl/gsl_algorithm index 6813b6c..9f1dd50 100644 --- a/include/gsl/gsl_algorithm +++ b/include/gsl/gsl_algorithm @@ -1,61 +1,3 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2015 Microsoft Corporation. All rights reserved. -// -// This code is licensed under the MIT License (MIT). -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef GSL_ALGORITHM_H -#define GSL_ALGORITHM_H - -#include <gsl/gsl_assert> // for Expects -#include <gsl/span> // for dynamic_extent, span - -#include <algorithm> // for copy_n -#include <cstddef> // for ptrdiff_t -#include <type_traits> // for is_assignable - -#ifdef _MSC_VER -#pragma warning(push) - -// turn off some warnings that are noisy about our Expects statements -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4996) // unsafe use of std::copy_n - -#endif // _MSC_VER - -namespace gsl -{ -// Note: this will generate faster code than std::copy using span iterator in older msvc+stl -// not necessary for msvc since VS2017 15.8 (_MSC_VER >= 1915) -template <class SrcElementType, std::size_t SrcExtent, class DestElementType, - std::size_t DestExtent> -void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest) -{ - static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value, - "Elements of source span can not be assigned to elements of destination span"); - static_assert(SrcExtent == dynamic_extent || DestExtent == dynamic_extent || - (SrcExtent <= DestExtent), - "Source range is longer than target range"); - - Expects(dest.size() >= src.size()); - GSL_SUPPRESS(stl.1) // NO-FORMAT: attribute - std::copy_n(src.data(), src.size(), dest.data()); -} - -} // namespace gsl - -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER - -#endif // GSL_ALGORITHM_H +#pragma once
+#pragma message("This header will soon be removed. Use <gsl/algorithm> instead of <gsl/gsl_algorithm>")
+#include <gsl/algorithm>
diff --git a/include/gsl/gsl_assert b/include/gsl/gsl_assert index 3b96117..b83a772 100644 --- a/include/gsl/gsl_assert +++ b/include/gsl/gsl_assert @@ -1,133 +1,3 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2015 Microsoft Corporation. All rights reserved. -// -// This code is licensed under the MIT License (MIT). -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef GSL_CONTRACTS_H -#define GSL_CONTRACTS_H - -// -// Temporary until MSVC STL supports no-exceptions mode. -// Currently terminate is a no-op in this mode, so we add termination behavior back -// -#if defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)) - -#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND -#include <intrin.h> -#define RANGE_CHECKS_FAILURE 0 - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Winvalid-noreturn" -#endif // defined(__clang__) - -#else // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)) - -#include <exception> - -#endif // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)) - -// -// make suppress attributes parse for some compilers -// Hopefully temporary until suppression standardization occurs -// -#if defined(__clang__) -#define GSL_SUPPRESS(x) [[gsl::suppress("x")]] -#else -#if defined(_MSC_VER) && ! defined(__INTEL_COMPILER) -#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] -#else -#define GSL_SUPPRESS(x) -#endif // _MSC_VER -#endif // __clang__ - -#define GSL_STRINGIFY_DETAIL(x) #x -#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x) - -#if defined(__clang__) || defined(__GNUC__) -#define GSL_LIKELY(x) __builtin_expect(!!(x), 1) -#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0) - -#else - -#define GSL_LIKELY(x) (!!(x)) -#define GSL_UNLIKELY(x) (!!(x)) -#endif // defined(__clang__) || defined(__GNUC__) - -// -// GSL_ASSUME(cond) -// -// Tell the optimizer that the predicate cond must hold. It is unspecified -// whether or not cond is actually evaluated. -// -#ifdef _MSC_VER -#define GSL_ASSUME(cond) __assume(cond) -#elif defined(__GNUC__) -#define GSL_ASSUME(cond) ((cond) ? static_cast<void>(0) : __builtin_unreachable()) -#else -#define GSL_ASSUME(cond) static_cast<void>((cond) ? 0 : 0) -#endif - -// -// GSL.assert: assertions -// - -namespace gsl -{ - -namespace details -{ -#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) - - typedef void(__cdecl* terminate_handler)(); - - // clang-format off - GSL_SUPPRESS(f.6) // NO-FORMAT: attribute - // clang-format on - [[noreturn]] inline void __cdecl default_terminate_handler() - { - __fastfail(RANGE_CHECKS_FAILURE); - } - - inline gsl::details::terminate_handler& get_terminate_handler() noexcept - { - static terminate_handler handler = &default_terminate_handler; - return handler; - } - -#endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) - - [[noreturn]] inline void terminate() noexcept - { -#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) - (*gsl::details::get_terminate_handler())(); -#else - std::terminate(); -#endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) - } - -} // namespace details -} // namespace gsl - -#define GSL_CONTRACT_CHECK(type, cond) \ - (GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate()) - -#define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond) -#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond) - -#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) && defined(__clang__) -#pragma clang diagnostic pop -#endif - -#endif // GSL_CONTRACTS_H +#pragma once
+#pragma message("This header will soon be removed. Use <gsl/assert> instead of <gsl/gsl_assert>")
+#include <gsl/assert>
diff --git a/include/gsl/gsl_byte b/include/gsl/gsl_byte index 0d74b13..4f198ce 100644 --- a/include/gsl/gsl_byte +++ b/include/gsl/gsl_byte @@ -1,209 +1,3 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2015 Microsoft Corporation. All rights reserved. -// -// This code is licensed under the MIT License (MIT). -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef GSL_BYTE_H -#define GSL_BYTE_H - -// -// make suppress attributes work for some compilers -// Hopefully temporary until suppression standardization occurs -// -#if defined(__clang__) -#define GSL_SUPPRESS(x) [[gsl::suppress("x")]] -#else -#if defined(_MSC_VER) && ! defined(__INTEL_COMPILER) -#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] -#else -#define GSL_SUPPRESS(x) -#endif // _MSC_VER -#endif // __clang__ - -#include <type_traits> - -// VS2017 15.8 added support for the __cpp_lib_byte definition -// To do: drop _HAS_STD_BYTE when support for pre 15.8 expires -#ifdef _MSC_VER - -#pragma warning(push) - -// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool. -#pragma warning(disable : 26493) // don't use c-style casts // TODO: MSVC suppression in templates does not always work - -#ifndef GSL_USE_STD_BYTE -// this tests if we are under MSVC and the standard lib has std::byte and it is enabled -#if (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603) - -#define GSL_USE_STD_BYTE 1 - -#else // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603) - -#define GSL_USE_STD_BYTE 0 - -#endif // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603) -#endif // GSL_USE_STD_BYTE - -#else // _MSC_VER - -#ifndef GSL_USE_STD_BYTE -#include <cstddef> /* __cpp_lib_byte */ -// this tests if we are under GCC or Clang with enough -std=c++1z power to get us std::byte -// also check if libc++ version is sufficient (> 5.0) or libstdc++ actually contains std::byte -#if defined(__cplusplus) && (__cplusplus >= 201703L) && \ - (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) || \ - defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000)) - -#define GSL_USE_STD_BYTE 1 - -#else // defined(__cplusplus) && (__cplusplus >= 201703L) && - // (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) || - // defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000)) - -#define GSL_USE_STD_BYTE 0 - -#endif //defined(__cplusplus) && (__cplusplus >= 201703L) && - // (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) || - // defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000)) -#endif // GSL_USE_STD_BYTE - -#endif // _MSC_VER - -// Use __may_alias__ attribute on gcc and clang -#if defined __clang__ || (defined(__GNUC__) && __GNUC__ > 5) -#define byte_may_alias __attribute__((__may_alias__)) -#else // defined __clang__ || defined __GNUC__ -#define byte_may_alias -#endif // defined __clang__ || defined __GNUC__ - -#if GSL_USE_STD_BYTE -#include <cstddef> -#endif - -namespace gsl -{ -#if GSL_USE_STD_BYTE - -using std::byte; -using std::to_integer; - -#else // GSL_USE_STD_BYTE - -// This is a simple definition for now that allows -// use of byte within span<> to be standards-compliant -enum class byte_may_alias byte : unsigned char -{ -}; - -template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> -constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept -{ - return b = byte(static_cast<unsigned char>(b) << shift); -} - -template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> -constexpr byte operator<<(byte b, IntegerType shift) noexcept -{ - return byte(static_cast<unsigned char>(b) << shift); -} - -template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> -constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept -{ - return b = byte(static_cast<unsigned char>(b) >> shift); -} - -template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> -constexpr byte operator>>(byte b, IntegerType shift) noexcept -{ - return byte(static_cast<unsigned char>(b) >> shift); -} - -constexpr byte& operator|=(byte& l, byte r) noexcept -{ - return l = byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r)); -} - -constexpr byte operator|(byte l, byte r) noexcept -{ - return byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r)); -} - -constexpr byte& operator&=(byte& l, byte r) noexcept -{ - return l = byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r)); -} - -constexpr byte operator&(byte l, byte r) noexcept -{ - return byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r)); -} - -constexpr byte& operator^=(byte& l, byte r) noexcept -{ - return l = byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r)); -} - -constexpr byte operator^(byte l, byte r) noexcept -{ - return byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r)); -} - -constexpr byte operator~(byte b) noexcept { return byte(~static_cast<unsigned char>(b)); } - -template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> -constexpr IntegerType to_integer(byte b) noexcept -{ - return static_cast<IntegerType>(b); -} - -#endif // GSL_USE_STD_BYTE - -template <bool E, typename T> -constexpr byte to_byte_impl(T t) noexcept -{ - static_assert( - E, "gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. " - "If you are calling to_byte with an integer contant use: gsl::to_byte<t>() version."); - return static_cast<byte>(t); -} -template <> -// NOTE: need suppression since c++14 does not allow "return {t}" -// GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: suppression does not work -constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept -{ - return byte(t); -} - -template <typename T> -constexpr byte to_byte(T t) noexcept -{ - return to_byte_impl<std::is_same<T, unsigned char>::value, T>(t); -} - -template <int I> -constexpr byte to_byte() noexcept -{ - static_assert(I >= 0 && I <= 255, - "gsl::byte only has 8 bits of storage, values must be in range 0-255"); - return static_cast<byte>(I); -} - -} // namespace gsl - -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER - -#endif // GSL_BYTE_H +#pragma once
+#pragma message("This header will soon be removed. Use <gsl/byte> instead of <gsl/gsl_byte>")
+#include <gsl/byte>
diff --git a/include/gsl/gsl_narrow b/include/gsl/gsl_narrow index cec25a1..6c2cd10 100644 --- a/include/gsl/gsl_narrow +++ b/include/gsl/gsl_narrow @@ -1,52 +1,3 @@ -///////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
-//
-// This code is licensed under the MIT License (MIT).
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef GSL_NARROW_H
-#define GSL_NARROW_H
-#include <gsl/gsl_assert> // for Expects
-#include <gsl/gsl_util> // for narrow_cast
-namespace gsl
-{
-struct narrowing_error : public std::exception
-{
- const char* what() const noexcept override
- {
- return "narrowing_error";
- }
-};
-
-// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
-template <class T, class U>
-GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
-GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
-constexpr
-T narrow(U u) noexcept(false)
-{
- constexpr const bool is_different_signedness = (std::is_signed<T>::value != std::is_signed<U>::value);
-
- const T t = narrow_cast<T>(u);
-
- if (static_cast<U>(t) != u
- || (is_different_signedness
- && ((t < T{}) != (u < U{}))))
- {
- throw narrowing_error{};
- }
-
- return t;
-}
-}
-#endif // GSL_NARROW_H
+#pragma once
+#pragma message("This header will soon be removed. Use <gsl/narrow> instead of <gsl/gsl_narrow>")
+#include <gsl/narrow>
diff --git a/include/gsl/gsl_util b/include/gsl/gsl_util index ca733ac..6a6d77e 100644 --- a/include/gsl/gsl_util +++ b/include/gsl/gsl_util @@ -1,129 +1,3 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2015 Microsoft Corporation. All rights reserved. -// -// This code is licensed under the MIT License (MIT). -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef GSL_UTIL_H -#define GSL_UTIL_H - -#include <gsl/gsl_assert> // for Expects - -#include <array> -#include <cstddef> // for ptrdiff_t, size_t -#include <initializer_list> // for initializer_list -#include <type_traits> // for is_signed, integral_constant -#include <utility> // for exchange, forward - -#if defined(_MSC_VER) && !defined(__clang__) - -#pragma warning(push) -#pragma warning(disable : 4127) // conditional expression is constant - -#endif // _MSC_VER - -#if defined(__cplusplus) && (__cplusplus >= 201703L) -#define GSL_NODISCARD [[nodiscard]] -#else -#define GSL_NODISCARD -#endif // defined(__cplusplus) && (__cplusplus >= 201703L) - -namespace gsl -{ -// -// GSL.util: utilities -// - -// index type for all container indexes/subscripts/sizes -using index = std::ptrdiff_t; - -// final_action allows you to ensure something gets run at the end of a scope -template <class F> -class final_action -{ -public: - static_assert(!std::is_reference<F>::value && !std::is_const<F>::value && !std::is_volatile<F>::value, "Final_action should store its callable by value"); - - explicit final_action(F f) noexcept : f_(std::move(f)) {} - - final_action(final_action&& other) noexcept : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false)) {} - - final_action(const final_action&) = delete; - final_action& operator=(const final_action&) = delete; - final_action& operator=(final_action&&) = delete; - - GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // terminate if throws - ~final_action() noexcept - { - if (invoke_) f_(); - } - -private: - F f_; - bool invoke_{true}; -}; - -// finally() - convenience function to generate a final_action -template <class F> -GSL_NODISCARD final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type> finally(F&& f) noexcept -{ - return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(std::forward<F>(f)); -} - -// narrow_cast(): a searchable way to do narrowing casts of values -template <class T, class U> -GSL_SUPPRESS(type.1) // NO-FORMAT: attribute -constexpr T narrow_cast(U&& u) noexcept -{ - return static_cast<T>(std::forward<U>(u)); -} - -// -// at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector -// -template <class T, std::size_t N> -GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute -GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute -constexpr T& at(T (&arr)[N], const index i) -{ - Expects(i >= 0 && i < narrow_cast<index>(N)); - return arr[narrow_cast<std::size_t>(i)]; -} - -template <class Cont> -GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute -GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute -constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()]) -{ - Expects(i >= 0 && i < narrow_cast<index>(cont.size())); - using size_type = decltype(cont.size()); - return cont[narrow_cast<size_type>(i)]; -} - -template <class T> -GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute -constexpr T at(const std::initializer_list<T> cont, const index i) -{ - Expects(i >= 0 && i < narrow_cast<index>(cont.size())); - return *(cont.begin() + i); -} - -} // namespace gsl - -#if defined(_MSC_VER) && !defined(__clang__) - -#pragma warning(pop) - -#endif // _MSC_VER - -#endif // GSL_UTIL_H +#pragma once
+#pragma message("This header will soon be removed. Use <gsl/util> instead of <gsl/gsl_util>")
+#include <gsl/util>
diff --git a/include/gsl/multi_span b/include/gsl/multi_span index 120b0c5..14b86b3 100644 --- a/include/gsl/multi_span +++ b/include/gsl/multi_span @@ -17,12 +17,12 @@ #ifndef GSL_MULTI_SPAN_H #define GSL_MULTI_SPAN_H -#include <gsl/gsl_assert> // for Expects -#include <gsl/gsl_byte> // for byte -#include <gsl/gsl_util> // for narrow_cast +#include <gsl/assert> // for Expects +#include <gsl/byte> // for byte +#include <gsl/util> // for narrow_cast -#include <algorithm> // for transform, lexicographical_compare -#include <array> // for array +#include <algorithm> // for transform, lexicographical_compare +#include <array> // for array #include <cstddef> // for std::ptrdiff_t, size_t, nullptr_t #include <cstdint> // for PTRDIFF_MAX #include <functional> // for divides, multiplies, minus, negate, plus @@ -95,7 +95,8 @@ namespace details } // namespace details template <std::size_t Rank> -class [[deprecated]] multi_span_index final { +class [[deprecated]] multi_span_index final +{ static_assert(Rank > 0, "Rank must be greater than 0!"); template <std::size_t OtherRank> @@ -110,10 +111,12 @@ public: constexpr multi_span_index() noexcept {} - constexpr multi_span_index(const value_type(&values)[Rank]) noexcept + constexpr multi_span_index(const value_type (&values)[Rank]) noexcept { + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute + // clang-format on std::copy(values, values + Rank, elems); } @@ -127,8 +130,10 @@ public: constexpr multi_span_index& operator=(const multi_span_index& rhs) noexcept = default; // Preconditions: component_idx < rank + // clang-format off GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr reference operator[](std::size_t component_idx) { Expects(component_idx < Rank); // Component index must be less than rank @@ -136,16 +141,20 @@ public: } // Preconditions: component_idx < rank + // clang-format off GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr const_reference operator[](std::size_t component_idx) const { Expects(component_idx < Rank); // Component index must be less than rank return elems[component_idx]; } + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute + // clang-format on constexpr bool operator==(const multi_span_index& rhs) const { return std::equal(elems, elems + rank, rhs.elems); @@ -178,16 +187,20 @@ public: constexpr multi_span_index& operator+=(const multi_span_index& rhs) { + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute + // clang-format on std::transform(elems, elems + rank, rhs.elems, elems, std::plus<value_type>{}); return *this; } constexpr multi_span_index& operator-=(const multi_span_index& rhs) { + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute + // clang-format on std::transform(elems, elems + rank, rhs.elems, elems, std::minus<value_type>{}); return *this; } @@ -213,8 +226,10 @@ public: constexpr multi_span_index& operator*=(value_type v) { + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute + // clang-format on std::transform(elems, elems + rank, elems, [v](value_type x) { return std::multiplies<value_type>{}(x, v); }); return *this; @@ -222,8 +237,10 @@ public: constexpr multi_span_index& operator/=(value_type v) { + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.3) // NO-FORMAT: attribute + // clang-format on std::transform(elems, elems + rank, elems, [v](value_type x) { return std::divides<value_type>{}(x, v); }); return *this; @@ -286,7 +303,9 @@ const std::ptrdiff_t dynamic_range = -1; struct [[deprecated]] generalized_mapping_tag { }; -struct[[deprecated]] contiguous_mapping_tag : generalized_mapping_tag{}; +struct [[deprecated]] contiguous_mapping_tag : generalized_mapping_tag +{ +}; namespace details { @@ -298,7 +317,8 @@ namespace details }; template <std::ptrdiff_t... Ranges> - struct [[deprecated]] BoundsRanges { + struct [[deprecated]] BoundsRanges + { using size_type = std::ptrdiff_t; static const size_type Depth = 0; static const size_type DynamicNum = 0; @@ -337,7 +357,7 @@ namespace details }; template <std::ptrdiff_t... RestRanges> - struct[[deprecated]] BoundsRanges<dynamic_range, RestRanges...> : BoundsRanges<RestRanges...> + struct [[deprecated]] BoundsRanges<dynamic_range, RestRanges...> : BoundsRanges<RestRanges...> { using Base = BoundsRanges<RestRanges...>; using size_type = std::ptrdiff_t; @@ -350,9 +370,10 @@ namespace details size_type m_bound; public: - GSL_SUPPRESS( - f.23) // NO-FORMAT: attribute // this pointer type is cannot be assigned nullptr - issue in not_null - GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format off + GSL_SUPPRESS(f.23) // NO-FORMAT: attribute // this pointer type is cannot be assigned nullptr - issue in not_null + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on constexpr BoundsRanges(const std::ptrdiff_t* const arr) : Base(arr + 1), m_bound(*arr * this->Base::totalSize()) { @@ -369,14 +390,16 @@ namespace details {} template <typename T, std::size_t Dim = 0> - constexpr void serialize(T & arr) const + constexpr void serialize(T& arr) const { arr[Dim] = elementNum(); this->Base::template serialize<T, Dim + 1>(arr); } template <typename T, std::size_t Dim = 0> + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr size_type linearize(const T& arr) const { const size_type index = this->Base::totalSize() * arr[Dim]; @@ -393,19 +416,22 @@ namespace details return cur < m_bound ? cur + last : -1; } - GSL_SUPPRESS( - c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format off + GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format on constexpr size_type totalSize() const noexcept { return m_bound; } - GSL_SUPPRESS( - c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format off + GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format on constexpr size_type elementNum() const noexcept { return totalSize() / this->Base::totalSize(); } - GSL_SUPPRESS( - c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format off + GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format on constexpr size_type elementNum(std::size_t dim) const noexcept { if (dim > 0) @@ -422,7 +448,7 @@ namespace details }; template <std::ptrdiff_t CurRange, std::ptrdiff_t... RestRanges> - struct[[deprecated]] BoundsRanges<CurRange, RestRanges...> : BoundsRanges<RestRanges...> + struct [[deprecated]] BoundsRanges<CurRange, RestRanges...> : BoundsRanges<RestRanges...> { using Base = BoundsRanges<RestRanges...>; using size_type = std::ptrdiff_t; @@ -440,12 +466,14 @@ namespace details bool firstLevel = true) : Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false) { + // clang-format off GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: false positive + // clang-format on (void) firstLevel; } template <typename T, std::size_t Dim = 0> - constexpr void serialize(T & arr) const + constexpr void serialize(T& arr) const { arr[Dim] = elementNum(); this->Base::template serialize<T, Dim + 1>(arr); @@ -454,9 +482,13 @@ namespace details template <typename T, std::size_t Dim = 0> constexpr size_type linearize(const T& arr) const { + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on Expects(arr[Dim] >= 0 && arr[Dim] < CurrentRange); // Index is out of range + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on const std::ptrdiff_t d = arr[Dim]; return this->Base::totalSize() * d + this->Base::template linearize<T, Dim + 1>(arr); } @@ -470,19 +502,22 @@ namespace details return this->Base::totalSize() * arr[Dim] + last; } - GSL_SUPPRESS( - c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format off + GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format on constexpr size_type totalSize() const noexcept { return CurrentRange * this->Base::totalSize(); } - GSL_SUPPRESS( - c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format off + GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format on constexpr size_type elementNum() const noexcept { return CurrentRange; } - GSL_SUPPRESS( - c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format off + GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used + // clang-format on constexpr size_type elementNum(std::size_t dim) const noexcept { if (dim > 0) @@ -498,14 +533,17 @@ namespace details }; template <typename SourceType, typename TargetType> - struct[[deprecated]] BoundsRangeConvertible + struct [[deprecated]] BoundsRangeConvertible : public std::integral_constant<bool, (SourceType::TotalSize >= TargetType::TotalSize || TargetType::TotalSize == dynamic_range || SourceType::TotalSize == dynamic_range || - TargetType::TotalSize == 0)>{}; + TargetType::TotalSize == 0)> + { + }; template <typename TypeChain> - struct [[deprecated]] TypeListIndexer { + struct [[deprecated]] TypeListIndexer + { const TypeChain& obj_; constexpr TypeListIndexer(const TypeChain& obj) : obj_(obj) {} @@ -518,13 +556,13 @@ namespace details template <std::size_t N, typename MyChain = TypeChain, typename MyBase = typename MyChain::Base> constexpr auto getObj(std::false_type) - ->decltype(TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>()) + -> decltype(TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>()) { return TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>(); } template <std::size_t N> - constexpr auto get()->decltype(getObj<N - 1>(std::integral_constant<bool, N == 0>())) + constexpr auto get() -> decltype(getObj<N - 1>(std::integral_constant<bool, N == 0>())) { return getObj<N - 1>(std::integral_constant<bool, N == 0>()); } @@ -543,7 +581,9 @@ namespace details Ret ret{}; for (std::size_t i = 0; i < Rank - 1; ++i) { + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on ret[i] = other[i + 1]; } return ret; @@ -554,13 +594,14 @@ template <typename IndexType> class [[deprecated]] bounds_iterator; template <std::ptrdiff_t... Ranges> -class [[deprecated]] static_bounds { +class [[deprecated]] static_bounds +{ public: static_bounds(const details::BoundsRanges<Ranges...>&) {} }; template <std::ptrdiff_t FirstRange, std::ptrdiff_t... RestRanges> -class[[deprecated]] static_bounds<FirstRange, RestRanges...> +class [[deprecated]] static_bounds<FirstRange, RestRanges...> { using MyRanges = details::BoundsRanges<FirstRange, RestRanges...>; @@ -592,10 +633,10 @@ public: template <std::size_t Rank, typename SourceType, typename TargetType, typename Ret = BoundsRangeConvertible2<typename SourceType::Base, typename TargetType::Base, Rank>> - static auto helpBoundsRangeConvertible(SourceType, TargetType, std::true_type)->Ret; + static auto helpBoundsRangeConvertible(SourceType, TargetType, std::true_type) -> Ret; template <std::size_t Rank, typename SourceType, typename TargetType> - static auto helpBoundsRangeConvertible(SourceType, TargetType, ...)->std::false_type; + static auto helpBoundsRangeConvertible(SourceType, TargetType, ...) -> std::false_type; template <typename SourceType, typename TargetType, std::size_t Rank> struct BoundsRangeConvertible2 @@ -721,7 +762,8 @@ public: }; template <std::size_t Rank> -class [[deprecated]] strided_bounds { +class [[deprecated]] strided_bounds +{ template <std::size_t OtherRank> friend class strided_bounds; @@ -745,7 +787,7 @@ public: constexpr strided_bounds& operator=(const strided_bounds&) noexcept = default; - constexpr strided_bounds(const value_type(&values)[rank], index_type strides) + constexpr strided_bounds(const value_type (&values)[rank], index_type strides) : m_extents(values), m_strides(std::move(strides)) {} @@ -755,7 +797,9 @@ public: constexpr index_type strides() const noexcept { return m_strides; } + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr size_type total_size() const noexcept { size_type ret = 0; @@ -763,7 +807,9 @@ public: return ret + 1; } + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr size_type size() const noexcept { size_type ret = 1; @@ -780,7 +826,9 @@ public: return true; } + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr size_type linearize(const index_type& idx) const { size_type ret = 0; @@ -792,7 +840,9 @@ public: return ret; } + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr size_type stride() const noexcept { return m_strides[0]; } template <bool Enabled = (rank > 1), typename Ret = std::enable_if_t<Enabled, sliced_type>> @@ -803,7 +853,9 @@ public: template <std::size_t Dim = 0> + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr size_type extent() const noexcept { static_assert(Dim < Rank, @@ -823,14 +875,21 @@ private: }; template <typename T> -struct[[deprecated]] is_bounds : std::integral_constant<bool, false>{}; +struct [[deprecated]] is_bounds : std::integral_constant<bool, false> +{ +}; template <std::ptrdiff_t... Ranges> -struct[[deprecated]] is_bounds<static_bounds<Ranges...>> : std::integral_constant<bool, true>{}; +struct [[deprecated]] is_bounds<static_bounds<Ranges...>> : std::integral_constant<bool, true> +{ +}; template <std::size_t Rank> -struct[[deprecated]] is_bounds<strided_bounds<Rank>> : std::integral_constant<bool, true>{}; +struct [[deprecated]] is_bounds<strided_bounds<Rank>> : std::integral_constant<bool, true> +{ +}; template <typename IndexType> -class [[deprecated]] bounds_iterator { +class [[deprecated]] bounds_iterator +{ public: static const std::size_t rank = IndexType::rank; using iterator_category = std::random_access_iterator_tag; @@ -851,8 +910,10 @@ public: constexpr pointer operator->() const noexcept { return &curr_; } + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute + // clang-format on constexpr bounds_iterator& operator++() noexcept { @@ -877,7 +938,9 @@ public: return ret; } + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr bounds_iterator& operator--() { if (!less(curr_, boundary_)) @@ -914,7 +977,9 @@ public: return ret += n; } + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr bounds_iterator& operator+=(difference_type n) { auto linear_idx = linearize(curr_) + n; @@ -964,15 +1029,17 @@ public: constexpr bool operator>=(const bounds_iterator& rhs) const noexcept { return !(rhs > *this); } - void swap(bounds_iterator & rhs) noexcept + void swap(bounds_iterator& rhs) noexcept { std::swap(boundary_, rhs.boundary_); std::swap(curr_, rhs.curr_); } private: + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute - constexpr bool less(index_type & one, index_type & other) const noexcept + // clang-format on + constexpr bool less(index_type& one, index_type& other) const noexcept { for (std::size_t i = 0; i < rank; ++i) { @@ -981,7 +1048,9 @@ private: return false; } + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on constexpr index_size_type linearize(const value_type& idx) const noexcept { // TODO: Smarter impl. @@ -1043,8 +1112,10 @@ namespace details stride[Bounds::rank - 1] = 1; for (std::size_t i = 1; i < Bounds::rank; ++i) { + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute + // clang-format on stride[Bounds::rank - i - 1] = stride[Bounds::rank - i] * extents[Bounds::rank - i]; } return {stride}; @@ -1098,10 +1169,12 @@ constexpr dim_t<N> dim(std::ptrdiff_t n) noexcept template <typename ValueType, std::ptrdiff_t FirstDimension = dynamic_range, std::ptrdiff_t... RestDimensions> -class [[deprecated("gsl::multi_span is deprecated because it is not in the C++ Core Guidelines")]] multi_span; +class [[deprecated( + "gsl::multi_span is deprecated because it is not in the C++ Core Guidelines")]] multi_span; template <typename ValueType, std::size_t Rank> -class [[deprecated("gsl::strided_span is deprecated because it is not in the C++ Core Guidelines")]] strided_span; +class [[deprecated( + "gsl::strided_span is deprecated because it is not in the C++ Core Guidelines")]] strided_span; namespace details { @@ -1188,8 +1261,8 @@ namespace details }; template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions> - struct [[deprecated]] is_multi_span_oracle<multi_span<ValueType, FirstDimension, RestDimensions...>> - : std::true_type + struct [[deprecated]] is_multi_span_oracle< + multi_span<ValueType, FirstDimension, RestDimensions...>> : std::true_type { }; @@ -1205,7 +1278,9 @@ namespace details } // namespace details template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions> -class [[deprecated("gsl::multi_span is deprecated because it is not in the C++ Core Guidelines")]] multi_span { +class [[deprecated( + "gsl::multi_span is deprecated because it is not in the C++ Core Guidelines")]] multi_span +{ // TODO do we still need this? template <typename ValueType2, std::ptrdiff_t FirstDimension2, std::ptrdiff_t... RestDimensions2> @@ -1237,7 +1312,9 @@ private: public: // default constructor - same as constructing from nullptr_t + // clang-format off GSL_SUPPRESS(type.6) // NO-FORMAT: attribute // TODO: false positive + // clang-format on constexpr multi_span() noexcept : multi_span(nullptr, bounds_type{}) { static_assert(bounds_type::dynamic_rank != 0 || @@ -1247,7 +1324,9 @@ public: } // construct from nullptr - get an empty multi_span + // clang-format off GSL_SUPPRESS(type.6) // NO-FORMAT: attribute // TODO: false positive + // clang-format on constexpr multi_span(std::nullptr_t) noexcept : multi_span(nullptr, bounds_type{}) { static_assert(bounds_type::dynamic_rank != 0 || @@ -1271,7 +1350,9 @@ public: // construct from a single element + // clang-format off GSL_SUPPRESS(type.6) // NO-FORMAT: attribute // TODO: false positive + // clang-format on constexpr multi_span(reference data) noexcept : multi_span(&data, bounds_type{1}) { static_assert(bounds_type::dynamic_rank > 0 || bounds_type::static_size == 0 || @@ -1284,7 +1365,9 @@ public: constexpr multi_span(value_type &&) = delete; // construct from pointer + length + // clang-format off GSL_SUPPRESS(type.6) // NO-FORMAT: attribute // TODO: false positive + // clang-format on constexpr multi_span(pointer ptr, size_type size) : multi_span(ptr, bounds_type{size}) {} // construct from pointer + length - multidimensional @@ -1521,7 +1604,9 @@ public: return this->operator[](idx); } + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on constexpr reference operator[](const index_type& idx) const { return data_[bounds_.linearize(idx)]; @@ -1529,7 +1614,9 @@ public: template <bool Enabled = (Rank > 1), typename Ret = std::enable_if_t<Enabled, sliced_type>> + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on constexpr Ret operator[](size_type idx) const { Expects(idx >= 0 && idx < bounds_.size()); // index is out of bounds of the array @@ -1544,7 +1631,9 @@ public: constexpr iterator end() const noexcept { return iterator{this, false}; } + // clang-format off GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on constexpr const_iterator cbegin() const noexcept { return const_iterator{reinterpret_cast<const const_span*>(this), true}; @@ -1642,8 +1731,7 @@ constexpr auto as_multi_span(SpanType s, Dimensions2... dims) // convert a multi_span<T> to a multi_span<const byte> template <typename U, std::ptrdiff_t... Dimensions> -multi_span<const byte, dynamic_range> -as_bytes(multi_span<U, Dimensions...> s) noexcept +multi_span<const byte, dynamic_range> as_bytes(multi_span<U, Dimensions...> s) noexcept { static_assert(std::is_trivial<std::decay_t<U>>::value, "The value_type of multi_span must be a trivial type."); @@ -1729,8 +1817,7 @@ constexpr auto as_multi_span(T* arr, std::ptrdiff_t len) -> } template <typename T, std::size_t N> -constexpr auto as_multi_span(T (&arr)[N]) -> - typename details::SpanArrayTraits<T, N>::type +constexpr auto as_multi_span(T (&arr)[N]) -> typename details::SpanArrayTraits<T, N>::type { return {arr}; } @@ -1772,7 +1859,9 @@ constexpr auto as_multi_span(Cont&& arr) -> std::enable_if_t< // from basic_string which doesn't have nonconst .data() member like other contiguous containers template <typename CharT, typename Traits, typename Allocator> +// clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute +// clang-format on constexpr auto as_multi_span(std::basic_string<CharT, Traits, Allocator>& str) -> multi_span<CharT, dynamic_range> { @@ -1783,7 +1872,8 @@ constexpr auto as_multi_span(std::basic_string<CharT, Traits, Allocator>& str) // strided_span is an extension that is not strictly part of the GSL at this time. // It is kept here while the multidimensional interface is still being defined. template <typename ValueType, std::size_t Rank> -class [[deprecated("gsl::strided_span is deprecated because it is not in the C++ Core Guidelines")]] strided_span +class [[deprecated( + "gsl::strided_span is deprecated because it is not in the C++ Core Guidelines")]] strided_span { public: using bounds_type = strided_bounds<Rank>; @@ -1818,13 +1908,15 @@ public: Expects((bounds_.size() > 0 && ptr != nullptr) || bounds_.size() == 0); // Bounds cross data boundaries Expects(this->bounds().total_size() <= size); + // clang-format off GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: false positive + // clang-format on (void) size; } // from static array of size N template <size_type N> - constexpr strided_span(value_type (&values)[N], bounds_type bounds) + constexpr strided_span(value_type(&values)[N], bounds_type bounds) : strided_span(values, N, std::move(bounds)) {} @@ -1839,7 +1931,7 @@ public: // convertible template <typename OtherValueType, typename = std::enable_if_t<std::is_convertible< - OtherValueType (*)[], value_type (*)[]>::value>> + OtherValueType(*)[], value_type(*)[]>::value>> constexpr strided_span(const strided_span<OtherValueType, Rank>& other) : data_(other.data_), bounds_(other.bounds_) {} @@ -1858,7 +1950,9 @@ public: const size_type size = this->bounds().total_size() / d; + // clang-format off GSL_SUPPRESS(type.3) // NO-FORMAT: attribute + // clang-format on return {const_cast<OtherValueType*>(reinterpret_cast<const OtherValueType*>(this->data())), size, bounds_type{resize_extent(this->bounds().index_bounds(), d), @@ -1872,14 +1966,18 @@ public: bounds_type{extents, details::make_stride(bounds())}}; } + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on constexpr reference operator[](const index_type& idx) const { return data_[bounds_.linearize(idx)]; } template <bool Enabled = (Rank > 1), typename Ret = std::enable_if_t<Enabled, sliced_type>> + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on constexpr Ret operator[](size_type idx) const { Expects(idx < bounds_.size()); // index is out of bounds of the array @@ -1983,7 +2081,9 @@ private: static index_type resize_extent(const index_type& extent, std::ptrdiff_t d) { // The last dimension of the array needs to contain a multiple of new type elements + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on Expects(extent[Rank - 1] >= d && (extent[Rank - 1] % d == 0)); index_type ret = extent; @@ -1996,14 +2096,18 @@ private: static index_type resize_stride(const index_type& strides, std::ptrdiff_t, void* = nullptr) { // Only strided arrays with regular strides can be resized + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on Expects(strides[Rank - 1] == 1); return strides; } template <bool Enabled = (Rank > 1), typename = std::enable_if_t<Enabled>> + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on static index_type resize_stride(const index_type& strides, std::ptrdiff_t d) { // Only strided arrays with regular strides can be resized @@ -2026,7 +2130,8 @@ private: }; template <class Span> -class [[deprecated]] contiguous_span_iterator { +class [[deprecated]] contiguous_span_iterator +{ public: using iterator_category = std::random_access_iterator_tag; using value_type = typename Span::value_type; @@ -2041,14 +2146,18 @@ private: pointer data_; const Span* m_validator; + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on void validateThis() const { // iterator is out of range of the array Expects(data_ >= m_validator->data_ && data_ < m_validator->data_ + m_validator->size()); } + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on contiguous_span_iterator(const Span* container, bool isbegin) : data_(isbegin ? container->data_ : container->data_ + container->size()) , m_validator(container) @@ -2066,7 +2175,9 @@ public: return data_; } + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on contiguous_span_iterator& operator++() noexcept { ++data_; @@ -2079,7 +2190,9 @@ public: return ret; } + // clang-format off GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on contiguous_span_iterator& operator--() noexcept { --data_; @@ -2132,7 +2245,7 @@ public: bool operator>(const contiguous_span_iterator& rhs) const { return rhs < *this; } bool operator>=(const contiguous_span_iterator& rhs) const { return !(rhs > *this); } - void swap(contiguous_span_iterator & rhs) noexcept + void swap(contiguous_span_iterator& rhs) noexcept { std::swap(data_, rhs.data_); std::swap(m_validator, rhs.m_validator); @@ -2147,7 +2260,8 @@ contiguous_span_iterator<Span> operator+(typename contiguous_span_iterator<Span> } template <typename Span> -class [[deprecated]] general_span_iterator { +class [[deprecated]] general_span_iterator +{ public: using iterator_category = std::random_access_iterator_tag; using value_type = typename Span::value_type; @@ -2213,7 +2327,9 @@ public: return m_itr - rhs.m_itr; } + // clang-format off GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute + // clang-format on value_type operator[](difference_type n) const { return (*m_container)[m_itr[n]]; } bool operator==(const general_span_iterator& rhs) const @@ -2230,7 +2346,7 @@ public: bool operator<=(const general_span_iterator& rhs) const { return !(rhs < *this); } bool operator>(const general_span_iterator& rhs) const { return rhs < *this; } bool operator>=(const general_span_iterator& rhs) const { return !(rhs > *this); } - void swap(general_span_iterator & rhs) noexcept + void swap(general_span_iterator& rhs) noexcept { std::swap(m_itr, rhs.m_itr); std::swap(m_container, rhs.m_container); diff --git a/include/gsl/narrow b/include/gsl/narrow new file mode 100644 index 0000000..d47d9fd --- /dev/null +++ b/include/gsl/narrow @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_NARROW_H
+#define GSL_NARROW_H
+#include <gsl/assert> // for Expects
+#include <gsl/util> // for narrow_cast
+namespace gsl
+{
+struct narrowing_error : public std::exception
+{
+ const char* what() const noexcept override { return "narrowing_error"; }
+};
+
+// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
+template <class T, class U>
+// clang-format off
+GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
+GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
+// clang-format on
+ constexpr T narrow(U u) noexcept(false)
+{
+ constexpr const bool is_different_signedness =
+ (std::is_signed<T>::value != std::is_signed<U>::value);
+
+ const T t = narrow_cast<T>(u);
+
+ if (static_cast<U>(t) != u || (is_different_signedness && ((t < T{}) != (u < U{}))))
+ {
+ throw narrowing_error{};
+ }
+
+ return t;
+}
+} // namespace gsl
+#endif // GSL_NARROW_H
diff --git a/include/gsl/pointers b/include/gsl/pointers index f7c3885..42e8c09 100644 --- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -17,7 +17,7 @@ #ifndef GSL_POINTERS_H #define GSL_POINTERS_H -#include <gsl/gsl_assert> // for Ensures, Expects +#include <gsl/assert> // for Ensures, Expects #include <algorithm> // for forward #include <cstddef> // for ptrdiff_t, nullptr_t, size_t @@ -26,8 +26,8 @@ #include <type_traits> // for enable_if_t, is_convertible, is_assignable #if !defined(GSL_NO_IOSTREAMS) -#include <iosfwd> // for ostream -#endif // !defined(GSL_NO_IOSTREAMS) +#include <iosfwd> // for ostream +#endif // !defined(GSL_NO_IOSTREAMS) namespace gsl { @@ -35,13 +35,14 @@ namespace gsl // // GSL.owner: ownership pointers // -using std::unique_ptr; using std::shared_ptr; +using std::unique_ptr; // // owner // -// owner<T> is designed as a bridge for code that must deal directly with owning pointers for some reason +// owner<T> is designed as a bridge for code that must deal directly with owning pointers for some +// reason // // T must be a pointer type // - disallow construction from any type other than pointer type @@ -67,7 +68,8 @@ template <class T> class not_null { public: - static_assert(std::is_convertible<decltype(std::declval<T>() != nullptr), bool>::value, "T cannot be compared to nullptr."); + static_assert(std::is_convertible<decltype(std::declval<T>() != nullptr), bool>::value, + "T cannot be compared to nullptr."); template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>> constexpr not_null(U&& u) : ptr_(std::forward<U>(u)) @@ -83,8 +85,7 @@ public: template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>> constexpr not_null(const not_null<U>& other) : not_null(other.get()) - { - } + {} not_null(const not_null& other) = default; not_null& operator=(const not_null& other) = default; @@ -116,7 +117,8 @@ private: }; template <class T> -auto make_not_null(T&& t) noexcept { +auto make_not_null(T&& t) noexcept +{ return not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)}; } @@ -130,37 +132,49 @@ std::ostream& operator<<(std::ostream& os, const not_null<T>& val) #endif // !defined(GSL_NO_IOSTREAMS) template <class T, class U> -auto operator==(const not_null<T>& lhs, const not_null<U>& rhs) noexcept(noexcept(lhs.get() == rhs.get())) -> decltype(lhs.get() == rhs.get()) +auto operator==(const not_null<T>& lhs, + const not_null<U>& rhs) noexcept(noexcept(lhs.get() == rhs.get())) + -> decltype(lhs.get() == rhs.get()) { return lhs.get() == rhs.get(); } template <class T, class U> -auto operator!=(const not_null<T>& lhs, const not_null<U>& rhs) noexcept(noexcept(lhs.get() != rhs.get())) -> decltype(lhs.get() != rhs.get()) +auto operator!=(const not_null<T>& lhs, + const not_null<U>& rhs) noexcept(noexcept(lhs.get() != rhs.get())) + -> decltype(lhs.get() != rhs.get()) { return lhs.get() != rhs.get(); } template <class T, class U> -auto operator<(const not_null<T>& lhs, const not_null<U>& rhs) noexcept(noexcept(lhs.get() < rhs.get())) -> decltype(lhs.get() < rhs.get()) +auto operator<(const not_null<T>& lhs, + const not_null<U>& rhs) noexcept(noexcept(lhs.get() < rhs.get())) + -> decltype(lhs.get() < rhs.get()) { return lhs.get() < rhs.get(); } template <class T, class U> -auto operator<=(const not_null<T>& lhs, const not_null<U>& rhs) noexcept(noexcept(lhs.get() <= rhs.get())) -> decltype(lhs.get() <= rhs.get()) +auto operator<=(const not_null<T>& lhs, + const not_null<U>& rhs) noexcept(noexcept(lhs.get() <= rhs.get())) + -> decltype(lhs.get() <= rhs.get()) { return lhs.get() <= rhs.get(); } template <class T, class U> -auto operator>(const not_null<T>& lhs, const not_null<U>& rhs) noexcept(noexcept(lhs.get() > rhs.get())) -> decltype(lhs.get() > rhs.get()) +auto operator>(const not_null<T>& lhs, + const not_null<U>& rhs) noexcept(noexcept(lhs.get() > rhs.get())) + -> decltype(lhs.get() > rhs.get()) { return lhs.get() > rhs.get(); } template <class T, class U> -auto operator>=(const not_null<T>& lhs, const not_null<U>& rhs) noexcept(noexcept(lhs.get() >= rhs.get())) -> decltype(lhs.get() >= rhs.get()) +auto operator>=(const not_null<T>& lhs, + const not_null<U>& rhs) noexcept(noexcept(lhs.get() >= rhs.get())) + -> decltype(lhs.get() >= rhs.get()) { return lhs.get() >= rhs.get(); } @@ -208,28 +222,23 @@ namespace gsl // - remove unnecessary asserts // template <class T> -class strict_not_null: public not_null<T> +class strict_not_null : public not_null<T> { public: - template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>> - constexpr explicit strict_not_null(U&& u) : - not_null<T>(std::forward<U>(u)) + constexpr explicit strict_not_null(U&& u) : not_null<T>(std::forward<U>(u)) {} template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>> - constexpr explicit strict_not_null(T u) : - not_null<T>(u) + constexpr explicit strict_not_null(T u) : not_null<T>(u) {} template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>> - constexpr strict_not_null(const not_null<U>& other) : - not_null<T>(other) + constexpr strict_not_null(const not_null<U>& other) : not_null<T>(other) {} template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>> - constexpr strict_not_null(const strict_not_null<U>& other) : - not_null<T>(other) + constexpr strict_not_null(const strict_not_null<U>& other) : not_null<T>(other) {} strict_not_null(strict_not_null&& other) = default; @@ -266,15 +275,18 @@ template <class T> strict_not_null<T> operator+(std::ptrdiff_t, const strict_not_null<T>&) = delete; template <class T> -auto make_strict_not_null(T&& t) noexcept { +auto make_strict_not_null(T&& t) noexcept +{ return strict_not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)}; } -#if ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) ) +#if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L)) // deduction guides to prevent the ctad-maybe-unsupported warning -template <class T> not_null(T) -> not_null<T>; -template <class T> strict_not_null(T) -> strict_not_null<T>; +template <class T> +not_null(T) -> not_null<T>; +template <class T> +strict_not_null(T) -> strict_not_null<T>; #endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) ) @@ -285,7 +297,10 @@ namespace std template <class T> struct hash<gsl::strict_not_null<T>> { - std::size_t operator()(const gsl::strict_not_null<T>& value) const { return hash<T>{}(value.get()); } + std::size_t operator()(const gsl::strict_not_null<T>& value) const + { + return hash<T>{}(value.get()); + } }; } // namespace std diff --git a/include/gsl/span b/include/gsl/span index 73a4d96..0f567df 100644 --- a/include/gsl/span +++ b/include/gsl/span @@ -17,9 +17,9 @@ #ifndef GSL_SPAN_H #define GSL_SPAN_H -#include <gsl/gsl_assert> // for Expects -#include <gsl/gsl_byte> // for byte -#include <gsl/gsl_util> // for narrow_cast +#include <gsl/assert> // for Expects +#include <gsl/byte> // for byte +#include <gsl/util> // for narrow_cast #include <array> // for array #include <cstddef> // for ptrdiff_t, size_t, nullptr_t @@ -472,66 +472,70 @@ public: // requirement on Container to be a contiguous sequence container. template <std::size_t MyExtent = Extent, class Container, std::enable_if_t< - MyExtent != dynamic_extent && - !details::is_span<Container>::value && !details::is_std_array<Container>::value && - std::is_pointer<decltype(std::declval<Container&>().data())>::value && - std::is_convertible< - std::remove_pointer_t<decltype(std::declval<Container&>().data())> (*)[], - element_type (*)[]>::value, int> = 0> + MyExtent != dynamic_extent && !details::is_span<Container>::value && + !details::is_std_array<Container>::value && + std::is_pointer<decltype(std::declval<Container&>().data())>::value && + std::is_convertible< + std::remove_pointer_t<decltype(std::declval<Container&>().data())> (*)[], + element_type (*)[]>::value, + int> = 0> constexpr explicit span(Container& cont) noexcept : span(cont.data(), cont.size()) {} template <std::size_t MyExtent = Extent, class Container, std::enable_if_t< - MyExtent == dynamic_extent && - !details::is_span<Container>::value && !details::is_std_array<Container>::value && - std::is_pointer<decltype(std::declval<Container&>().data())>::value && - std::is_convertible< - std::remove_pointer_t<decltype(std::declval<Container&>().data())> (*)[], - element_type (*)[]>::value, int> = 0> + MyExtent == dynamic_extent && !details::is_span<Container>::value && + !details::is_std_array<Container>::value && + std::is_pointer<decltype(std::declval<Container&>().data())>::value && + std::is_convertible< + std::remove_pointer_t<decltype(std::declval<Container&>().data())> (*)[], + element_type (*)[]>::value, + int> = 0> constexpr span(Container& cont) noexcept : span(cont.data(), cont.size()) {} - template <std::size_t MyExtent = Extent, class Container, - std::enable_if_t< - MyExtent != dynamic_extent && - std::is_const<element_type>::value && !details::is_span<Container>::value && - !details::is_std_array<Container>::value && - std::is_pointer<decltype(std::declval<const Container&>().data())>::value && - std::is_convertible<std::remove_pointer_t< - decltype(std::declval<const Container&>().data())> (*)[], - element_type (*)[]>::value, int> = 0> + template < + std::size_t MyExtent = Extent, class Container, + std::enable_if_t< + MyExtent != dynamic_extent && std::is_const<element_type>::value && + !details::is_span<Container>::value && !details::is_std_array<Container>::value && + std::is_pointer<decltype(std::declval<const Container&>().data())>::value && + std::is_convertible< + std::remove_pointer_t<decltype(std::declval<const Container&>().data())> (*)[], + element_type (*)[]>::value, + int> = 0> constexpr explicit span(const Container& cont) noexcept : span(cont.data(), cont.size()) {} - template <std::size_t MyExtent = Extent, class Container, - std::enable_if_t< - MyExtent == dynamic_extent && - std::is_const<element_type>::value && !details::is_span<Container>::value && - !details::is_std_array<Container>::value && - std::is_pointer<decltype(std::declval<const Container&>().data())>::value && - std::is_convertible<std::remove_pointer_t< - decltype(std::declval<const Container&>().data())> (*)[], - element_type (*)[]>::value, int> = 0> + template < + std::size_t MyExtent = Extent, class Container, + std::enable_if_t< + MyExtent == dynamic_extent && std::is_const<element_type>::value && + !details::is_span<Container>::value && !details::is_std_array<Container>::value && + std::is_pointer<decltype(std::declval<const Container&>().data())>::value && + std::is_convertible< + std::remove_pointer_t<decltype(std::declval<const Container&>().data())> (*)[], + element_type (*)[]>::value, + int> = 0> constexpr span(const Container& cont) noexcept : span(cont.data(), cont.size()) {} constexpr span(const span& other) noexcept = default; - template < - class OtherElementType, std::size_t OtherExtent, std::size_t MyExtent = Extent, - std::enable_if_t< - (MyExtent == dynamic_extent || MyExtent == OtherExtent) && - details::is_allowed_element_type_conversion<OtherElementType, element_type>::value, int> = 0> + template <class OtherElementType, std::size_t OtherExtent, std::size_t MyExtent = Extent, + std::enable_if_t<(MyExtent == dynamic_extent || MyExtent == OtherExtent) && + details::is_allowed_element_type_conversion<OtherElementType, + element_type>::value, + int> = 0> constexpr span(const span<OtherElementType, OtherExtent>& other) noexcept : storage_(other.data(), details::extent_type<OtherExtent>(other.size())) {} - template < - class OtherElementType, std::size_t OtherExtent, std::size_t MyExtent = Extent, - std::enable_if_t< - MyExtent != dynamic_extent && OtherExtent == dynamic_extent && - details::is_allowed_element_type_conversion<OtherElementType, element_type>::value, int> = 0> + template <class OtherElementType, std::size_t OtherExtent, std::size_t MyExtent = Extent, + std::enable_if_t<MyExtent != dynamic_extent && OtherExtent == dynamic_extent && + details::is_allowed_element_type_conversion<OtherElementType, + element_type>::value, + int> = 0> constexpr explicit span(const span<OtherElementType, OtherExtent>& other) noexcept : storage_(other.data(), details::extent_type<OtherExtent>(other.size())) {} @@ -565,7 +569,8 @@ public: typename details::calculate_subspan_type<ElementType, Extent, Offset, Count>::type { Expects((size() >= Offset) && (Count == dynamic_extent || (Count <= size() - Offset))); - using type = typename details::calculate_subspan_type<ElementType, Extent, Offset, Count>::type; + using type = + typename details::calculate_subspan_type<ElementType, Extent, Offset, Count>::type; return type{data() + Offset, Count == dynamic_extent ? size() - Offset : Count}; } @@ -581,9 +586,8 @@ public: return make_subspan(size() - count, dynamic_extent, subspan_selector<Extent>{}); } - constexpr span<element_type, dynamic_extent> subspan(size_type offset, - size_type count = dynamic_extent) const - noexcept + constexpr span<element_type, dynamic_extent> + subspan(size_type offset, size_type count = dynamic_extent) const noexcept { return make_subspan(offset, count, subspan_selector<Extent>{}); } @@ -706,9 +710,8 @@ private: }; template <std::size_t CallerExtent> - constexpr span<element_type, dynamic_extent> make_subspan(size_type offset, size_type count, - subspan_selector<CallerExtent>) const - noexcept + constexpr span<element_type, dynamic_extent> + make_subspan(size_type offset, size_type count, subspan_selector<CallerExtent>) const noexcept { const span<element_type, dynamic_extent> tmp(*this); return tmp.subspan(offset, count); @@ -733,21 +736,21 @@ private: // Deduction Guides template <class Type, std::size_t Extent> -span(Type (&)[Extent])->span<Type, Extent>; +span(Type (&)[Extent]) -> span<Type, Extent>; template <class Type, std::size_t Size> -span(std::array<Type, Size>&)->span<Type, Size>; +span(std::array<Type, Size>&) -> span<Type, Size>; template <class Type, std::size_t Size> -span(const std::array<Type, Size>&)->span<const Type, Size>; +span(const std::array<Type, Size>&) -> span<const Type, Size>; template <class Container, - class Element = std::remove_pointer_t<decltype(std::declval<Container&>().data())>> -span(Container&)->span<Element>; + class Element = std::remove_pointer_t<decltype(std::declval<Container&>().data())>> +span(Container&) -> span<Element>; template <class Container, - class Element = std::remove_pointer_t<decltype(std::declval<const Container&>().data())>> -span(const Container&)->span<Element>; + class Element = std::remove_pointer_t<decltype(std::declval<const Container&>().data())>> +span(const Container&) -> span<Element>; #endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) ) diff --git a/include/gsl/span_ext b/include/gsl/span_ext index 1d375fd..b7c12cf 100644 --- a/include/gsl/span_ext +++ b/include/gsl/span_ext @@ -27,9 +27,8 @@ //
///////////////////////////////////////////////////////////////////////////////
-
-#include <gsl/gsl_util> // for narrow_cast, narrow
-#include <gsl/span> // for span
+#include <gsl/span> // for span
+#include <gsl/util> // for narrow_cast, narrow
#include <algorithm> // for lexicographical_compare
#include <cstddef> // for ptrdiff_t, size_t
diff --git a/include/gsl/string_span b/include/gsl/string_span index 2c11228..a76236d 100644 --- a/include/gsl/string_span +++ b/include/gsl/string_span @@ -17,9 +17,9 @@ #ifndef GSL_STRING_SPAN_H
#define GSL_STRING_SPAN_H
-#include <gsl/gsl_assert> // for Ensures, Expects
-#include <gsl/gsl_util> // for narrow_cast
-#include <gsl/span_ext> // for operator!=, operator==, dynamic_extent
+#include <gsl/assert> // for Ensures, Expects
+#include <gsl/span_ext> // for operator!=, operator==, dynamic_extent
+#include <gsl/util> // for narrow_cast
#include <algorithm> // for equal, lexicographical_compare
#include <array> // for array
@@ -167,10 +167,9 @@ class [[deprecated("string_span was removed from the C++ Core Guidelines. For mo namespace details
{
template <typename T>
- struct [
- [deprecated("string_span was removed from the C++ Core Guidelines. For more information, "
- "see isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span_oracle
- : std::false_type{};
+ struct [[deprecated(
+ "string_span was removed from the C++ Core Guidelines. For more information, "
+ "see isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span_oracle : std::false_type{};
template <typename CharT, std::size_t Extent>
struct [[deprecated(
diff --git a/include/gsl/util b/include/gsl/util new file mode 100644 index 0000000..2d67b7f --- /dev/null +++ b/include/gsl/util @@ -0,0 +1,145 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GSL_UTIL_H +#define GSL_UTIL_H + +#include <gsl/assert> // for Expects + +#include <array> +#include <cstddef> // for ptrdiff_t, size_t +#include <initializer_list> // for initializer_list +#include <type_traits> // for is_signed, integral_constant +#include <utility> // for exchange, forward + +#if defined(_MSC_VER) && !defined(__clang__) + +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant + +#endif // _MSC_VER + +#if defined(__cplusplus) && (__cplusplus >= 201703L) +#define GSL_NODISCARD [[nodiscard]] +#else +#define GSL_NODISCARD +#endif // defined(__cplusplus) && (__cplusplus >= 201703L) + +namespace gsl +{ +// +// GSL.util: utilities +// + +// index type for all container indexes/subscripts/sizes +using index = std::ptrdiff_t; + +// final_action allows you to ensure something gets run at the end of a scope +template <class F> +class final_action +{ +public: + static_assert(!std::is_reference<F>::value && !std::is_const<F>::value && + !std::is_volatile<F>::value, + "Final_action should store its callable by value"); + + explicit final_action(F f) noexcept : f_(std::move(f)) {} + + final_action(final_action&& other) noexcept + : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false)) + {} + + final_action(const final_action&) = delete; + final_action& operator=(const final_action&) = delete; + final_action& operator=(final_action&&) = delete; + + // clang-format off + GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // terminate if throws + // clang-format on + ~final_action() noexcept + { + if (invoke_) f_(); + } + +private: + F f_; + bool invoke_{true}; +}; + +// finally() - convenience function to generate a final_action +template <class F> +GSL_NODISCARD final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type> +finally(F&& f) noexcept +{ + return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>( + std::forward<F>(f)); +} + +// narrow_cast(): a searchable way to do narrowing casts of values +template <class T, class U> +// clang-format off +GSL_SUPPRESS(type.1) // NO-FORMAT: attribute +// clang-format on +constexpr T narrow_cast(U&& u) noexcept +{ + return static_cast<T>(std::forward<U>(u)); +} + +// +// at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector +// +template <class T, std::size_t N> +// clang-format off +GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute +GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute +// clang-format on + constexpr T& at(T (&arr)[N], const index i) +{ + Expects(i >= 0 && i < narrow_cast<index>(N)); + return arr[narrow_cast<std::size_t>(i)]; +} + +template <class Cont> +// clang-format off +GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute +GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute +// clang-format on + constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()]) +{ + Expects(i >= 0 && i < narrow_cast<index>(cont.size())); + using size_type = decltype(cont.size()); + return cont[narrow_cast<size_type>(i)]; +} + +template <class T> +// clang-format off +GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute +// clang-format on +constexpr T at(const std::initializer_list<T> cont, const index i) +{ + Expects(i >= 0 && i < narrow_cast<index>(cont.size())); + return *(cont.begin() + i); +} + +} // namespace gsl + +#if defined(_MSC_VER) && !defined(__clang__) + +#pragma warning(pop) + +#endif // _MSC_VER + +#endif // GSL_UTIL_H diff --git a/tests/algorithm_tests.cpp b/tests/algorithm_tests.cpp index ec9b2d1..0f209ac 100644 --- a/tests/algorithm_tests.cpp +++ b/tests/algorithm_tests.cpp @@ -15,7 +15,7 @@ /////////////////////////////////////////////////////////////////////////////// #include <gtest/gtest.h> -#include <gsl/gsl_algorithm> // for copy +#include <gsl/algorithm> // for copy #include <gsl/span> // for span #include <array> // for array #include <cstddef> // for size_t diff --git a/tests/assertion_tests.cpp b/tests/assertion_tests.cpp index c45b00c..6b5fb0b 100644 --- a/tests/assertion_tests.cpp +++ b/tests/assertion_tests.cpp @@ -15,7 +15,7 @@ /////////////////////////////////////////////////////////////////////////////// #include <gtest/gtest.h> -#include <gsl/gsl_assert> // for fail_fast (ptr only), Ensures, Expects +#include <gsl/assert> // for fail_fast (ptr only), Ensures, Expects using namespace gsl; diff --git a/tests/at_tests.cpp b/tests/at_tests.cpp index be2c7b8..1285139 100644 --- a/tests/at_tests.cpp +++ b/tests/at_tests.cpp @@ -16,7 +16,7 @@ #include <gtest/gtest.h> -#include <gsl/gsl_util> // for at +#include <gsl/util> // for at #include <array> // for array #include <cstddef> // for size_t diff --git a/tests/byte_tests.cpp b/tests/byte_tests.cpp index f2850ad..2a86cac 100644 --- a/tests/byte_tests.cpp +++ b/tests/byte_tests.cpp @@ -16,7 +16,7 @@ #include <gtest/gtest.h> -#include <gsl/gsl_byte> // for to_byte, to_integer, byte, operator&, ope... +#include <gsl/byte> // for to_byte, to_integer, byte, operator&, ope... using namespace std; using namespace gsl; diff --git a/tests/multi_span_tests.cpp b/tests/multi_span_tests.cpp index 32dbf94..9f93315 100644 --- a/tests/multi_span_tests.cpp +++ b/tests/multi_span_tests.cpp @@ -16,8 +16,8 @@ #include <gtest/gtest.h> -#include <gsl/gsl_byte> // for byte -#include <gsl/gsl_util> // for narrow_cast +#include <gsl/byte> // for byte +#include <gsl/util> // for narrow_cast #include <gsl/multi_span> // for multi_span, contiguous_span_iterator, dim #include <algorithm> // for fill, for_each diff --git a/tests/span_compatibility_tests.cpp b/tests/span_compatibility_tests.cpp index 5035687..361db84 100644 --- a/tests/span_compatibility_tests.cpp +++ b/tests/span_compatibility_tests.cpp @@ -16,7 +16,7 @@ #include <gtest/gtest.h> -#include <gsl/gsl_byte> // for byte +#include <gsl/byte> // for byte #include <gsl/span> // for span, span_iterator, operator==, operator!= #include <array> // for array diff --git a/tests/span_ext_tests.cpp b/tests/span_ext_tests.cpp index d413e03..4f07188 100644 --- a/tests/span_ext_tests.cpp +++ b/tests/span_ext_tests.cpp @@ -16,7 +16,7 @@ #include <gtest/gtest.h>
-#include <gsl/gsl_util> // for narrow_cast, at
+#include <gsl/util> // for narrow_cast, at
#include <gsl/span_ext> // for operator==, operator!=, make_span
#include <array> // for array
diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 6caaeea..b845d07 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -16,8 +16,8 @@ #include <gtest/gtest.h> -#include <gsl/gsl_byte> // for byte -#include <gsl/gsl_util> // for narrow_cast, at +#include <gsl/byte> // for byte +#include <gsl/util> // for narrow_cast, at #include <gsl/span> // for span, span_iterator, operator==, operator!= #include <array> // for array diff --git a/tests/strided_span_tests.cpp b/tests/strided_span_tests.cpp index 5a18f1b..67b23eb 100644 --- a/tests/strided_span_tests.cpp +++ b/tests/strided_span_tests.cpp @@ -15,8 +15,8 @@ /////////////////////////////////////////////////////////////////////////////// #include <gtest/gtest.h> -#include <gsl/gsl_byte> // for byte -#include <gsl/gsl_util> // for narrow_cast +#include <gsl/byte> // for byte +#include <gsl/util> // for narrow_cast #include <gsl/multi_span> // for strided_span, index, multi_span, strided_... #include <iostream> // for size_t diff --git a/tests/string_span_tests.cpp b/tests/string_span_tests.cpp index 7a9f7fb..3c919d0 100644 --- a/tests/string_span_tests.cpp +++ b/tests/string_span_tests.cpp @@ -16,7 +16,7 @@ #include <gtest/gtest.h> -#include <gsl/gsl_assert> // for Expects, fail_fast (ptr only) +#include <gsl/assert> // for Expects, fail_fast (ptr only) #include <gsl/pointers> // for owner #include <gsl/span> // for span, dynamic_extent #include <gsl/string_span> // for basic_string_span, operator==, ensure_z diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp index 430788e..74dc990 100644 --- a/tests/utils_tests.cpp +++ b/tests/utils_tests.cpp @@ -16,8 +16,8 @@ #include <gtest/gtest.h> -#include <gsl/gsl_util> // finally, narrow_cast -#include <gsl/gsl_narrow> // for narrow, narrowing_error +#include <gsl/util> // finally, narrow_cast +#include <gsl/narrow> // for narrow, narrowing_error #include <algorithm> // for move #include <functional> // for reference_wrapper, _Bind_helper<>::type #include <limits> // for numeric_limits |