commit 4453827665a9ddf783c5d45bddaae37218ba41c6 from: Aleksey Ryndin date: Tue Aug 08 09:46:56 2023 UTC Add `git@github.com:microsoft/GSL.git`, v4.0.0 commit - a5e97151cb50779d57dec9ba02864a8b0fe5dfde commit + 4453827665a9ddf783c5d45bddaae37218ba41c6 blob - /dev/null blob + b27475de54b87a1c9692eca6adf853650e727361 (mode 644) --- /dev/null +++ 3party/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 // for Expects +#include // for dynamic_extent, span + +#include // for copy_n +#include // for ptrdiff_t +#include // 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 +void copy(span src, span dest) +{ + static_assert(std::is_assignable::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 blob - /dev/null blob + a6012048fc8def0907b7703e439cc2e73d8d5868 (mode 644) --- /dev/null +++ 3party/gsl/assert @@ -0,0 +1,136 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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_KERNEL_MODE + +#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND +#include +#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 + +#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(0) : __builtin_unreachable()) +#else +#define GSL_ASSUME(cond) static_cast((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(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 blob - /dev/null blob + 9231340b56839e06794c6a6f25e8bf651457e2e9 (mode 644) --- /dev/null +++ 3party/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 + +// 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 /* __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 +#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 ::value>> +constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept +{ + return b = byte(static_cast(b) << shift); +} + +template ::value>> +constexpr byte operator<<(byte b, IntegerType shift) noexcept +{ + return byte(static_cast(b) << shift); +} + +template ::value>> +constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept +{ + return b = byte(static_cast(b) >> shift); +} + +template ::value>> +constexpr byte operator>>(byte b, IntegerType shift) noexcept +{ + return byte(static_cast(b) >> shift); +} + +constexpr byte& operator|=(byte& l, byte r) noexcept +{ + return l = byte(static_cast(l) | static_cast(r)); +} + +constexpr byte operator|(byte l, byte r) noexcept +{ + return byte(static_cast(l) | static_cast(r)); +} + +constexpr byte& operator&=(byte& l, byte r) noexcept +{ + return l = byte(static_cast(l) & static_cast(r)); +} + +constexpr byte operator&(byte l, byte r) noexcept +{ + return byte(static_cast(l) & static_cast(r)); +} + +constexpr byte& operator^=(byte& l, byte r) noexcept +{ + return l = byte(static_cast(l) ^ static_cast(r)); +} + +constexpr byte operator^(byte l, byte r) noexcept +{ + return byte(static_cast(l) ^ static_cast(r)); +} + +constexpr byte operator~(byte b) noexcept { return byte(~static_cast(b)); } + +template ::value>> +constexpr IntegerType to_integer(byte b) noexcept +{ + return static_cast(b); +} + +#endif // GSL_USE_STD_BYTE + +template +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() version."); + return static_cast(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(unsigned char t) noexcept +{ + return byte(t); +} + +template +constexpr byte to_byte(T t) noexcept +{ + return to_byte_impl::value, T>(t); +} + +template +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(I); +} + +} // namespace gsl + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +#endif // GSL_BYTE_H blob - /dev/null blob + adadc40fe695f5c293c50734c30bf0b7d601425f (mode 644) --- /dev/null +++ 3party/gsl/gsl @@ -0,0 +1,32 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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_GSL_H +#define GSL_GSL_H + +#include // copy +#include // Ensures/Expects +#include // byte +#include // owner, not_null +#include // span +#include // zstring, string_span, zstring_builder... +#include // finally()/narrow_cast()... + +#ifdef __cpp_exceptions +#include // narrow() +#endif + +#endif // GSL_GSL_H blob - /dev/null blob + 303a5ae68c71099b5a9fb3a6a019c40af7f971b9 (mode 644) --- /dev/null +++ 3party/gsl/gsl_algorithm @@ -0,0 +1,4 @@ +#pragma once +#pragma message( \ + "This header will soon be removed. Use instead of ") +#include blob - /dev/null blob + b83a7729d0691d7959cf721c35f540ec3a4a88fe (mode 644) --- /dev/null +++ 3party/gsl/gsl_assert @@ -0,0 +1,3 @@ +#pragma once +#pragma message("This header will soon be removed. Use instead of ") +#include blob - /dev/null blob + 4f198ceffd93ae1a9ede4d2f92d5c34936dfa5f5 (mode 644) --- /dev/null +++ 3party/gsl/gsl_byte @@ -0,0 +1,3 @@ +#pragma once +#pragma message("This header will soon be removed. Use instead of ") +#include blob - /dev/null blob + 6c2cd103c4f9d9082314003058ab693a03a39685 (mode 644) --- /dev/null +++ 3party/gsl/gsl_narrow @@ -0,0 +1,3 @@ +#pragma once +#pragma message("This header will soon be removed. Use instead of ") +#include blob - /dev/null blob + 6a6d77e04b3df46f0356df9beba6c4aa8b90759a (mode 644) --- /dev/null +++ 3party/gsl/gsl_util @@ -0,0 +1,3 @@ +#pragma once +#pragma message("This header will soon be removed. Use instead of ") +#include blob - /dev/null blob + bec30d113f508c790c186fee502009569e3da54d (mode 644) --- /dev/null +++ 3party/gsl/narrow @@ -0,0 +1,71 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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 // for Expects +#include // 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 ::value>::type* = nullptr> +// 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::value != std::is_signed::value); + +GSL_SUPPRESS(es.103) // NO-FORMAT: attribute // don't overflow +GSL_SUPPRESS(es.104) // NO-FORMAT: attribute // don't underflow +GSL_SUPPRESS(p.2) // NO-FORMAT: attribute // don't rely on undefined behavior + const T t = narrow_cast(u); // While this is technically undefined behavior in some cases (i.e., if the source value is of floating-point type + // and cannot fit into the destination integral type), the resultant behavior is benign on the platforms + // that we target (i.e., no hardware trap representations are hit). + + if (static_cast(t) != u || (is_different_signedness && ((t < T{}) != (u < U{})))) + { + throw narrowing_error{}; + } + + return t; +} + +template ::value>::type* = nullptr> +// 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) +{ + const T t = narrow_cast(u); + + if (static_cast(t) != u) + { + throw narrowing_error{}; + } + + return t; +} +} // namespace gsl +#endif // GSL_NARROW_H blob - /dev/null blob + e6b234853aecb2133d6b1a65545d03669fa2e716 (mode 644) --- /dev/null +++ 3party/gsl/pointers @@ -0,0 +1,323 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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_POINTERS_H +#define GSL_POINTERS_H + +#include // for Ensures, Expects + +#include // for forward +#include // for ptrdiff_t, nullptr_t, size_t +#include // for shared_ptr, unique_ptr +#include // for hash +#include // for enable_if_t, is_convertible, is_assignable + +#if !defined(GSL_NO_IOSTREAMS) +#include // for ostream +#endif // !defined(GSL_NO_IOSTREAMS) + +namespace gsl +{ + +namespace details +{ + template + struct is_comparable_to_nullptr : std::false_type + { + }; + + template + struct is_comparable_to_nullptr< + T, + std::enable_if_t() != nullptr), bool>::value>> + : std::true_type + { + }; +} // namespace details + +// +// GSL.owner: ownership pointers +// +using std::shared_ptr; +using std::unique_ptr; + +// +// owner +// +// owner 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 +// +template ::value>> +using owner = T; + +// +// not_null +// +// Restricts a pointer or smart pointer to only hold non-null values. +// +// Has zero size overhead over T. +// +// If T is a pointer (i.e. T == U*) then +// - allow construction from U* +// - disallow construction from nullptr_t +// - disallow default construction +// - ensure construction from null U* fails +// - allow implicit conversion to U* +// +template +class not_null +{ +public: + static_assert(details::is_comparable_to_nullptr::value, "T cannot be compared to nullptr."); + + template ::value>> + constexpr not_null(U&& u) : ptr_(std::forward(u)) + { + Expects(ptr_ != nullptr); + } + + template ::value>> + constexpr not_null(T u) : ptr_(std::move(u)) + { + Expects(ptr_ != nullptr); + } + + template ::value>> + constexpr not_null(const not_null& other) : not_null(other.get()) + {} + + not_null(const not_null& other) = default; + not_null& operator=(const not_null& other) = default; + constexpr std::conditional_t::value, T, const T&> get() const + { + Ensures(ptr_ != nullptr); + return ptr_; + } + + constexpr operator T() const { return get(); } + constexpr decltype(auto) operator->() const { return get(); } + constexpr decltype(auto) operator*() const { return *get(); } + + // prevents compilation when someone attempts to assign a null pointer constant + not_null(std::nullptr_t) = delete; + not_null& operator=(std::nullptr_t) = delete; + + // unwanted operators...pointers only point to single objects! + not_null& operator++() = delete; + not_null& operator--() = delete; + not_null operator++(int) = delete; + not_null operator--(int) = delete; + not_null& operator+=(std::ptrdiff_t) = delete; + not_null& operator-=(std::ptrdiff_t) = delete; + void operator[](std::ptrdiff_t) const = delete; + +private: + T ptr_; +}; + +template +auto make_not_null(T&& t) noexcept +{ + return not_null>>{std::forward(t)}; +} + +#if !defined(GSL_NO_IOSTREAMS) +template +std::ostream& operator<<(std::ostream& os, const not_null& val) +{ + os << val.get(); + return os; +} +#endif // !defined(GSL_NO_IOSTREAMS) + +template +auto operator==(const not_null& lhs, + const not_null& rhs) noexcept(noexcept(lhs.get() == rhs.get())) + -> decltype(lhs.get() == rhs.get()) +{ + return lhs.get() == rhs.get(); +} + +template +auto operator!=(const not_null& lhs, + const not_null& rhs) noexcept(noexcept(lhs.get() != rhs.get())) + -> decltype(lhs.get() != rhs.get()) +{ + return lhs.get() != rhs.get(); +} + +template +auto operator<(const not_null& lhs, + const not_null& rhs) noexcept(noexcept(lhs.get() < rhs.get())) + -> decltype(lhs.get() < rhs.get()) +{ + return lhs.get() < rhs.get(); +} + +template +auto operator<=(const not_null& lhs, + const not_null& rhs) noexcept(noexcept(lhs.get() <= rhs.get())) + -> decltype(lhs.get() <= rhs.get()) +{ + return lhs.get() <= rhs.get(); +} + +template +auto operator>(const not_null& lhs, + const not_null& rhs) noexcept(noexcept(lhs.get() > rhs.get())) + -> decltype(lhs.get() > rhs.get()) +{ + return lhs.get() > rhs.get(); +} + +template +auto operator>=(const not_null& lhs, + const not_null& rhs) noexcept(noexcept(lhs.get() >= rhs.get())) + -> decltype(lhs.get() >= rhs.get()) +{ + return lhs.get() >= rhs.get(); +} + +// more unwanted operators +template +std::ptrdiff_t operator-(const not_null&, const not_null&) = delete; +template +not_null operator-(const not_null&, std::ptrdiff_t) = delete; +template +not_null operator+(const not_null&, std::ptrdiff_t) = delete; +template +not_null operator+(std::ptrdiff_t, const not_null&) = delete; + +} // namespace gsl + +namespace std +{ +template +struct hash> +{ + std::size_t operator()(const gsl::not_null& value) const { return hash{}(value.get()); } +}; + +} // namespace std + +namespace gsl +{ + +// +// strict_not_null +// +// Restricts a pointer or smart pointer to only hold non-null values, +// +// - provides a strict (i.e. explicit constructor from T) wrapper of not_null +// - to be used for new code that wishes the design to be cleaner and make not_null +// checks intentional, or in old code that would like to make the transition. +// +// To make the transition from not_null, incrementally replace not_null +// by strict_not_null and fix compilation errors +// +// Expect to +// - remove all unneeded conversions from raw pointer to not_null and back +// - make API clear by specifying not_null in parameters where needed +// - remove unnecessary asserts +// +template +class strict_not_null : public not_null +{ +public: + template ::value>> + constexpr explicit strict_not_null(U&& u) : not_null(std::forward(u)) + {} + + template ::value>> + constexpr explicit strict_not_null(T u) : not_null(u) + {} + + template ::value>> + constexpr strict_not_null(const not_null& other) : not_null(other) + {} + + template ::value>> + constexpr strict_not_null(const strict_not_null& other) : not_null(other) + {} + + strict_not_null(strict_not_null&& other) = default; + strict_not_null(const strict_not_null& other) = default; + strict_not_null& operator=(const strict_not_null& other) = default; + strict_not_null& operator=(const not_null& other) + { + not_null::operator=(other); + return *this; + } + + // prevents compilation when someone attempts to assign a null pointer constant + strict_not_null(std::nullptr_t) = delete; + strict_not_null& operator=(std::nullptr_t) = delete; + + // unwanted operators...pointers only point to single objects! + strict_not_null& operator++() = delete; + strict_not_null& operator--() = delete; + strict_not_null operator++(int) = delete; + strict_not_null operator--(int) = delete; + strict_not_null& operator+=(std::ptrdiff_t) = delete; + strict_not_null& operator-=(std::ptrdiff_t) = delete; + void operator[](std::ptrdiff_t) const = delete; +}; + +// more unwanted operators +template +std::ptrdiff_t operator-(const strict_not_null&, const strict_not_null&) = delete; +template +strict_not_null operator-(const strict_not_null&, std::ptrdiff_t) = delete; +template +strict_not_null operator+(const strict_not_null&, std::ptrdiff_t) = delete; +template +strict_not_null operator+(std::ptrdiff_t, const strict_not_null&) = delete; + +template +auto make_strict_not_null(T&& t) noexcept +{ + return strict_not_null>>{std::forward(t)}; +} + +#if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L)) + +// deduction guides to prevent the ctad-maybe-unsupported warning +template +not_null(T) -> not_null; +template +strict_not_null(T) -> strict_not_null; + +#endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) ) + +} // namespace gsl + +namespace std +{ +template +struct hash> +{ + std::size_t operator()(const gsl::strict_not_null& value) const + { + return hash{}(value.get()); + } +}; + +} // namespace std + +#endif // GSL_POINTERS_H blob - /dev/null blob + cc8a7b9b0ee79d0ab8669f45fe45d502c4a6c02f (mode 644) --- /dev/null +++ 3party/gsl/span @@ -0,0 +1,821 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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_SPAN_H +#define GSL_SPAN_H + +#include // for Expects +#include // for byte +#include // for narrow_cast + +#include // for array +#include // for ptrdiff_t, size_t, nullptr_t +#include // for span specialization of gsl::at and other span-related extensions +#include // for reverse_iterator, distance, random_access_... +#include // for enable_if_t, declval, is_convertible, inte... + +#if defined(_MSC_VER) && !defined(__clang__) +#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 : 4146) // unary minus operator applied to unsigned type, result still unsigned +#pragma warning(disable : 4702) // unreachable code + +// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool. +#pragma warning(disable : 26495) // uninitalized member when constructor calls constructor +#pragma warning(disable : 26446) // parser bug does not allow attributes on some templates + +#endif // _MSC_VER + +// See if we have enough C++17 power to use a static constexpr data member +// without needing an out-of-line definition +#if !(defined(__cplusplus) && (__cplusplus >= 201703L)) +#define GSL_USE_STATIC_CONSTEXPR_WORKAROUND +#endif // !(defined(__cplusplus) && (__cplusplus >= 201703L)) + +// GCC 7 does not like the signed unsigned missmatch (size_t ptrdiff_t) +// While there is a conversion from signed to unsigned, it happens at +// compiletime, so the compiler wouldn't have to warn indiscriminately, but +// could check if the source value actually doesn't fit into the target type +// and only warn in those cases. +#if defined(__GNUC__) && __GNUC__ > 6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + +namespace gsl +{ + +// implementation details +namespace details +{ + template + struct is_span_oracle : std::false_type + { + }; + + template + struct is_span_oracle> : std::true_type + { + }; + + template + struct is_span : public is_span_oracle> + { + }; + + template + struct is_std_array_oracle : std::false_type + { + }; + + template + struct is_std_array_oracle> : std::true_type + { + }; + + template + struct is_std_array : is_std_array_oracle> + { + }; + + template + struct is_allowed_extent_conversion + : std::integral_constant + { + }; + + template + struct is_allowed_element_type_conversion + : std::integral_constant::value> + { + }; + + template + class span_iterator + { + public: + using iterator_category = std::random_access_iterator_tag; + using value_type = std::remove_cv_t; + using difference_type = std::ptrdiff_t; + using pointer = Type*; + using reference = Type&; + +#ifdef _MSC_VER + using _Unchecked_type = pointer; +#endif // _MSC_VER + constexpr span_iterator() = default; + + constexpr span_iterator(pointer begin, pointer end, pointer current) + : begin_(begin), end_(end), current_(current) + {} + + constexpr operator span_iterator() const noexcept + { + return {begin_, end_, current_}; + } + + constexpr reference operator*() const noexcept + { + Expects(begin_ && end_); + Expects(begin_ <= current_ && current_ < end_); + return *current_; + } + + constexpr pointer operator->() const noexcept + { + Expects(begin_ && end_); + Expects(begin_ <= current_ && current_ < end_); + return current_; + } + constexpr span_iterator& operator++() noexcept + { + Expects(begin_ && current_ && end_); + Expects(current_ < end_); + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + ++current_; + return *this; + } + + constexpr span_iterator operator++(int) noexcept + { + span_iterator ret = *this; + ++*this; + return ret; + } + + constexpr span_iterator& operator--() noexcept + { + Expects(begin_ && end_); + Expects(begin_ < current_); + --current_; + return *this; + } + + constexpr span_iterator operator--(int) noexcept + { + span_iterator ret = *this; + --*this; + return ret; + } + + constexpr span_iterator& operator+=(const difference_type n) noexcept + { + if (n != 0) Expects(begin_ && current_ && end_); + if (n > 0) Expects(end_ - current_ >= n); + if (n < 0) Expects(current_ - begin_ >= -n); + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + current_ += n; + return *this; + } + + constexpr span_iterator operator+(const difference_type n) const noexcept + { + span_iterator ret = *this; + ret += n; + return ret; + } + + friend constexpr span_iterator operator+(const difference_type n, + const span_iterator& rhs) noexcept + { + return rhs + n; + } + + constexpr span_iterator& operator-=(const difference_type n) noexcept + { + if (n != 0) Expects(begin_ && current_ && end_); + if (n > 0) Expects(current_ - begin_ >= n); + if (n < 0) Expects(end_ - current_ >= -n); + current_ -= n; + return *this; + } + + constexpr span_iterator operator-(const difference_type n) const noexcept + { + span_iterator ret = *this; + ret -= n; + return ret; + } + + template < + class Type2, + std::enable_if_t, value_type>::value, int> = 0> + constexpr difference_type operator-(const span_iterator& rhs) const noexcept + { + Expects(begin_ == rhs.begin_ && end_ == rhs.end_); + return current_ - rhs.current_; + } + + constexpr reference operator[](const difference_type n) const noexcept + { + return *(*this + n); + } + + template < + class Type2, + std::enable_if_t, value_type>::value, int> = 0> + constexpr bool operator==(const span_iterator& rhs) const noexcept + { + Expects(begin_ == rhs.begin_ && end_ == rhs.end_); + return current_ == rhs.current_; + } + + template < + class Type2, + std::enable_if_t, value_type>::value, int> = 0> + constexpr bool operator!=(const span_iterator& rhs) const noexcept + { + return !(*this == rhs); + } + + template < + class Type2, + std::enable_if_t, value_type>::value, int> = 0> + constexpr bool operator<(const span_iterator& rhs) const noexcept + { + Expects(begin_ == rhs.begin_ && end_ == rhs.end_); + return current_ < rhs.current_; + } + + template < + class Type2, + std::enable_if_t, value_type>::value, int> = 0> + constexpr bool operator>(const span_iterator& rhs) const noexcept + { + return rhs < *this; + } + + template < + class Type2, + std::enable_if_t, value_type>::value, int> = 0> + constexpr bool operator<=(const span_iterator& rhs) const noexcept + { + return !(rhs < *this); + } + + template < + class Type2, + std::enable_if_t, value_type>::value, int> = 0> + constexpr bool operator>=(const span_iterator& rhs) const noexcept + { + return !(*this < rhs); + } + +#ifdef _MSC_VER + // MSVC++ iterator debugging support; allows STL algorithms in 15.8+ + // to unwrap span_iterator to a pointer type after a range check in STL + // algorithm calls + friend constexpr void _Verify_range(span_iterator lhs, span_iterator rhs) noexcept + { // test that [lhs, rhs) forms a valid range inside an STL algorithm + Expects(lhs.begin_ == rhs.begin_ // range spans have to match + && lhs.end_ == rhs.end_ && + lhs.current_ <= rhs.current_); // range must not be transposed + } + + constexpr void _Verify_offset(const difference_type n) const noexcept + { // test that *this + n is within the range of this call + if (n != 0) Expects(begin_ && current_ && end_); + if (n > 0) Expects(end_ - current_ >= n); + if (n < 0) Expects(current_ - begin_ >= -n); + } + + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + constexpr pointer _Unwrapped() const noexcept + { // after seeking *this to a high water mark, or using one of the + // _Verify_xxx functions above, unwrap this span_iterator to a raw + // pointer + return current_; + } + + // Tell the STL that span_iterator should not be unwrapped if it can't + // validate in advance, even in release / optimized builds: +#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND) + static constexpr const bool _Unwrap_when_unverified = false; +#else + static constexpr bool _Unwrap_when_unverified = false; +#endif + // clang-format off + GSL_SUPPRESS(con.3) // NO-FORMAT: attribute // TODO: false positive + // clang-format on + constexpr void _Seek_to(const pointer p) noexcept + { // adjust the position of *this to previously verified location p + // after _Unwrapped + current_ = p; + } +#endif + + pointer begin_ = nullptr; + pointer end_ = nullptr; + pointer current_ = nullptr; + }; + + template + class extent_type + { + public: + using size_type = std::size_t; + + constexpr extent_type() noexcept = default; + + constexpr explicit extent_type(extent_type); + + constexpr explicit extent_type(size_type size) { Expects(size == Ext); } + + constexpr size_type size() const noexcept { return Ext; } + + private: +#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND) + static constexpr const size_type size_ = Ext; // static size equal to Ext +#else + static constexpr size_type size_ = Ext; // static size equal to Ext +#endif + }; + + template <> + class extent_type + { + public: + using size_type = std::size_t; + + template + constexpr explicit extent_type(extent_type ext) : size_(ext.size()) + {} + + constexpr explicit extent_type(size_type size) : size_(size) + { + Expects(size != dynamic_extent); + } + + constexpr size_type size() const noexcept { return size_; } + + private: + size_type size_; + }; + + template + constexpr extent_type::extent_type(extent_type ext) + { + Expects(ext.size() == Ext); + } + + template + struct calculate_subspan_type + { + using type = span; + }; +} // namespace details + +// [span], class template span +template +class span +{ +public: + // constants and types + using element_type = ElementType; + using value_type = std::remove_cv_t; + using size_type = std::size_t; + using pointer = element_type*; + using const_pointer = const element_type*; + using reference = element_type&; + using const_reference = const element_type&; + using difference_type = std::ptrdiff_t; + + using iterator = details::span_iterator; + using reverse_iterator = std::reverse_iterator; + +#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND) + static constexpr const size_type extent{Extent}; +#else + static constexpr size_type extent{Extent}; +#endif + + // [span.cons], span constructors, copy, assignment, and destructor + template " SFINAE, since "std::enable_if_t" is ill-formed when Extent is greater than 0. + class = std::enable_if_t<(Dependent || + details::is_allowed_extent_conversion<0, Extent>::value)>> + constexpr span() noexcept : storage_(nullptr, details::extent_type<0>()) + {} + + template = 0> + constexpr explicit span(pointer ptr, size_type count) noexcept : storage_(ptr, count) + { + Expects(count == Extent); + } + + template = 0> + constexpr span(pointer ptr, size_type count) noexcept : storage_(ptr, count) + {} + + template = 0> + constexpr explicit span(pointer firstElem, pointer lastElem) noexcept + : storage_(firstElem, narrow_cast(lastElem - firstElem)) + { + Expects(lastElem - firstElem == static_cast(Extent)); + } + + template = 0> + constexpr span(pointer firstElem, pointer lastElem) noexcept + : storage_(firstElem, narrow_cast(lastElem - firstElem)) + {} + + template ::value, int> = 0> + constexpr span(element_type (&arr)[N]) noexcept + : storage_(KnownNotNull{arr}, details::extent_type()) + {} + + template < + class T, std::size_t N, + std::enable_if_t<(details::is_allowed_extent_conversion::value && + details::is_allowed_element_type_conversion::value), + int> = 0> + constexpr span(std::array& arr) noexcept + : storage_(KnownNotNull{arr.data()}, details::extent_type()) + {} + + template ::value && + details::is_allowed_element_type_conversion::value), + int> = 0> + constexpr span(const std::array& arr) noexcept + : storage_(KnownNotNull{arr.data()}, details::extent_type()) + {} + + // NB: the SFINAE on these constructors uses .data() as an incomplete/imperfect proxy for the + // requirement on Container to be a contiguous sequence container. + template ::value && + !details::is_std_array::value && + std::is_pointer().data())>::value && + std::is_convertible< + std::remove_pointer_t().data())> (*)[], + element_type (*)[]>::value, + int> = 0> + constexpr explicit span(Container& cont) noexcept : span(cont.data(), cont.size()) + {} + + template ::value && + !details::is_std_array::value && + std::is_pointer().data())>::value && + std::is_convertible< + std::remove_pointer_t().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::value && + !details::is_span::value && !details::is_std_array::value && + std::is_pointer().data())>::value && + std::is_convertible< + std::remove_pointer_t().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::value && + !details::is_span::value && !details::is_std_array::value && + std::is_pointer().data())>::value && + std::is_convertible< + std::remove_pointer_t().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 ::value, + int> = 0> + constexpr span(const span& other) noexcept + : storage_(other.data(), details::extent_type(other.size())) + {} + + template ::value, + int> = 0> + constexpr explicit span(const span& other) noexcept + : storage_(other.data(), details::extent_type(other.size())) + {} + + ~span() noexcept = default; + constexpr span& operator=(const span& other) noexcept = default; + + // [span.sub], span subviews + template + constexpr span first() const noexcept + { + Expects(Count <= size()); + return span{data(), Count}; + } + + template + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + constexpr span last() const noexcept + { + Expects(Count <= size()); + return span{data() + (size() - Count), Count}; + } + + template + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + constexpr auto subspan() const noexcept -> + typename details::calculate_subspan_type::type + { + Expects((size() >= Offset) && (Count == dynamic_extent || (Count <= size() - Offset))); + using type = + typename details::calculate_subspan_type::type; + return type{data() + Offset, Count == dynamic_extent ? size() - Offset : Count}; + } + + constexpr span first(size_type count) const noexcept + { + Expects(count <= size()); + return {data(), count}; + } + + constexpr span last(size_type count) const noexcept + { + Expects(count <= size()); + return make_subspan(size() - count, dynamic_extent, subspan_selector{}); + } + + constexpr span + subspan(size_type offset, size_type count = dynamic_extent) const noexcept + { + return make_subspan(offset, count, subspan_selector{}); + } + + // [span.obs], span observers + constexpr size_type size() const noexcept { return storage_.size(); } + + constexpr size_type size_bytes() const noexcept + { + Expects(size() < dynamic_extent / sizeof(element_type)); + return size() * sizeof(element_type); + } + + constexpr bool empty() const noexcept { return size() == 0; } + + // [span.elem], span element access + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + constexpr reference operator[](size_type idx) const noexcept + { + Expects(idx < size()); + return data()[idx]; + } + + constexpr reference front() const noexcept + { + Expects(size() > 0); + return data()[0]; + } + + constexpr reference back() const noexcept + { + Expects(size() > 0); + return data()[size() - 1]; + } + + constexpr pointer data() const noexcept { return storage_.data(); } + + // [span.iter], span iterator support + constexpr iterator begin() const noexcept + { + const auto data = storage_.data(); + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + return {data, data + size(), data}; + } + + constexpr iterator end() const noexcept + { + const auto data = storage_.data(); + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + const auto endData = data + storage_.size(); + return {data, endData, endData}; + } + + constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; } + constexpr reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; } + +#ifdef _MSC_VER + // Tell MSVC how to unwrap spans in range-based-for + constexpr pointer _Unchecked_begin() const noexcept { return data(); } + constexpr pointer _Unchecked_end() const noexcept + { + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + return data() + size(); + } +#endif // _MSC_VER + +private: + // Needed to remove unnecessary null check in subspans + struct KnownNotNull + { + pointer p; + }; + + // this implementation detail class lets us take advantage of the + // empty base class optimization to pay for only storage of a single + // pointer in the case of fixed-size spans + template + class storage_type : public ExtentType + { + public: + // KnownNotNull parameter is needed to remove unnecessary null check + // in subspans and constructors from arrays + template + constexpr storage_type(KnownNotNull data, OtherExtentType ext) + : ExtentType(ext), data_(data.p) + { + Expects(ExtentType::size() != dynamic_extent); + } + + template + constexpr storage_type(pointer data, OtherExtentType ext) : ExtentType(ext), data_(data) + { + Expects(ExtentType::size() != dynamic_extent); + Expects(data || ExtentType::size() == 0); + } + + constexpr pointer data() const noexcept { return data_; } + + private: + pointer data_; + }; + + storage_type> storage_; + + // The rest is needed to remove unnecessary null check + // in subspans and constructors from arrays + constexpr span(KnownNotNull ptr, size_type count) noexcept : storage_(ptr, count) {} + + template + class subspan_selector + { + }; + + template + constexpr span + make_subspan(size_type offset, size_type count, subspan_selector) const noexcept + { + const span tmp(*this); + return tmp.subspan(offset, count); + } + + // clang-format off + GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + constexpr span + make_subspan(size_type offset, size_type count, subspan_selector) const noexcept + { + Expects(size() >= offset); + + if (count == dynamic_extent) { return {KnownNotNull{data() + offset}, size() - offset}; } + + Expects(size() - offset >= count); + return {KnownNotNull{data() + offset}, count}; + } +}; + +#if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L)) + +// Deduction Guides +template +span(Type (&)[Extent]) -> span; + +template +span(std::array&) -> span; + +template +span(const std::array&) -> span; + +template ().data())>> +span(Container&) -> span; + +template ().data())>> +span(const Container&) -> span; + +#endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) ) + +#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND) +template +constexpr const typename span::size_type span::extent; +#endif + +namespace details +{ + // if we only supported compilers with good constexpr support then + // this pair of classes could collapse down to a constexpr function + + // we should use a narrow_cast<> to go to std::size_t, but older compilers may not see it as + // constexpr + // and so will fail compilation of the template + template + struct calculate_byte_size : std::integral_constant + { + static_assert(Extent < dynamic_extent / sizeof(ElementType), "Size is too big."); + }; + + template + struct calculate_byte_size + : std::integral_constant + { + }; +} // namespace details + +// [span.objectrep], views of object representation +template +span::value> +as_bytes(span s) noexcept +{ + using type = span::value>; + + // clang-format off + GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on + return type{reinterpret_cast(s.data()), s.size_bytes()}; +} + +template ::value, int> = 0> +span::value> +as_writable_bytes(span s) noexcept +{ + using type = span::value>; + + // clang-format off + GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on + return type{reinterpret_cast(s.data()), s.size_bytes()}; +} + +} // namespace gsl + +#if defined(_MSC_VER) && !defined(__clang__) + +#pragma warning(pop) +#endif // _MSC_VER + +#if defined(__GNUC__) && __GNUC__ > 6 +#pragma GCC diagnostic pop +#endif // __GNUC__ > 6 + +#endif // GSL_SPAN_H blob - /dev/null blob + 5feb2b868b132ed4e51c73e78b15967f07422afa (mode 644) --- /dev/null +++ 3party/gsl/span_ext @@ -0,0 +1,212 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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_SPAN_EXT_H +#define GSL_SPAN_EXT_H + +/////////////////////////////////////////////////////////////////////////////// +// +// File: span_ext +// Purpose: continue offering features that have been cut from the official +// implementation of span. +// While modernizing gsl::span a number of features needed to be removed to +// be compliant with the design of std::span +// +/////////////////////////////////////////////////////////////////////////////// + +#include // GSL_KERNEL_MODE +#include // for narrow_cast, narrow + +#include // for ptrdiff_t, size_t +#include + +#ifndef GSL_KERNEL_MODE +#include // for lexicographical_compare +#endif // GSL_KERNEL_MODE + +namespace gsl +{ + +// [span.views.constants], constants +constexpr const std::size_t dynamic_extent = narrow_cast(-1); + +template +class span; + +// std::equal and std::lexicographical_compare are not /kernel compatible +// so all comparison operators must be removed for kernel mode. +#ifndef GSL_KERNEL_MODE + +// [span.comparison], span comparison operators +template +constexpr bool operator==(span l, span r) +{ + return std::equal(l.begin(), l.end(), r.begin(), r.end()); +} + +template +constexpr bool operator!=(span l, span r) +{ + return !(l == r); +} + +template +constexpr bool operator<(span l, span r) +{ + return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); +} + +template +constexpr bool operator<=(span l, span r) +{ + return !(l > r); +} + +template +constexpr bool operator>(span l, span r) +{ + return r < l; +} + +template +constexpr bool operator>=(span l, span r) +{ + return !(l < r); +} + +#endif // GSL_KERNEL_MODE + +// +// make_span() - Utility functions for creating spans +// +template +constexpr span make_span(ElementType* ptr, typename span::size_type count) +{ + return span(ptr, count); +} + +template +constexpr span make_span(ElementType* firstElem, ElementType* lastElem) +{ + return span(firstElem, lastElem); +} + +template +constexpr span make_span(ElementType (&arr)[N]) noexcept +{ + return span(arr); +} + +template +constexpr span make_span(Container& cont) +{ + return span(cont); +} + +template +constexpr span make_span(const Container& cont) +{ + return span(cont); +} + +template +constexpr span make_span(Ptr& cont, std::size_t count) +{ + return span(cont, count); +} + +template +constexpr span make_span(Ptr& cont) +{ + return span(cont); +} + +// Specialization of gsl::at for span +template +constexpr ElementType& at(span s, index i) +{ + // No bounds checking here because it is done in span::operator[] called below + Ensures(i >= 0); + return s[narrow_cast(i)]; +} + +// [span.obs] Free observer functions +template +constexpr std::ptrdiff_t ssize(const span& s) noexcept +{ + return static_cast(s.size()); +} + +// [span.iter] Free functions for begin/end functions +template +constexpr typename span::iterator +begin(const span& s) noexcept +{ + return s.begin(); +} + +template +constexpr typename span::iterator +end(const span& s) noexcept +{ + return s.end(); +} + +template +constexpr typename span::reverse_iterator +rbegin(const span& s) noexcept +{ + return s.rbegin(); +} + +template +constexpr typename span::reverse_iterator +rend(const span& s) noexcept +{ + return s.rend(); +} + +template +constexpr typename span::iterator +cbegin(const span& s) noexcept +{ + return s.begin(); +} + +template +constexpr typename span::iterator +cend(const span& s) noexcept +{ + return s.end(); +} + +template +constexpr typename span::reverse_iterator +crbegin(const span& s) noexcept +{ + return s.rbegin(); +} + +template +constexpr typename span::reverse_iterator +crend(const span& s) noexcept +{ + return s.rend(); +} + +} // namespace gsl + +#endif // GSL_SPAN_EXT_H blob - /dev/null blob + bcc672af097c1a42412b774a8ad140394d65e217 (mode 644) --- /dev/null +++ 3party/gsl/string_span @@ -0,0 +1,759 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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_STRING_SPAN_H +#define GSL_STRING_SPAN_H + +#include // for Ensures, Expects +#include // for operator!=, operator==, dynamic_extent +#include // for narrow_cast + +#include // for equal, lexicographical_compare +#include // for array +#include // for size_t, nullptr_t +#include // for PTRDIFF_MAX +#include +#include // for basic_string, allocator, char_traits +#include // for declval, is_convertible, enable_if_t, add_... + +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) + +// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool. +#pragma warning(disable : 26446) // TODO: bug in parser - attributes and templates +#pragma warning(disable : 26481) // TODO: suppress does not work inside templates sometimes +#pragma warning(disable : 4996) // use of functions & classes marked [[deprecated]] +#endif // _MSC_VER + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +namespace gsl +{ +// +// czstring and wzstring +// +// These are "tag" typedefs for C-style strings (i.e. null-terminated character arrays) +// that allow static analysis to help find bugs. +// +// There are no additional features/semantics that we can find a way to add inside the +// type system for these types that will not either incur significant runtime costs or +// (sometimes needlessly) break existing programs when introduced. +// + +template +using basic_zstring = CharT*; + +using czstring = basic_zstring; + +using cwzstring = basic_zstring; + +using cu16zstring = basic_zstring; + +using cu32zstring = basic_zstring; + +using zstring = basic_zstring; + +using wzstring = basic_zstring; + +using u16zstring = basic_zstring; + +using u32zstring = basic_zstring; + +namespace details +{ + template + [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see " + "isocpp/CppCoreGuidelines PR#1680")]] constexpr std::size_t + string_length(const CharT* str, std::size_t n) + { + if (str == nullptr || n == dynamic_extent) return 0; + + const span str_span{str, n}; + + std::size_t len = 0; + while (len < n && str_span[len]) len++; + + return len; + } +} // namespace details + +// +// ensure_sentinel() +// +// Provides a way to obtain an span from a contiguous sequence +// that ends with a (non-inclusive) sentinel value. +// +// Will fail-fast if sentinel cannot be found before max elements are examined. +// +template +[[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see " + "isocpp/CppCoreGuidelines PR#1680")]] constexpr span +ensure_sentinel(T* seq, std::size_t max = static_cast(-1)) +{ + Ensures(seq != nullptr); + + // clang-format off + GSL_SUPPRESS(f.23) // TODO: false positive // TODO: suppress does not work + // clang-format on + auto cur = seq; + Ensures(cur != nullptr); // workaround for removing the warning + + // clang-format off + GSL_SUPPRESS(bounds.1) // TODO: suppress does not work + // clang-format on + while (static_cast(cur - seq) < max && *cur != Sentinel) ++cur; + Ensures(*cur == Sentinel); + return {seq, static_cast(cur - seq)}; +} + +// +// ensure_z - creates a span for a zero terminated strings. The span will not contain the zero +// termination. Will fail fast if a null-terminator cannot be found before the limit of size_type. +// +template +[[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see " + "isocpp/CppCoreGuidelines PR#1680")]] constexpr span +ensure_z(CharT* const& sz, std::size_t max = static_cast(-1)) +{ + return ensure_sentinel(sz, max); +} + +template +constexpr span ensure_z(CharT (&sz)[N]) +{ + return ensure_z(&sz[0], N); +} + +template +[[deprecated( + "string_span was removed from the C++ Core Guidelines. For more information, see " + "isocpp/CppCoreGuidelines PR#1680")]] constexpr span::type, + dynamic_extent> +ensure_z(Cont& cont) +{ + return ensure_z(cont.data(), cont.size()); +} + +template +class [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, " + "see isocpp/CppCoreGuidelines PR#1680")]] basic_string_span; + +namespace details +{ + template + 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 + 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::true_type{}; + + template + struct [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span + : is_basic_string_span_oracle>{}; +} // namespace details + +// +// string_span and relatives +// +template +class [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, " + "see isocpp/CppCoreGuidelines PR#1680")]] basic_string_span +{ +public: + using element_type = CharT; + using value_type = std::remove_cv_t; + using pointer = std::add_pointer_t; + using reference = std::add_lvalue_reference_t; + using const_reference = std::add_lvalue_reference_t>; + using impl_type = span; + + using size_type = typename impl_type::size_type; + using iterator = typename impl_type::iterator; + using reverse_iterator = typename impl_type::reverse_iterator; + + // default (empty) + constexpr basic_string_span() noexcept = default; + + // copy + constexpr basic_string_span(const basic_string_span& other) noexcept = default; + + // assign + constexpr basic_string_span& operator=(const basic_string_span& other) noexcept = default; + + constexpr basic_string_span(pointer ptr, size_type length) : span_(ptr, length) {} + constexpr basic_string_span(pointer firstElem, pointer lastElem) : span_(firstElem, lastElem) {} + + // From static arrays - if 0-terminated, remove 0 from the view + // All other containers allow 0s within the length, so we do not remove them + template + constexpr basic_string_span(element_type(&arr)[N]) : span_(remove_z(arr)) + {} + + template > + constexpr basic_string_span(std::array & arr) noexcept : span_(arr) + {} + + template > + constexpr basic_string_span(const std::array& arr) noexcept : span_(arr) + {} + + // Container signature should work for basic_string after C++17 version exists + template + // GSL_SUPPRESS(bounds.4) // TODO: parser bug + constexpr basic_string_span(std::basic_string & str) + : span_(&str[0], str.length()) + {} + + template + constexpr basic_string_span(const std::basic_string& str) + : span_(&str[0], str.length()) + {} + + // from containers. Containers must have a pointer type and data() function signatures + template ::value && + std::is_convertible::value && + std::is_convertible().data())>::value>> + constexpr basic_string_span(Container & cont) : span_(cont) + {} + + template ::value && + std::is_convertible::value && + std::is_convertible().data())>::value>> + constexpr basic_string_span(const Container& cont) : span_(cont) + {} + + // from string_span + template < + class OtherValueType, std::size_t OtherExtent, + class = std::enable_if_t::impl_type, impl_type>::value>> + constexpr basic_string_span(basic_string_span other) + : span_(other.data(), other.length()) + {} + + template + constexpr basic_string_span first() const + { + return {span_.template first()}; + } + + constexpr basic_string_span first(size_type count) const + { + return {span_.first(count)}; + } + + template + constexpr basic_string_span last() const + { + return {span_.template last()}; + } + + constexpr basic_string_span last(size_type count) const + { + return {span_.last(count)}; + } + + template + constexpr basic_string_span subspan() const + { + return {span_.template subspan()}; + } + + constexpr basic_string_span subspan( + size_type offset, size_type count = dynamic_extent) const + { + return {span_.subspan(offset, count)}; + } + + constexpr reference operator[](size_type idx) const { return span_[idx]; } + constexpr reference operator()(size_type idx) const { return span_[idx]; } + + constexpr pointer data() const { return span_.data(); } + + constexpr size_type length() const noexcept { return span_.size(); } + constexpr size_type size() const noexcept { return span_.size(); } + constexpr size_type size_bytes() const noexcept { return span_.size_bytes(); } + constexpr size_type length_bytes() const noexcept { return span_.length_bytes(); } + constexpr bool empty() const noexcept { return size() == 0; } + + constexpr iterator begin() const noexcept { return span_.begin(); } + constexpr iterator end() const noexcept { return span_.end(); } + + constexpr reverse_iterator rbegin() const noexcept { return span_.rbegin(); } + constexpr reverse_iterator rend() const noexcept { return span_.rend(); } + +private: + static constexpr impl_type remove_z(pointer const& sz, std::size_t max) + { + return impl_type(sz, details::string_length(sz, max)); + } + + template + static constexpr impl_type remove_z(element_type(&sz)[N]) + { + return remove_z(&sz[0], N); + } + + impl_type span_; +}; + +template +using string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_string_span; + +template +using cstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_string_span; + +template +using wstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_string_span; + +template +using cwstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_string_span; + +template +using u16string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_string_span; + +template +using cu16string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_string_span; + +template +using u32string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_string_span; + +template +using cu32string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_string_span; + +// +// to_string() allow (explicit) conversions from string_span to string +// + +template +constexpr std::basic_string::type> +to_string(basic_string_span view) +{ + return {view.data(), narrow_cast(view.length())}; +} + +template , + typename Allocator = std::allocator, typename gCharT, std::size_t Extent> +constexpr std::basic_string +to_basic_string(basic_string_span view) +{ + return {view.data(), narrow_cast(view.length())}; +} + +template +constexpr basic_string_span::value> +as_bytes(basic_string_span s) noexcept +{ + // clang-format off + GSL_SUPPRESS(type.1) + // clang-format on + return {reinterpret_cast(s.data()), s.size_bytes()}; +} + +template ::value>> +constexpr basic_string_span::value> +as_writable_bytes(basic_string_span s) noexcept +{ + // clang-format off + GSL_SUPPRESS(type.1) + // clang-format on + return {reinterpret_cast(s.data()), s.size_bytes()}; +} + +// zero-terminated string span, used to convert +// zero-terminated spans to legacy strings +template +class [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, " + "see isocpp/CppCoreGuidelines PR#1680")]] basic_zstring_span +{ +public: + using value_type = CharT; + using const_value_type = std::add_const_t; + + using pointer = std::add_pointer_t; + using const_pointer = std::add_pointer_t; + + using zstring_type = basic_zstring; + using const_zstring_type = basic_zstring; + + using impl_type = span; + using string_span_type = basic_string_span; + + constexpr basic_zstring_span(impl_type s) : span_(s) + { + // expects a zero-terminated span + Expects(s.size() > 0); + Expects(s[s.size() - 1] == value_type{}); + } + + // copy + constexpr basic_zstring_span(const basic_zstring_span& other) = default; + + // move + constexpr basic_zstring_span(basic_zstring_span && other) = default; + + // assign + constexpr basic_zstring_span& operator=(const basic_zstring_span& other) = default; + + // move assign + constexpr basic_zstring_span& operator=(basic_zstring_span&& other) = default; + + constexpr bool empty() const noexcept { return false; } + + constexpr string_span_type as_string_span() const noexcept + { + return {span_.data(), span_.size() - 1}; + } + constexpr string_span_type ensure_z() const { return gsl::ensure_z(span_); } + + constexpr const_zstring_type assume_z() const noexcept { return span_.data(); } + +private: + impl_type span_; +}; + +template +using zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_zstring_span; + +template +using wzstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_zstring_span; + +template +using u16zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_zstring_span; + +template +using u32zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_zstring_span; + +template +using czstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_zstring_span; + +template +using cwzstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " + "information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_zstring_span; + +template +using cu16zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For " + "more information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_zstring_span; + +template +using cu32zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For " + "more information, see isocpp/CppCoreGuidelines PR#1680")]] = + basic_zstring_span; + +// operator == +template ::value || + std::is_convertible>>::value>> +bool operator==(const gsl::basic_string_span& one, const T& other) +{ + const gsl::basic_string_span> tmp(other); + return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end()); +} + +template ::value && + std::is_convertible>>::value>> +bool operator==(const T& one, const gsl::basic_string_span& other) +{ + const gsl::basic_string_span> tmp(one); + return std::equal(tmp.begin(), tmp.end(), other.begin(), other.end()); +} + +// operator != +template , Extent>>::value>> +bool operator!=(gsl::basic_string_span one, const T& other) +{ + return !(one == other); +} + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename = std::enable_if_t< + std::is_convertible, Extent>>::value && + !gsl::details::is_basic_string_span::value>> +bool operator!=(const T& one, gsl::basic_string_span other) +{ + return !(one == other); +} + +// operator< +template , Extent>>::value>> +bool operator<(gsl::basic_string_span one, const T& other) +{ + const gsl::basic_string_span, Extent> tmp(other); + return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end()); +} + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename = std::enable_if_t< + std::is_convertible, Extent>>::value && + !gsl::details::is_basic_string_span::value>> +bool operator<(const T& one, gsl::basic_string_span other) +{ + gsl::basic_string_span, Extent> tmp(one); + return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end()); +} + +#ifndef _MSC_VER + +// VS treats temp and const containers as convertible to basic_string_span, +// so the cases below are already covered by the previous operators + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename DataType = typename T::value_type, + typename = std::enable_if_t< + !gsl::details::is_span::value && !gsl::details::is_basic_string_span::value && + std::is_convertible::value && + std::is_same().size(), *std::declval().data())>, + DataType>::value>> +bool operator<(gsl::basic_string_span one, const T& other) +{ + gsl::basic_string_span, Extent> tmp(other); + return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end()); +} + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename DataType = typename T::value_type, + typename = std::enable_if_t< + !gsl::details::is_span::value && !gsl::details::is_basic_string_span::value && + std::is_convertible::value && + std::is_same().size(), *std::declval().data())>, + DataType>::value>> +bool operator<(const T& one, gsl::basic_string_span other) +{ + gsl::basic_string_span, Extent> tmp(one); + return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end()); +} +#endif + +// operator <= +template , Extent>>::value>> +bool operator<=(gsl::basic_string_span one, const T& other) +{ + return !(other < one); +} + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename = std::enable_if_t< + std::is_convertible, Extent>>::value && + !gsl::details::is_basic_string_span::value>> +bool operator<=(const T& one, gsl::basic_string_span other) +{ + return !(other < one); +} + +#ifndef _MSC_VER + +// VS treats temp and const containers as convertible to basic_string_span, +// so the cases below are already covered by the previous operators + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename DataType = typename T::value_type, + typename = std::enable_if_t< + !gsl::details::is_span::value && !gsl::details::is_basic_string_span::value && + std::is_convertible::value && + std::is_same().size(), *std::declval().data())>, + DataType>::value>> +bool operator<=(gsl::basic_string_span one, const T& other) +{ + return !(other < one); +} + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename DataType = typename T::value_type, + typename = std::enable_if_t< + !gsl::details::is_span::value && !gsl::details::is_basic_string_span::value && + std::is_convertible::value && + std::is_same().size(), *std::declval().data())>, + DataType>::value>> +bool operator<=(const T& one, gsl::basic_string_span other) +{ + return !(other < one); +} +#endif + +// operator> +template , Extent>>::value>> +bool operator>(gsl::basic_string_span one, const T& other) +{ + return other < one; +} + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename = std::enable_if_t< + std::is_convertible, Extent>>::value && + !gsl::details::is_basic_string_span::value>> +bool operator>(const T& one, gsl::basic_string_span other) +{ + return other < one; +} + +#ifndef _MSC_VER + +// VS treats temp and const containers as convertible to basic_string_span, +// so the cases below are already covered by the previous operators + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename DataType = typename T::value_type, + typename = std::enable_if_t< + !gsl::details::is_span::value && !gsl::details::is_basic_string_span::value && + std::is_convertible::value && + std::is_same().size(), *std::declval().data())>, + DataType>::value>> +bool operator>(gsl::basic_string_span one, const T& other) +{ + return other < one; +} + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename DataType = typename T::value_type, + typename = std::enable_if_t< + !gsl::details::is_span::value && !gsl::details::is_basic_string_span::value && + std::is_convertible::value && + std::is_same().size(), *std::declval().data())>, + DataType>::value>> +bool operator>(const T& one, gsl::basic_string_span other) +{ + return other < one; +} +#endif + +// operator >= +template , Extent>>::value>> +bool operator>=(gsl::basic_string_span one, const T& other) +{ + return !(one < other); +} + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename = std::enable_if_t< + std::is_convertible, Extent>>::value && + !gsl::details::is_basic_string_span::value>> +bool operator>=(const T& one, gsl::basic_string_span other) +{ + return !(one < other); +} + +#ifndef _MSC_VER + +// VS treats temp and const containers as convertible to basic_string_span, +// so the cases below are already covered by the previous operators + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename DataType = typename T::value_type, + typename = std::enable_if_t< + !gsl::details::is_span::value && !gsl::details::is_basic_string_span::value && + std::is_convertible::value && + std::is_same().size(), *std::declval().data())>, + DataType>::value>> +bool operator>=(gsl::basic_string_span one, const T& other) +{ + return !(one < other); +} + +template < + typename CharT, std::size_t Extent = dynamic_extent, typename T, + typename DataType = typename T::value_type, + typename = std::enable_if_t< + !gsl::details::is_span::value && !gsl::details::is_basic_string_span::value && + std::is_convertible::value && + std::is_same().size(), *std::declval().data())>, + DataType>::value>> +bool operator>=(const T& one, gsl::basic_string_span other) +{ + return !(one < other); +} +#endif +} // namespace gsl + +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) + +#endif // _MSC_VER + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif +#endif // GSL_STRING_SPAN_H blob - /dev/null blob + a215bad108b8e485bdeda78a305da14da45b59e0 (mode 644) --- /dev/null +++ 3party/gsl/util @@ -0,0 +1,160 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// 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 // for Expects + +#include +#include // for ptrdiff_t, size_t +#include // for initializer_list +#include // for is_signed, integral_constant +#include // for exchange, forward + +#if defined(__has_include) && __has_include() +#include +#if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L +#include +#endif // __cpp_lib_span >= 202002L +#endif //__has_include() + +#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 final_action +{ +public: + static_assert(!std::is_reference::value && !std::is_const::value && + !std::is_volatile::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 +GSL_NODISCARD final_action::type>::type> +finally(F&& f) noexcept +{ + return final_action::type>::type>( + std::forward(f)); +} + +// narrow_cast(): a searchable way to do narrowing casts of values +template +// clang-format off +GSL_SUPPRESS(type.1) // NO-FORMAT: attribute + // clang-format on + constexpr T narrow_cast(U&& u) noexcept +{ + return static_cast(std::forward(u)); +} + +// +// at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector +// +template +// 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(N)); + return arr[narrow_cast(i)]; +} + +template +// 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(cont.size())); + using size_type = decltype(cont.size()); + return cont[narrow_cast(i)]; +} + +template +// clang-format off +GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute + // clang-format on + constexpr T at(const std::initializer_list cont, const index i) +{ + Expects(i >= 0 && i < narrow_cast(cont.size())); + return *(cont.begin() + i); +} + +#if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L +template +constexpr auto at(std::span sp, const index i) -> decltype(sp[sp.size()]) +{ + Expects(i >= 0 && i < narrow_cast(sp.size())); + return sp[gsl::narrow_cast(i)]; +} +#endif // __cpp_lib_span >= 202002L +} // namespace gsl + +#if defined(_MSC_VER) && !defined(__clang__) + +#pragma warning(pop) + +#endif // _MSC_VER + +#endif // GSL_UTIL_H