mirror of
				https://github.com/RetroDECK/Duckstation.git
				synced 2025-04-10 19:15:14 +00:00 
			
		
		
		
	dep: Add GSL 4.0.0
This commit is contained in:
		
							parent
							
								
									e87f64faed
								
							
						
					
					
						commit
						9c41126298
					
				|  | @ -1,4 +1,5 @@ | |||
| add_subdirectory(fmt) | ||||
| add_subdirectory(gsl) | ||||
| add_subdirectory(glad) | ||||
| add_subdirectory(stb) | ||||
| add_subdirectory(zlib) | ||||
|  |  | |||
							
								
								
									
										49
									
								
								dep/gsl/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								dep/gsl/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | |||
| cmake_minimum_required(VERSION 3.1.3...3.16) | ||||
| 
 | ||||
| list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") | ||||
| include(guidelineSupportLibrary) | ||||
| 
 | ||||
| project(GSL | ||||
|     VERSION 4.0.0 | ||||
|     LANGUAGES CXX | ||||
| ) | ||||
| 
 | ||||
| # Must include after the project call due to GNUInstallDirs requiring a language be enabled (IE. CXX) | ||||
| include(GNUInstallDirs) | ||||
| 
 | ||||
| # Creates a library GSL which is an interface (header files only) | ||||
| add_library(GSL INTERFACE) | ||||
| 
 | ||||
| # NOTE: If you want to use GSL prefer to link against GSL using this alias target | ||||
| # EX: | ||||
| #   target_link_libraries(foobar PRIVATE Microsoft.GSL::GSL) | ||||
| # | ||||
| # Add Microsoft.GSL::GSL alias for GSL so that dependents can be agnostic about | ||||
| # whether GSL was added via `add_subdirectory` or `find_package` | ||||
| add_library(Microsoft.GSL::GSL ALIAS GSL) | ||||
| 
 | ||||
| # Determine whether this is a standalone project or included by other projects | ||||
| set(GSL_STANDALONE_PROJECT OFF) | ||||
| if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) | ||||
|     set(GSL_STANDALONE_PROJECT ON) | ||||
| endif() | ||||
| 
 | ||||
| ### Project options | ||||
| option(GSL_INSTALL "Generate and install GSL target" ${GSL_STANDALONE_PROJECT}) | ||||
| option(GSL_TEST "Build and perform GSL tests" ${GSL_STANDALONE_PROJECT}) | ||||
| 
 | ||||
| # This GSL implementation generally assumes a platform that implements C++14 support. | ||||
| set(gsl_min_cxx_standard "14") | ||||
| 
 | ||||
| if (GSL_STANDALONE_PROJECT) | ||||
|     gsl_set_default_cxx_standard(${gsl_min_cxx_standard}) | ||||
| else() | ||||
|     gsl_client_set_cxx_standard(${gsl_min_cxx_standard}) | ||||
| endif() | ||||
| 
 | ||||
| # Setup include directory | ||||
| add_subdirectory(include) | ||||
| 
 | ||||
| # Add natvis file | ||||
| gsl_add_native_visualizer_support() | ||||
| 
 | ||||
							
								
								
									
										59
									
								
								dep/gsl/GSL.natvis
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								dep/gsl/GSL.natvis
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!--  | ||||
|     This will make GitHub and some editors recognize this code as XML:  | ||||
|     vim: syntax=xml | ||||
| --> | ||||
| <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> | ||||
|     <!-- These types are from the gsl_assert header. --> | ||||
|     <Type Name="gsl::fail_fast"> | ||||
|         <!-- na hides the address, otherwise it would appear as 0x.... "Message" --> | ||||
|         <DisplayString>{_Data._What,nasb}</DisplayString> | ||||
|     </Type> | ||||
| 
 | ||||
|     <!-- These types are from the gsl_util header. --> | ||||
|     <Type Name="gsl::final_action<*>"> | ||||
|         <DisplayString>{{ invoke = {invoke_}, action = {f_} }}</DisplayString> | ||||
|         <Expand> | ||||
|             <Item Name="[invoke]">invoke_</Item> | ||||
|             <Item Name="[callback]">f_</Item> | ||||
|         </Expand> | ||||
|     </Type> | ||||
| 
 | ||||
|     <Type Name="gsl::span<*, *>"> | ||||
|         <DisplayString>{{ extent = {storage_.size_} }}</DisplayString> | ||||
|         <Expand> | ||||
|             <ArrayItems> | ||||
|                 <Size>storage_.size_</Size> | ||||
|                 <ValuePointer>storage_.data_</ValuePointer> | ||||
|             </ArrayItems> | ||||
|         </Expand> | ||||
|     </Type> | ||||
| 
 | ||||
|     <Type Name="gsl::basic_string_span<*, *>"> | ||||
|         <DisplayString>{span_.storage_.data_,[span_.storage_.size_]na}</DisplayString> | ||||
|         <Expand> | ||||
|             <Item Name="[size]">span_.storage_.size_</Item> | ||||
|             <ArrayItems> | ||||
|                 <Size>span_.storage_.size_</Size> | ||||
|                 <ValuePointer>span_.storage_.data_</ValuePointer> | ||||
|             </ArrayItems> | ||||
|         </Expand> | ||||
|     </Type> | ||||
| 
 | ||||
|     <Type Name="gsl::basic_zstring_span<*, *>"> | ||||
|         <DisplayString>{span_.storage_.data_,[span_.storage_.size_]na}</DisplayString> | ||||
|         <Expand> | ||||
|             <Item Name="[size]">span_.storage_.size_</Item> | ||||
|             <ArrayItems> | ||||
|                 <Size>span_.storage_.size_</Size> | ||||
|                 <ValuePointer>span_.storage_.data_</ValuePointer> | ||||
|             </ArrayItems> | ||||
|         </Expand> | ||||
|     </Type> | ||||
| 
 | ||||
|     <!-- These types are from the gsl header. --> | ||||
|     <Type Name="gsl::not_null<*>"> | ||||
|         <!-- We can always dereference this since it's an invariant. --> | ||||
|         <DisplayString>value = {*ptr_}</DisplayString> | ||||
|     </Type> | ||||
| </AutoVisualizer>   | ||||
							
								
								
									
										21
									
								
								dep/gsl/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								dep/gsl/LICENSE
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| Copyright (c) 2015 Microsoft Corporation. All rights reserved.  | ||||
|   | ||||
| This code is licensed under the MIT License (MIT).  | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy  | ||||
| of this software and associated documentation files (the "Software"), to deal  | ||||
| in the Software without restriction, including without limitation the rights  | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies  | ||||
| of the Software, and to permit persons to whom the Software is furnished to do  | ||||
| so, subject to the following conditions:  | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in all  | ||||
| copies or substantial portions of the Software.  | ||||
| 
 | ||||
| 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.  | ||||
							
								
								
									
										85
									
								
								dep/gsl/cmake/guidelineSupportLibrary.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								dep/gsl/cmake/guidelineSupportLibrary.cmake
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,85 @@ | |||
| # This cmake module is meant to hold helper functions/macros | ||||
| # that make maintaining the cmake build system much easier. | ||||
| # This is especially helpful since gsl needs to provide coverage | ||||
| # for multiple versions of cmake. | ||||
| # | ||||
| # Any functions/macros should have a gsl_* prefix to avoid problems | ||||
| if (CMAKE_VERSION VERSION_GREATER 3.10 OR CMAKE_VERSION VERSION_EQUAL 3.10) | ||||
|     include_guard() | ||||
| else() | ||||
|     if (DEFINED guideline_support_library_include_guard) | ||||
|         return() | ||||
|     endif() | ||||
|     set(guideline_support_library_include_guard ON) | ||||
| endif() | ||||
| 
 | ||||
| # Necessary for 'write_basic_package_version_file' | ||||
| include(CMakePackageConfigHelpers) | ||||
| 
 | ||||
| function(gsl_set_default_cxx_standard min_cxx_standard) | ||||
|     set(GSL_CXX_STANDARD "${min_cxx_standard}" CACHE STRING "Use c++ standard") | ||||
| 
 | ||||
|     set(GSL_CXX_STD "cxx_std_${GSL_CXX_STANDARD}") | ||||
| 
 | ||||
|     if (MSVC) | ||||
|         set(GSL_CXX_STD_OPT "-std:c++${GSL_CXX_STANDARD}") | ||||
|     else() | ||||
|         set(GSL_CXX_STD_OPT "-std=c++${GSL_CXX_STANDARD}") | ||||
|     endif() | ||||
| 
 | ||||
|     # when minimum version required is 3.8.0 remove if below | ||||
|     # both branches do exactly the same thing | ||||
|     if (CMAKE_VERSION VERSION_LESS 3.7.9) | ||||
|         include(CheckCXXCompilerFlag) | ||||
|         CHECK_CXX_COMPILER_FLAG("${GSL_CXX_STD_OPT}" COMPILER_SUPPORTS_CXX_STANDARD) | ||||
| 
 | ||||
|         if(COMPILER_SUPPORTS_CXX_STANDARD) | ||||
|             target_compile_options(GSL INTERFACE "${GSL_CXX_STD_OPT}") | ||||
|         else() | ||||
|             message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no c++${GSL_CXX_STANDARD} support. Please use a different C++ compiler.") | ||||
|         endif() | ||||
|     else() | ||||
|         target_compile_features(GSL INTERFACE "${GSL_CXX_STD}") | ||||
|         # on *nix systems force the use of -std=c++XX instead of -std=gnu++XX (default) | ||||
|         set(CMAKE_CXX_EXTENSIONS OFF) | ||||
|     endif() | ||||
| endfunction() | ||||
| 
 | ||||
| # The best way for a project to specify the GSL's C++ standard is by the client specifying | ||||
| # the CMAKE_CXX_STANDARD. However, this isn't always ideal. Since the CMAKE_CXX_STANDARD is | ||||
| # tied to the cmake version. And many projects have low cmake minimums. | ||||
| # | ||||
| # So provide an alternative approach in case that doesn't work. | ||||
| function(gsl_client_set_cxx_standard min_cxx_standard) | ||||
|     if (DEFINED CMAKE_CXX_STANDARD) | ||||
|         if (${CMAKE_CXX_STANDARD} VERSION_LESS ${min_cxx_standard}) | ||||
|             message(FATAL_ERROR "GSL: Requires at least CXX standard ${min_cxx_standard}, user provided ${CMAKE_CXX_STANDARD}") | ||||
|         endif() | ||||
| 
 | ||||
|         # Set the GSL standard to what the client desires | ||||
|         set(GSL_CXX_STANDARD "${CMAKE_CXX_STANDARD}" PARENT_SCOPE) | ||||
| 
 | ||||
|         # Exit out early to avoid extra unneccessary work | ||||
|         return() | ||||
|     endif() | ||||
| 
 | ||||
|     # Otherwise pick a reasonable default | ||||
|     gsl_set_default_cxx_standard(${min_cxx_standard}) | ||||
| endfunction() | ||||
| 
 | ||||
| # Adding the GSL.natvis files improves the debugging experience for users of this library. | ||||
| function(gsl_add_native_visualizer_support) | ||||
|     if (CMAKE_VERSION VERSION_GREATER 3.7.8) | ||||
|         if (MSVC_IDE) | ||||
|             option(GSL_VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE) | ||||
|         else() | ||||
|             set(GSL_VS_ADD_NATIVE_VISUALIZERS FALSE CACHE INTERNAL "Native visualizers are Visual Studio extension" FORCE) | ||||
|         endif() | ||||
| 
 | ||||
|         # add natvis file to the library so it will automatically be loaded into Visual Studio | ||||
|         if(GSL_VS_ADD_NATIVE_VISUALIZERS) | ||||
|             target_sources(GSL INTERFACE $<BUILD_INTERFACE:${GSL_SOURCE_DIR}/GSL.natvis>) | ||||
|         endif() | ||||
|     endif() | ||||
| endfunction() | ||||
| 
 | ||||
							
								
								
									
										20
									
								
								dep/gsl/include/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								dep/gsl/include/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| 
 | ||||
| # Add include folders to the library and targets that consume it | ||||
| # the SYSTEM keyword suppresses warnings for users of the library | ||||
| # | ||||
| # By adding this directory as an include directory the user gets a | ||||
| # namespace effect. | ||||
| # | ||||
| # IE: | ||||
| #   #include <gsl/gsl> | ||||
| if(GSL_STANDALONE_PROJECT) | ||||
|     target_include_directories(GSL INTERFACE | ||||
|         $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> | ||||
|         $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> | ||||
|     ) | ||||
| else() | ||||
|     target_include_directories(GSL SYSTEM INTERFACE | ||||
|         $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> | ||||
|         $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> | ||||
|     ) | ||||
| endif() | ||||
							
								
								
									
										63
									
								
								dep/gsl/include/gsl/algorithm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								dep/gsl/include/gsl/algorithm
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
							
								
								
									
										136
									
								
								dep/gsl/include/gsl/assert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								dep/gsl/include/gsl/assert
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 <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 | ||||
							
								
								
									
										213
									
								
								dep/gsl/include/gsl/byte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								dep/gsl/include/gsl/byte
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
							
								
								
									
										32
									
								
								dep/gsl/include/gsl/gsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								dep/gsl/include/gsl/gsl
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 <gsl/algorithm>   // copy | ||||
| #include <gsl/assert>      // Ensures/Expects | ||||
| #include <gsl/byte>        // byte | ||||
| #include <gsl/pointers>    // owner, not_null | ||||
| #include <gsl/span>        // span | ||||
| #include <gsl/string_span> // zstring, string_span, zstring_builder... | ||||
| #include <gsl/util>        // finally()/narrow_cast()... | ||||
| 
 | ||||
| #ifdef __cpp_exceptions | ||||
| #include <gsl/narrow> // narrow() | ||||
| #endif | ||||
| 
 | ||||
| #endif // GSL_GSL_H | ||||
							
								
								
									
										4
									
								
								dep/gsl/include/gsl/gsl_algorithm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								dep/gsl/include/gsl/gsl_algorithm
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| #pragma once | ||||
| #pragma message(                                                                                   \ | ||||
|     "This header will soon be removed. Use <gsl/algorithm> instead of <gsl/gsl_algorithm>") | ||||
| #include <gsl/algorithm> | ||||
							
								
								
									
										3
									
								
								dep/gsl/include/gsl/gsl_assert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								dep/gsl/include/gsl/gsl_assert
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| #pragma once | ||||
| #pragma message("This header will soon be removed. Use <gsl/assert> instead of <gsl/gsl_assert>") | ||||
| #include <gsl/assert> | ||||
							
								
								
									
										3
									
								
								dep/gsl/include/gsl/gsl_byte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								dep/gsl/include/gsl/gsl_byte
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| #pragma once | ||||
| #pragma message("This header will soon be removed. Use <gsl/byte> instead of <gsl/gsl_byte>") | ||||
| #include <gsl/byte> | ||||
							
								
								
									
										3
									
								
								dep/gsl/include/gsl/gsl_narrow
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								dep/gsl/include/gsl/gsl_narrow
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| #pragma once | ||||
| #pragma message("This header will soon be removed. Use <gsl/narrow> instead of <gsl/gsl_narrow>") | ||||
| #include <gsl/narrow> | ||||
							
								
								
									
										3
									
								
								dep/gsl/include/gsl/gsl_util
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								dep/gsl/include/gsl/gsl_util
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| #pragma once | ||||
| #pragma message("This header will soon be removed. Use <gsl/util> instead of <gsl/gsl_util>") | ||||
| #include <gsl/util> | ||||
							
								
								
									
										71
									
								
								dep/gsl/include/gsl/narrow
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								dep/gsl/include/gsl/narrow
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 <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, typename std::enable_if<std::is_arithmetic<T>::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<T>::value != std::is_signed<U>::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<T>(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<U>(t) != u || (is_different_signedness && ((t < T{}) != (u < U{})))) | ||||
|     { | ||||
|         throw narrowing_error{}; | ||||
|     } | ||||
| 
 | ||||
|     return t; | ||||
| } | ||||
| 
 | ||||
| template <class T, class U, typename std::enable_if<!std::is_arithmetic<T>::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<T>(u); | ||||
| 
 | ||||
|     if (static_cast<U>(t) != u) | ||||
|     { | ||||
|         throw narrowing_error{}; | ||||
|     } | ||||
| 
 | ||||
|     return t; | ||||
| } | ||||
| } // namespace gsl | ||||
| #endif // GSL_NARROW_H | ||||
							
								
								
									
										323
									
								
								dep/gsl/include/gsl/pointers
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								dep/gsl/include/gsl/pointers
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 <gsl/assert> // for Ensures, Expects | ||||
| 
 | ||||
| #include <algorithm>    // for forward | ||||
| #include <cstddef>      // for ptrdiff_t, nullptr_t, size_t | ||||
| #include <memory>       // for shared_ptr, unique_ptr | ||||
| #include <system_error> // for hash | ||||
| #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) | ||||
| 
 | ||||
| namespace gsl | ||||
| { | ||||
| 
 | ||||
| namespace details | ||||
| { | ||||
|     template <typename T, typename = void> | ||||
|     struct is_comparable_to_nullptr : std::false_type | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <typename T> | ||||
|     struct is_comparable_to_nullptr< | ||||
|         T, | ||||
|         std::enable_if_t<std::is_convertible<decltype(std::declval<T>() != nullptr), bool>::value>> | ||||
|         : std::true_type | ||||
|     { | ||||
|     }; | ||||
| } // namespace details | ||||
| 
 | ||||
| // | ||||
| // GSL.owner: ownership pointers | ||||
| // | ||||
| 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 | ||||
| // | ||||
| // T must be a pointer type | ||||
| // - disallow construction from any type other than pointer type | ||||
| // | ||||
| template <class T, class = std::enable_if_t<std::is_pointer<T>::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 T> | ||||
| class not_null | ||||
| { | ||||
| public: | ||||
|     static_assert(details::is_comparable_to_nullptr<T>::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)) | ||||
|     { | ||||
|         Expects(ptr_ != nullptr); | ||||
|     } | ||||
| 
 | ||||
|     template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>> | ||||
|     constexpr not_null(T u) : ptr_(std::move(u)) | ||||
|     { | ||||
|         Expects(ptr_ != nullptr); | ||||
|     } | ||||
| 
 | ||||
|     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; | ||||
|     constexpr std::conditional_t<std::is_copy_constructible<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 <class T> | ||||
| auto make_not_null(T&& t) noexcept | ||||
| { | ||||
|     return not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)}; | ||||
| } | ||||
| 
 | ||||
| #if !defined(GSL_NO_IOSTREAMS) | ||||
| template <class T> | ||||
| std::ostream& operator<<(std::ostream& os, const not_null<T>& val) | ||||
| { | ||||
|     os << val.get(); | ||||
|     return os; | ||||
| } | ||||
| #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()) | ||||
| { | ||||
|     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()) | ||||
| { | ||||
|     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()) | ||||
| { | ||||
|     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()) | ||||
| { | ||||
|     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()) | ||||
| { | ||||
|     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()) | ||||
| { | ||||
|     return lhs.get() >= rhs.get(); | ||||
| } | ||||
| 
 | ||||
| // more unwanted operators | ||||
| template <class T, class U> | ||||
| std::ptrdiff_t operator-(const not_null<T>&, const not_null<U>&) = delete; | ||||
| template <class T> | ||||
| not_null<T> operator-(const not_null<T>&, std::ptrdiff_t) = delete; | ||||
| template <class T> | ||||
| not_null<T> operator+(const not_null<T>&, std::ptrdiff_t) = delete; | ||||
| template <class T> | ||||
| not_null<T> operator+(std::ptrdiff_t, const not_null<T>&) = delete; | ||||
| 
 | ||||
| } // namespace gsl | ||||
| 
 | ||||
| namespace std | ||||
| { | ||||
| template <class T> | ||||
| struct hash<gsl::not_null<T>> | ||||
| { | ||||
|     std::size_t operator()(const gsl::not_null<T>& value) const { return hash<T>{}(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 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)) | ||||
|     {} | ||||
| 
 | ||||
|     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) | ||||
|     {} | ||||
| 
 | ||||
|     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) | ||||
|     {} | ||||
| 
 | ||||
|     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) | ||||
|     {} | ||||
| 
 | ||||
|     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<T>& other) | ||||
|     { | ||||
|         not_null<T>::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 <class T, class U> | ||||
| std::ptrdiff_t operator-(const strict_not_null<T>&, const strict_not_null<U>&) = delete; | ||||
| template <class T> | ||||
| strict_not_null<T> operator-(const strict_not_null<T>&, std::ptrdiff_t) = delete; | ||||
| template <class T> | ||||
| strict_not_null<T> operator+(const strict_not_null<T>&, std::ptrdiff_t) = delete; | ||||
| 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 | ||||
| { | ||||
|     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)) | ||||
| 
 | ||||
| // 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>; | ||||
| 
 | ||||
| #endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) ) | ||||
| 
 | ||||
| } // namespace gsl | ||||
| 
 | ||||
| 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()); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| } // namespace std | ||||
| 
 | ||||
| #endif // GSL_POINTERS_H | ||||
							
								
								
									
										821
									
								
								dep/gsl/include/gsl/span
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										821
									
								
								dep/gsl/include/gsl/span
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 <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 | ||||
| #include <gsl/span_ext> // for span specialization of gsl::at and other span-related extensions | ||||
| #include <iterator>     // for reverse_iterator, distance, random_access_... | ||||
| #include <type_traits>  // 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 <class T> | ||||
|     struct is_span_oracle : std::false_type | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <class ElementType, std::size_t Extent> | ||||
|     struct is_span_oracle<gsl::span<ElementType, Extent>> : std::true_type | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <class T> | ||||
|     struct is_span : public is_span_oracle<std::remove_cv_t<T>> | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <class T> | ||||
|     struct is_std_array_oracle : std::false_type | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <class ElementType, std::size_t Extent> | ||||
|     struct is_std_array_oracle<std::array<ElementType, Extent>> : std::true_type | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <class T> | ||||
|     struct is_std_array : is_std_array_oracle<std::remove_cv_t<T>> | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <std::size_t From, std::size_t To> | ||||
|     struct is_allowed_extent_conversion | ||||
|         : std::integral_constant<bool, From == To || To == dynamic_extent> | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <class From, class To> | ||||
|     struct is_allowed_element_type_conversion | ||||
|         : std::integral_constant<bool, std::is_convertible<From (*)[], To (*)[]>::value> | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <class Type> | ||||
|     class span_iterator | ||||
|     { | ||||
|     public: | ||||
|         using iterator_category = std::random_access_iterator_tag; | ||||
|         using value_type = std::remove_cv_t<Type>; | ||||
|         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 Type>() 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<std::is_same<std::remove_cv_t<Type2>, value_type>::value, int> = 0> | ||||
|         constexpr difference_type operator-(const span_iterator<Type2>& 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<std::is_same<std::remove_cv_t<Type2>, value_type>::value, int> = 0> | ||||
|         constexpr bool operator==(const span_iterator<Type2>& rhs) const noexcept | ||||
|         { | ||||
|             Expects(begin_ == rhs.begin_ && end_ == rhs.end_); | ||||
|             return current_ == rhs.current_; | ||||
|         } | ||||
| 
 | ||||
|         template < | ||||
|             class Type2, | ||||
|             std::enable_if_t<std::is_same<std::remove_cv_t<Type2>, value_type>::value, int> = 0> | ||||
|         constexpr bool operator!=(const span_iterator<Type2>& rhs) const noexcept | ||||
|         { | ||||
|             return !(*this == rhs); | ||||
|         } | ||||
| 
 | ||||
|         template < | ||||
|             class Type2, | ||||
|             std::enable_if_t<std::is_same<std::remove_cv_t<Type2>, value_type>::value, int> = 0> | ||||
|         constexpr bool operator<(const span_iterator<Type2>& rhs) const noexcept | ||||
|         { | ||||
|             Expects(begin_ == rhs.begin_ && end_ == rhs.end_); | ||||
|             return current_ < rhs.current_; | ||||
|         } | ||||
| 
 | ||||
|         template < | ||||
|             class Type2, | ||||
|             std::enable_if_t<std::is_same<std::remove_cv_t<Type2>, value_type>::value, int> = 0> | ||||
|         constexpr bool operator>(const span_iterator<Type2>& rhs) const noexcept | ||||
|         { | ||||
|             return rhs < *this; | ||||
|         } | ||||
| 
 | ||||
|         template < | ||||
|             class Type2, | ||||
|             std::enable_if_t<std::is_same<std::remove_cv_t<Type2>, value_type>::value, int> = 0> | ||||
|         constexpr bool operator<=(const span_iterator<Type2>& rhs) const noexcept | ||||
|         { | ||||
|             return !(rhs < *this); | ||||
|         } | ||||
| 
 | ||||
|         template < | ||||
|             class Type2, | ||||
|             std::enable_if_t<std::is_same<std::remove_cv_t<Type2>, value_type>::value, int> = 0> | ||||
|         constexpr bool operator>=(const span_iterator<Type2>& 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 <std::size_t Ext> | ||||
|     class extent_type | ||||
|     { | ||||
|     public: | ||||
|         using size_type = std::size_t; | ||||
| 
 | ||||
|         constexpr extent_type() noexcept = default; | ||||
| 
 | ||||
|         constexpr explicit extent_type(extent_type<dynamic_extent>); | ||||
| 
 | ||||
|         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<dynamic_extent> | ||||
|     { | ||||
|     public: | ||||
|         using size_type = std::size_t; | ||||
| 
 | ||||
|         template <size_type Other> | ||||
|         constexpr explicit extent_type(extent_type<Other> 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 <std::size_t Ext> | ||||
|     constexpr extent_type<Ext>::extent_type(extent_type<dynamic_extent> ext) | ||||
|     { | ||||
|         Expects(ext.size() == Ext); | ||||
|     } | ||||
| 
 | ||||
|     template <class ElementType, std::size_t Extent, std::size_t Offset, std::size_t Count> | ||||
|     struct calculate_subspan_type | ||||
|     { | ||||
|         using type = span<ElementType, Count != dynamic_extent | ||||
|                                            ? Count | ||||
|                                            : (Extent != dynamic_extent ? Extent - Offset : Extent)>; | ||||
|     }; | ||||
| } // namespace details | ||||
| 
 | ||||
| // [span], class template span | ||||
| template <class ElementType, std::size_t Extent> | ||||
| class span | ||||
| { | ||||
| public: | ||||
|     // constants and types | ||||
|     using element_type = ElementType; | ||||
|     using value_type = std::remove_cv_t<ElementType>; | ||||
|     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<ElementType>; | ||||
|     using reverse_iterator = std::reverse_iterator<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 <bool Dependent = false, | ||||
|               // "Dependent" is needed to make "std::enable_if_t<Dependent || Extent == 0 || Extent | ||||
|               // == dynamic_extent>" SFINAE, since "std::enable_if_t<Extent == 0 || Extent == | ||||
|               // dynamic_extent>" 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 <std::size_t MyExtent = Extent, std::enable_if_t<MyExtent != dynamic_extent, int> = 0> | ||||
|     constexpr explicit span(pointer ptr, size_type count) noexcept : storage_(ptr, count) | ||||
|     { | ||||
|         Expects(count == Extent); | ||||
|     } | ||||
| 
 | ||||
|     template <std::size_t MyExtent = Extent, std::enable_if_t<MyExtent == dynamic_extent, int> = 0> | ||||
|     constexpr span(pointer ptr, size_type count) noexcept : storage_(ptr, count) | ||||
|     {} | ||||
| 
 | ||||
|     template <std::size_t MyExtent = Extent, std::enable_if_t<MyExtent != dynamic_extent, int> = 0> | ||||
|     constexpr explicit span(pointer firstElem, pointer lastElem) noexcept | ||||
|         : storage_(firstElem, narrow_cast<std::size_t>(lastElem - firstElem)) | ||||
|     { | ||||
|         Expects(lastElem - firstElem == static_cast<difference_type>(Extent)); | ||||
|     } | ||||
| 
 | ||||
|     template <std::size_t MyExtent = Extent, std::enable_if_t<MyExtent == dynamic_extent, int> = 0> | ||||
|     constexpr span(pointer firstElem, pointer lastElem) noexcept | ||||
|         : storage_(firstElem, narrow_cast<std::size_t>(lastElem - firstElem)) | ||||
|     {} | ||||
| 
 | ||||
|     template <std::size_t N, | ||||
|               std::enable_if_t<details::is_allowed_extent_conversion<N, Extent>::value, int> = 0> | ||||
|     constexpr span(element_type (&arr)[N]) noexcept | ||||
|         : storage_(KnownNotNull{arr}, details::extent_type<N>()) | ||||
|     {} | ||||
| 
 | ||||
|     template < | ||||
|         class T, std::size_t N, | ||||
|         std::enable_if_t<(details::is_allowed_extent_conversion<N, Extent>::value && | ||||
|                           details::is_allowed_element_type_conversion<T, element_type>::value), | ||||
|                          int> = 0> | ||||
|     constexpr span(std::array<T, N>& arr) noexcept | ||||
|         : storage_(KnownNotNull{arr.data()}, details::extent_type<N>()) | ||||
|     {} | ||||
| 
 | ||||
|     template <class T, std::size_t N, | ||||
|               std::enable_if_t< | ||||
|                   (details::is_allowed_extent_conversion<N, Extent>::value && | ||||
|                    details::is_allowed_element_type_conversion<const T, element_type>::value), | ||||
|                   int> = 0> | ||||
|     constexpr span(const std::array<T, N>& arr) noexcept | ||||
|         : storage_(KnownNotNull{arr.data()}, details::extent_type<N>()) | ||||
|     {} | ||||
| 
 | ||||
|     // 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 <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> | ||||
|     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> | ||||
|     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> | ||||
|     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> | ||||
|     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> | ||||
|     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> | ||||
|     constexpr explicit span(const span<OtherElementType, OtherExtent>& other) noexcept | ||||
|         : storage_(other.data(), details::extent_type<OtherExtent>(other.size())) | ||||
|     {} | ||||
| 
 | ||||
|     ~span() noexcept = default; | ||||
|     constexpr span& operator=(const span& other) noexcept = default; | ||||
| 
 | ||||
|     // [span.sub], span subviews | ||||
|     template <std::size_t Count> | ||||
|     constexpr span<element_type, Count> first() const noexcept | ||||
|     { | ||||
|         Expects(Count <= size()); | ||||
|         return span<element_type, Count>{data(), Count}; | ||||
|     } | ||||
| 
 | ||||
|     template <std::size_t Count> | ||||
|     // clang-format off | ||||
|     GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute | ||||
|         // clang-format on | ||||
|         constexpr span<element_type, Count> last() const noexcept | ||||
|     { | ||||
|         Expects(Count <= size()); | ||||
|         return span<element_type, Count>{data() + (size() - Count), Count}; | ||||
|     } | ||||
| 
 | ||||
|     template <std::size_t Offset, std::size_t Count = dynamic_extent> | ||||
|     // clang-format off | ||||
|     GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute | ||||
|         // clang-format on | ||||
|         constexpr auto subspan() const noexcept -> | ||||
|         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; | ||||
|         return type{data() + Offset, Count == dynamic_extent ? size() - Offset : Count}; | ||||
|     } | ||||
| 
 | ||||
|     constexpr span<element_type, dynamic_extent> first(size_type count) const noexcept | ||||
|     { | ||||
|         Expects(count <= size()); | ||||
|         return {data(), count}; | ||||
|     } | ||||
| 
 | ||||
|     constexpr span<element_type, dynamic_extent> last(size_type count) const noexcept | ||||
|     { | ||||
|         Expects(count <= size()); | ||||
|         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 | ||||
|     { | ||||
|         return make_subspan(offset, count, subspan_selector<Extent>{}); | ||||
|     } | ||||
| 
 | ||||
|     // [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 ExtentType> | ||||
|     class storage_type : public ExtentType | ||||
|     { | ||||
|     public: | ||||
|         // KnownNotNull parameter is needed to remove unnecessary null check | ||||
|         // in subspans and constructors from arrays | ||||
|         template <class OtherExtentType> | ||||
|         constexpr storage_type(KnownNotNull data, OtherExtentType ext) | ||||
|             : ExtentType(ext), data_(data.p) | ||||
|         { | ||||
|             Expects(ExtentType::size() != dynamic_extent); | ||||
|         } | ||||
| 
 | ||||
|         template <class OtherExtentType> | ||||
|         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<details::extent_type<Extent>> 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 <std::size_t CallerExtent> | ||||
|     class subspan_selector | ||||
|     { | ||||
|     }; | ||||
| 
 | ||||
|     template <std::size_t CallerExtent> | ||||
|     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); | ||||
|     } | ||||
| 
 | ||||
|     // clang-format off | ||||
|     GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute | ||||
|     // clang-format on | ||||
|     constexpr span<element_type, dynamic_extent> | ||||
|     make_subspan(size_type offset, size_type count, subspan_selector<dynamic_extent>) 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 <class Type, std::size_t Extent> | ||||
| span(Type (&)[Extent]) -> span<Type, Extent>; | ||||
| 
 | ||||
| template <class Type, std::size_t 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>; | ||||
| 
 | ||||
| template <class Container, | ||||
|           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>; | ||||
| 
 | ||||
| #endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) ) | ||||
| 
 | ||||
| #if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND) | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr const typename span<ElementType, Extent>::size_type span<ElementType, Extent>::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 <class ElementType, std::size_t Extent> | ||||
|     struct calculate_byte_size : std::integral_constant<std::size_t, sizeof(ElementType) * Extent> | ||||
|     { | ||||
|         static_assert(Extent < dynamic_extent / sizeof(ElementType), "Size is too big."); | ||||
|     }; | ||||
| 
 | ||||
|     template <class ElementType> | ||||
|     struct calculate_byte_size<ElementType, dynamic_extent> | ||||
|         : std::integral_constant<std::size_t, dynamic_extent> | ||||
|     { | ||||
|     }; | ||||
| } // namespace details | ||||
| 
 | ||||
| // [span.objectrep], views of object representation | ||||
| template <class ElementType, std::size_t Extent> | ||||
| span<const byte, details::calculate_byte_size<ElementType, Extent>::value> | ||||
| as_bytes(span<ElementType, Extent> s) noexcept | ||||
| { | ||||
|     using type = span<const byte, details::calculate_byte_size<ElementType, Extent>::value>; | ||||
| 
 | ||||
|     // clang-format off | ||||
|     GSL_SUPPRESS(type.1) // NO-FORMAT: attribute | ||||
|     // clang-format on | ||||
|     return type{reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent, | ||||
|           std::enable_if_t<!std::is_const<ElementType>::value, int> = 0> | ||||
| span<byte, details::calculate_byte_size<ElementType, Extent>::value> | ||||
| as_writable_bytes(span<ElementType, Extent> s) noexcept | ||||
| { | ||||
|     using type = span<byte, details::calculate_byte_size<ElementType, Extent>::value>; | ||||
| 
 | ||||
|     // clang-format off | ||||
|     GSL_SUPPRESS(type.1) // NO-FORMAT: attribute | ||||
|     // clang-format on | ||||
|     return type{reinterpret_cast<byte*>(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 | ||||
							
								
								
									
										212
									
								
								dep/gsl/include/gsl/span_ext
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								dep/gsl/include/gsl/span_ext
									
									
									
									
									
										Normal file
									
								
							|  | @ -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/assert> // GSL_KERNEL_MODE | ||||
| #include <gsl/util>   // for narrow_cast, narrow | ||||
| 
 | ||||
| #include <cstddef> // for ptrdiff_t, size_t | ||||
| #include <utility> | ||||
| 
 | ||||
| #ifndef GSL_KERNEL_MODE | ||||
| #include <algorithm> // for lexicographical_compare | ||||
| #endif               // GSL_KERNEL_MODE | ||||
| 
 | ||||
| namespace gsl | ||||
| { | ||||
| 
 | ||||
| // [span.views.constants], constants | ||||
| constexpr const std::size_t dynamic_extent = narrow_cast<std::size_t>(-1); | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent = dynamic_extent> | ||||
| 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 <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent> | ||||
| constexpr bool operator==(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r) | ||||
| { | ||||
|     return std::equal(l.begin(), l.end(), r.begin(), r.end()); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr bool operator!=(span<ElementType, Extent> l, span<ElementType, Extent> r) | ||||
| { | ||||
|     return !(l == r); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr bool operator<(span<ElementType, Extent> l, span<ElementType, Extent> r) | ||||
| { | ||||
|     return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr bool operator<=(span<ElementType, Extent> l, span<ElementType, Extent> r) | ||||
| { | ||||
|     return !(l > r); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr bool operator>(span<ElementType, Extent> l, span<ElementType, Extent> r) | ||||
| { | ||||
|     return r < l; | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr bool operator>=(span<ElementType, Extent> l, span<ElementType, Extent> r) | ||||
| { | ||||
|     return !(l < r); | ||||
| } | ||||
| 
 | ||||
| #endif // GSL_KERNEL_MODE | ||||
| 
 | ||||
| // | ||||
| // make_span() - Utility functions for creating spans | ||||
| // | ||||
| template <class ElementType> | ||||
| constexpr span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::size_type count) | ||||
| { | ||||
|     return span<ElementType>(ptr, count); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType> | ||||
| constexpr span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem) | ||||
| { | ||||
|     return span<ElementType>(firstElem, lastElem); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t N> | ||||
| constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) noexcept | ||||
| { | ||||
|     return span<ElementType, N>(arr); | ||||
| } | ||||
| 
 | ||||
| template <class Container> | ||||
| constexpr span<typename Container::value_type> make_span(Container& cont) | ||||
| { | ||||
|     return span<typename Container::value_type>(cont); | ||||
| } | ||||
| 
 | ||||
| template <class Container> | ||||
| constexpr span<const typename Container::value_type> make_span(const Container& cont) | ||||
| { | ||||
|     return span<const typename Container::value_type>(cont); | ||||
| } | ||||
| 
 | ||||
| template <class Ptr> | ||||
| constexpr span<typename Ptr::element_type> make_span(Ptr& cont, std::size_t count) | ||||
| { | ||||
|     return span<typename Ptr::element_type>(cont, count); | ||||
| } | ||||
| 
 | ||||
| template <class Ptr> | ||||
| constexpr span<typename Ptr::element_type> make_span(Ptr& cont) | ||||
| { | ||||
|     return span<typename Ptr::element_type>(cont); | ||||
| } | ||||
| 
 | ||||
| // Specialization of gsl::at for span | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr ElementType& at(span<ElementType, Extent> s, index i) | ||||
| { | ||||
|     // No bounds checking here because it is done in span::operator[] called below | ||||
|     Ensures(i >= 0); | ||||
|     return s[narrow_cast<std::size_t>(i)]; | ||||
| } | ||||
| 
 | ||||
| // [span.obs] Free observer functions | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr std::ptrdiff_t ssize(const span<ElementType, Extent>& s) noexcept | ||||
| { | ||||
|     return static_cast<std::ptrdiff_t>(s.size()); | ||||
| } | ||||
| 
 | ||||
| // [span.iter] Free functions for begin/end functions | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr typename span<ElementType, Extent>::iterator | ||||
| begin(const span<ElementType, Extent>& s) noexcept | ||||
| { | ||||
|     return s.begin(); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent = dynamic_extent> | ||||
| constexpr typename span<ElementType, Extent>::iterator | ||||
| end(const span<ElementType, Extent>& s) noexcept | ||||
| { | ||||
|     return s.end(); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr typename span<ElementType, Extent>::reverse_iterator | ||||
| rbegin(const span<ElementType, Extent>& s) noexcept | ||||
| { | ||||
|     return s.rbegin(); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr typename span<ElementType, Extent>::reverse_iterator | ||||
| rend(const span<ElementType, Extent>& s) noexcept | ||||
| { | ||||
|     return s.rend(); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr typename span<ElementType, Extent>::iterator | ||||
| cbegin(const span<ElementType, Extent>& s) noexcept | ||||
| { | ||||
|     return s.begin(); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent = dynamic_extent> | ||||
| constexpr typename span<ElementType, Extent>::iterator | ||||
| cend(const span<ElementType, Extent>& s) noexcept | ||||
| { | ||||
|     return s.end(); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr typename span<ElementType, Extent>::reverse_iterator | ||||
| crbegin(const span<ElementType, Extent>& s) noexcept | ||||
| { | ||||
|     return s.rbegin(); | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr typename span<ElementType, Extent>::reverse_iterator | ||||
| crend(const span<ElementType, Extent>& s) noexcept | ||||
| { | ||||
|     return s.rend(); | ||||
| } | ||||
| 
 | ||||
| } // namespace gsl | ||||
| 
 | ||||
| #endif // GSL_SPAN_EXT_H | ||||
							
								
								
									
										759
									
								
								dep/gsl/include/gsl/string_span
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										759
									
								
								dep/gsl/include/gsl/string_span
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 <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 | ||||
| #include <cstddef>   // for size_t, nullptr_t | ||||
| #include <cstdint>   // for PTRDIFF_MAX | ||||
| #include <cstring> | ||||
| #include <string>      // for basic_string, allocator, char_traits | ||||
| #include <type_traits> // 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 <typename CharT, std::size_t Extent = dynamic_extent> | ||||
| using basic_zstring = CharT*; | ||||
| 
 | ||||
| using czstring = basic_zstring<const char, dynamic_extent>; | ||||
| 
 | ||||
| using cwzstring = basic_zstring<const wchar_t, dynamic_extent>; | ||||
| 
 | ||||
| using cu16zstring = basic_zstring<const char16_t, dynamic_extent>; | ||||
| 
 | ||||
| using cu32zstring = basic_zstring<const char32_t, dynamic_extent>; | ||||
| 
 | ||||
| using zstring = basic_zstring<char, dynamic_extent>; | ||||
| 
 | ||||
| using wzstring = basic_zstring<wchar_t, dynamic_extent>; | ||||
| 
 | ||||
| using u16zstring = basic_zstring<char16_t, dynamic_extent>; | ||||
| 
 | ||||
| using u32zstring = basic_zstring<char32_t, dynamic_extent>; | ||||
| 
 | ||||
| namespace details | ||||
| { | ||||
|     template <class CharT> | ||||
|     [[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<const CharT> 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 <typename T, const T Sentinel> | ||||
| [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see " | ||||
|              "isocpp/CppCoreGuidelines PR#1680")]] constexpr span<T, dynamic_extent> | ||||
| ensure_sentinel(T* seq, std::size_t max = static_cast<std::size_t>(-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<std::size_t>(cur - seq) < max && *cur != Sentinel) ++cur; | ||||
|     Ensures(*cur == Sentinel); | ||||
|     return {seq, static_cast<std::size_t>(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 <typename CharT> | ||||
| [[deprecated("string_span was removed from the C++ Core Guidelines. For more information, see " | ||||
|              "isocpp/CppCoreGuidelines PR#1680")]] constexpr span<CharT, dynamic_extent> | ||||
| ensure_z(CharT* const& sz, std::size_t max = static_cast<std::size_t>(-1)) | ||||
| { | ||||
|     return ensure_sentinel<CharT, CharT(0)>(sz, max); | ||||
| } | ||||
| 
 | ||||
| template <typename CharT, std::size_t N> | ||||
| constexpr span<CharT, dynamic_extent> ensure_z(CharT (&sz)[N]) | ||||
| { | ||||
|     return ensure_z(&sz[0], N); | ||||
| } | ||||
| 
 | ||||
| template <class Cont> | ||||
| [[deprecated( | ||||
|     "string_span was removed from the C++ Core Guidelines. For more information, see " | ||||
|     "isocpp/CppCoreGuidelines PR#1680")]] constexpr span<typename std:: | ||||
|                                                              remove_pointer< | ||||
|                                                                  typename Cont::pointer>::type, | ||||
|                                                          dynamic_extent> | ||||
| ensure_z(Cont& cont) | ||||
| { | ||||
|     return ensure_z(cont.data(), cont.size()); | ||||
| } | ||||
| 
 | ||||
| template <typename CharT, std::size_t> | ||||
| 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 <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{}; | ||||
| 
 | ||||
|     template <typename CharT, std::size_t Extent> | ||||
|     struct [[deprecated( | ||||
|         "string_span was removed from the C++ Core Guidelines. For more information, see " | ||||
|         "isocpp/CppCoreGuidelines PR#1680")]] is_basic_string_span_oracle<basic_string_span<CharT, | ||||
|                                                                                             Extent>> | ||||
|         : std::true_type{}; | ||||
| 
 | ||||
|     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 | ||||
|         : is_basic_string_span_oracle<std::remove_cv_t<T>>{}; | ||||
| } // namespace details | ||||
| 
 | ||||
| // | ||||
| // string_span and relatives | ||||
| // | ||||
| template <typename CharT, std::size_t Extent = dynamic_extent> | ||||
| 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<element_type>; | ||||
|     using pointer = std::add_pointer_t<element_type>; | ||||
|     using reference = std::add_lvalue_reference_t<element_type>; | ||||
|     using const_reference = std::add_lvalue_reference_t<std::add_const_t<element_type>>; | ||||
|     using impl_type = span<element_type, Extent>; | ||||
| 
 | ||||
|     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 <std::size_t N> | ||||
|     constexpr basic_string_span(element_type(&arr)[N]) : span_(remove_z(arr)) | ||||
|     {} | ||||
| 
 | ||||
|     template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>> | ||||
|     constexpr basic_string_span(std::array<ArrayElementType, N> & arr) noexcept : span_(arr) | ||||
|     {} | ||||
| 
 | ||||
|     template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>> | ||||
|     constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) noexcept : span_(arr) | ||||
|     {} | ||||
| 
 | ||||
|     // Container signature should work for basic_string after C++17 version exists | ||||
|     template <class Traits, class Allocator> | ||||
|     // GSL_SUPPRESS(bounds.4) // TODO: parser bug | ||||
|     constexpr basic_string_span(std::basic_string<element_type, Traits, Allocator> & str) | ||||
|         : span_(&str[0], str.length()) | ||||
|     {} | ||||
| 
 | ||||
|     template <class Traits, class Allocator> | ||||
|     constexpr basic_string_span(const std::basic_string<element_type, Traits, Allocator>& str) | ||||
|         : span_(&str[0], str.length()) | ||||
|     {} | ||||
| 
 | ||||
|     // from containers. Containers must have a pointer type and data() function signatures | ||||
|     template <class Container, | ||||
|               class = std::enable_if_t< | ||||
|                   !details::is_basic_string_span<Container>::value && | ||||
|                   std::is_convertible<typename Container::pointer, pointer>::value && | ||||
|                   std::is_convertible<typename Container::pointer, | ||||
|                                       decltype(std::declval<Container>().data())>::value>> | ||||
|     constexpr basic_string_span(Container & cont) : span_(cont) | ||||
|     {} | ||||
| 
 | ||||
|     template <class Container, | ||||
|               class = std::enable_if_t< | ||||
|                   !details::is_basic_string_span<Container>::value && | ||||
|                   std::is_convertible<typename Container::pointer, pointer>::value && | ||||
|                   std::is_convertible<typename Container::pointer, | ||||
|                                       decltype(std::declval<Container>().data())>::value>> | ||||
|     constexpr basic_string_span(const Container& cont) : span_(cont) | ||||
|     {} | ||||
| 
 | ||||
|     // from string_span | ||||
|     template < | ||||
|         class OtherValueType, std::size_t OtherExtent, | ||||
|         class = std::enable_if_t<std::is_convertible< | ||||
|             typename basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value>> | ||||
|     constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other) | ||||
|         : span_(other.data(), other.length()) | ||||
|     {} | ||||
| 
 | ||||
|     template <size_type Count> | ||||
|     constexpr basic_string_span<element_type, Count> first() const | ||||
|     { | ||||
|         return {span_.template first<Count>()}; | ||||
|     } | ||||
| 
 | ||||
|     constexpr basic_string_span<element_type, dynamic_extent> first(size_type count) const | ||||
|     { | ||||
|         return {span_.first(count)}; | ||||
|     } | ||||
| 
 | ||||
|     template <size_type Count> | ||||
|     constexpr basic_string_span<element_type, Count> last() const | ||||
|     { | ||||
|         return {span_.template last<Count>()}; | ||||
|     } | ||||
| 
 | ||||
|     constexpr basic_string_span<element_type, dynamic_extent> last(size_type count) const | ||||
|     { | ||||
|         return {span_.last(count)}; | ||||
|     } | ||||
| 
 | ||||
|     template <size_type Offset, size_type Count> | ||||
|     constexpr basic_string_span<element_type, Count> subspan() const | ||||
|     { | ||||
|         return {span_.template subspan<Offset, Count>()}; | ||||
|     } | ||||
| 
 | ||||
|     constexpr basic_string_span<element_type, dynamic_extent> 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 <std::size_t N> | ||||
|     static constexpr impl_type remove_z(element_type(&sz)[N]) | ||||
|     { | ||||
|         return remove_z(&sz[0], N); | ||||
|     } | ||||
| 
 | ||||
|     impl_type span_; | ||||
| }; | ||||
| 
 | ||||
| template <std::size_t Extent = dynamic_extent> | ||||
| using string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_string_span<char, Extent>; | ||||
| 
 | ||||
| template <std::size_t Extent = dynamic_extent> | ||||
| using cstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                 "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_string_span<const char, Extent>; | ||||
| 
 | ||||
| template <std::size_t Extent = dynamic_extent> | ||||
| using wstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                 "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_string_span<wchar_t, Extent>; | ||||
| 
 | ||||
| template <std::size_t Extent = dynamic_extent> | ||||
| using cwstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                  "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_string_span<const wchar_t, Extent>; | ||||
| 
 | ||||
| template <std::size_t Extent = dynamic_extent> | ||||
| using u16string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                   "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_string_span<char16_t, Extent>; | ||||
| 
 | ||||
| template <std::size_t Extent = dynamic_extent> | ||||
| using cu16string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                    "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_string_span<const char16_t, Extent>; | ||||
| 
 | ||||
| template <std::size_t Extent = dynamic_extent> | ||||
| using u32string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                   "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_string_span<char32_t, Extent>; | ||||
| 
 | ||||
| template <std::size_t Extent = dynamic_extent> | ||||
| using cu32string_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                    "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_string_span<const char32_t, Extent>; | ||||
| 
 | ||||
| // | ||||
| // to_string() allow (explicit) conversions from string_span to string | ||||
| // | ||||
| 
 | ||||
| template <typename CharT, std::size_t Extent> | ||||
| constexpr std::basic_string<typename std::remove_const<CharT>::type> | ||||
| to_string(basic_string_span<CharT, Extent> view) | ||||
| { | ||||
|     return {view.data(), narrow_cast<std::size_t>(view.length())}; | ||||
| } | ||||
| 
 | ||||
| template <typename CharT, typename Traits = typename std::char_traits<CharT>, | ||||
|           typename Allocator = std::allocator<CharT>, typename gCharT, std::size_t Extent> | ||||
| constexpr std::basic_string<CharT, Traits, Allocator> | ||||
| to_basic_string(basic_string_span<gCharT, Extent> view) | ||||
| { | ||||
|     return {view.data(), narrow_cast<std::size_t>(view.length())}; | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent> | ||||
| constexpr basic_string_span<const byte, details::calculate_byte_size<ElementType, Extent>::value> | ||||
| as_bytes(basic_string_span<ElementType, Extent> s) noexcept | ||||
| { | ||||
|     // clang-format off | ||||
|     GSL_SUPPRESS(type.1) | ||||
|     // clang-format on | ||||
|     return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; | ||||
| } | ||||
| 
 | ||||
| template <class ElementType, std::size_t Extent, | ||||
|           class = std::enable_if_t<!std::is_const<ElementType>::value>> | ||||
| constexpr basic_string_span<byte, details::calculate_byte_size<ElementType, Extent>::value> | ||||
| as_writable_bytes(basic_string_span<ElementType, Extent> s) noexcept | ||||
| { | ||||
|     // clang-format off | ||||
|     GSL_SUPPRESS(type.1) | ||||
|     // clang-format on | ||||
|     return {reinterpret_cast<byte*>(s.data()), s.size_bytes()}; | ||||
| } | ||||
| 
 | ||||
| // zero-terminated string span, used to convert | ||||
| // zero-terminated spans to legacy strings | ||||
| template <typename CharT, std::size_t Extent = dynamic_extent> | ||||
| 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<CharT>; | ||||
| 
 | ||||
|     using pointer = std::add_pointer_t<value_type>; | ||||
|     using const_pointer = std::add_pointer_t<const_value_type>; | ||||
| 
 | ||||
|     using zstring_type = basic_zstring<value_type, Extent>; | ||||
|     using const_zstring_type = basic_zstring<const_value_type, Extent>; | ||||
| 
 | ||||
|     using impl_type = span<value_type, Extent>; | ||||
|     using string_span_type = basic_string_span<value_type, Extent>; | ||||
| 
 | ||||
|     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 <std::size_t Max = dynamic_extent> | ||||
| using zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                 "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_zstring_span<char, Max>; | ||||
| 
 | ||||
| template <std::size_t Max = dynamic_extent> | ||||
| using wzstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                  "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_zstring_span<wchar_t, Max>; | ||||
| 
 | ||||
| template <std::size_t Max = dynamic_extent> | ||||
| using u16zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                    "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_zstring_span<char16_t, Max>; | ||||
| 
 | ||||
| template <std::size_t Max = dynamic_extent> | ||||
| using u32zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                    "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_zstring_span<char32_t, Max>; | ||||
| 
 | ||||
| template <std::size_t Max = dynamic_extent> | ||||
| using czstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                  "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_zstring_span<const char, Max>; | ||||
| 
 | ||||
| template <std::size_t Max = dynamic_extent> | ||||
| using cwzstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For more " | ||||
|                                   "information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_zstring_span<const wchar_t, Max>; | ||||
| 
 | ||||
| template <std::size_t Max = dynamic_extent> | ||||
| using cu16zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For " | ||||
|                                     "more information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_zstring_span<const char16_t, Max>; | ||||
| 
 | ||||
| template <std::size_t Max = dynamic_extent> | ||||
| using cu32zstring_span [[deprecated("string_span was removed from the C++ Core Guidelines. For " | ||||
|                                     "more information, see isocpp/CppCoreGuidelines PR#1680")]] = | ||||
|     basic_zstring_span<const char32_t, Max>; | ||||
| 
 | ||||
| // operator == | ||||
| template <class CharT, std::size_t Extent, class T, | ||||
|           class = std::enable_if_t< | ||||
|               details::is_basic_string_span<T>::value || | ||||
|               std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>> | ||||
| bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other) | ||||
| { | ||||
|     const gsl::basic_string_span<std::add_const_t<CharT>> tmp(other); | ||||
|     return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end()); | ||||
| } | ||||
| 
 | ||||
| template <class CharT, std::size_t Extent, class T, | ||||
|           class = std::enable_if_t< | ||||
|               !details::is_basic_string_span<T>::value && | ||||
|               std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>> | ||||
| bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other) | ||||
| { | ||||
|     const gsl::basic_string_span<std::add_const_t<CharT>> tmp(one); | ||||
|     return std::equal(tmp.begin(), tmp.end(), other.begin(), other.end()); | ||||
| } | ||||
| 
 | ||||
| // operator != | ||||
| template <typename CharT, std::size_t Extent = dynamic_extent, typename T, | ||||
|           typename = std::enable_if_t<std::is_convertible< | ||||
|               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> | ||||
| bool operator!=(gsl::basic_string_span<CharT, Extent> 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<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && | ||||
|         !gsl::details::is_basic_string_span<T>::value>> | ||||
| bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) | ||||
| { | ||||
|     return !(one == other); | ||||
| } | ||||
| 
 | ||||
| // operator< | ||||
| template <typename CharT, std::size_t Extent = dynamic_extent, typename T, | ||||
|           typename = std::enable_if_t<std::is_convertible< | ||||
|               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> | ||||
| bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) | ||||
| { | ||||
|     const gsl::basic_string_span<std::add_const_t<CharT>, 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<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && | ||||
|         !gsl::details::is_basic_string_span<T>::value>> | ||||
| bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) | ||||
| { | ||||
|     gsl::basic_string_span<std::add_const_t<CharT>, 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<T>::value && !gsl::details::is_basic_string_span<T>::value && | ||||
|         std::is_convertible<DataType*, CharT*>::value && | ||||
|         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, | ||||
|                      DataType>::value>> | ||||
| bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) | ||||
| { | ||||
|     gsl::basic_string_span<std::add_const_t<CharT>, 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<T>::value && !gsl::details::is_basic_string_span<T>::value && | ||||
|         std::is_convertible<DataType*, CharT*>::value && | ||||
|         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, | ||||
|                      DataType>::value>> | ||||
| bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) | ||||
| { | ||||
|     gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one); | ||||
|     return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end()); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| // operator <= | ||||
| template <typename CharT, std::size_t Extent = dynamic_extent, typename T, | ||||
|           typename = std::enable_if_t<std::is_convertible< | ||||
|               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> | ||||
| bool operator<=(gsl::basic_string_span<CharT, Extent> 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<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && | ||||
|         !gsl::details::is_basic_string_span<T>::value>> | ||||
| bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> 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<T>::value && !gsl::details::is_basic_string_span<T>::value && | ||||
|         std::is_convertible<DataType*, CharT*>::value && | ||||
|         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, | ||||
|                      DataType>::value>> | ||||
| bool operator<=(gsl::basic_string_span<CharT, Extent> 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<T>::value && !gsl::details::is_basic_string_span<T>::value && | ||||
|         std::is_convertible<DataType*, CharT*>::value && | ||||
|         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, | ||||
|                      DataType>::value>> | ||||
| bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) | ||||
| { | ||||
|     return !(other < one); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| // operator> | ||||
| template <typename CharT, std::size_t Extent = dynamic_extent, typename T, | ||||
|           typename = std::enable_if_t<std::is_convertible< | ||||
|               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> | ||||
| bool operator>(gsl::basic_string_span<CharT, Extent> 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<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && | ||||
|         !gsl::details::is_basic_string_span<T>::value>> | ||||
| bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> 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<T>::value && !gsl::details::is_basic_string_span<T>::value && | ||||
|         std::is_convertible<DataType*, CharT*>::value && | ||||
|         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, | ||||
|                      DataType>::value>> | ||||
| bool operator>(gsl::basic_string_span<CharT, Extent> 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<T>::value && !gsl::details::is_basic_string_span<T>::value && | ||||
|         std::is_convertible<DataType*, CharT*>::value && | ||||
|         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, | ||||
|                      DataType>::value>> | ||||
| bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) | ||||
| { | ||||
|     return other < one; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| // operator >= | ||||
| template <typename CharT, std::size_t Extent = dynamic_extent, typename T, | ||||
|           typename = std::enable_if_t<std::is_convertible< | ||||
|               T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> | ||||
| bool operator>=(gsl::basic_string_span<CharT, Extent> 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<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && | ||||
|         !gsl::details::is_basic_string_span<T>::value>> | ||||
| bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> 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<T>::value && !gsl::details::is_basic_string_span<T>::value && | ||||
|         std::is_convertible<DataType*, CharT*>::value && | ||||
|         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, | ||||
|                      DataType>::value>> | ||||
| bool operator>=(gsl::basic_string_span<CharT, Extent> 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<T>::value && !gsl::details::is_basic_string_span<T>::value && | ||||
|         std::is_convertible<DataType*, CharT*>::value && | ||||
|         std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, | ||||
|                      DataType>::value>> | ||||
| bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> 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 | ||||
							
								
								
									
										160
									
								
								dep/gsl/include/gsl/util
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								dep/gsl/include/gsl/util
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 <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(__has_include) && __has_include(<version>) | ||||
| #include <version> | ||||
| #if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L | ||||
| #include <span> | ||||
| #endif // __cpp_lib_span >= 202002L | ||||
| #endif //__has_include(<version>) | ||||
| 
 | ||||
| #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); | ||||
| } | ||||
| 
 | ||||
| #if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L | ||||
| template <class T, size_t extent = std::dynamic_extent> | ||||
| constexpr auto at(std::span<T, extent> sp, const index i) -> decltype(sp[sp.size()]) | ||||
| { | ||||
|     Expects(i >= 0 && i < narrow_cast<index>(sp.size())); | ||||
|     return sp[gsl::narrow_cast<size_t>(i)]; | ||||
| } | ||||
| #endif // __cpp_lib_span >= 202002L | ||||
| } // namespace gsl | ||||
| 
 | ||||
| #if defined(_MSC_VER) && !defined(__clang__) | ||||
| 
 | ||||
| #pragma warning(pop) | ||||
| 
 | ||||
| #endif // _MSC_VER | ||||
| 
 | ||||
| #endif // GSL_UTIL_H | ||||
		Loading…
	
		Reference in a new issue
	
	 Connor McLaughlin
						Connor McLaughlin