github.com/ledgerwatch/erigon-lib@v1.0.0/pedersen_hash/gsl-lite.hpp (about) 1 // 2 // gsl-lite is based on GSL: Guideline Support Library. 3 // For more information see https://github.com/martinmoene/gsl-lite 4 // 5 // Copyright (c) 2015-2018 Martin Moene 6 // Copyright (c) 2015-2018 Microsoft Corporation. All rights reserved. 7 // 8 // This code is licensed under the MIT License (MIT). 9 // 10 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 13 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 14 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 15 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 16 // THE SOFTWARE. 17 18 #pragma once 19 20 #ifndef GSL_GSL_LITE_HPP_INCLUDED 21 #define GSL_GSL_LITE_HPP_INCLUDED 22 23 #include <algorithm> 24 #include <exception> 25 #include <iterator> 26 #include <limits> 27 #include <memory> 28 #include <ostream> 29 #include <stdexcept> 30 #include <string> 31 #include <utility> 32 #include <vector> 33 34 #define gsl_lite_MAJOR 0 35 #define gsl_lite_MINOR 32 36 #define gsl_lite_PATCH 0 37 #define gsl_lite_VERSION gsl_STRINGIFY(gsl_lite_MAJOR) "." gsl_STRINGIFY(gsl_lite_MINOR) "." gsl_STRINGIFY(gsl_lite_PATCH) 38 39 // gsl-lite backward compatibility: 40 41 #ifdef gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR 42 # define gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR 43 # pragma message ("gsl_CONFIG_ALLOWS_SPAN_CONTAINER_CTOR is deprecated since gsl-lite 0.7.0; replace with gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR, or consider span(with_container, cont).") 44 #endif 45 46 // M-GSL compatibility: 47 48 #if defined( GSL_THROW_ON_CONTRACT_VIOLATION ) 49 # define gsl_CONFIG_CONTRACT_VIOLATION_THROWS 1 50 #endif 51 52 #if defined( GSL_TERMINATE_ON_CONTRACT_VIOLATION ) 53 # define gsl_CONFIG_CONTRACT_VIOLATION_THROWS 0 54 #endif 55 56 #if defined( GSL_UNENFORCED_ON_CONTRACT_VIOLATION ) 57 # define gsl_CONFIG_CONTRACT_LEVEL_OFF 1 58 #endif 59 60 // Configuration: Features 61 62 #ifndef gsl_FEATURE_WITH_CONTAINER_TO_STD 63 # define gsl_FEATURE_WITH_CONTAINER_TO_STD 99 64 #endif 65 66 #ifndef gsl_FEATURE_MAKE_SPAN_TO_STD 67 # define gsl_FEATURE_MAKE_SPAN_TO_STD 99 68 #endif 69 70 #ifndef gsl_FEATURE_BYTE_SPAN_TO_STD 71 # define gsl_FEATURE_BYTE_SPAN_TO_STD 99 72 #endif 73 74 #ifndef gsl_FEATURE_HAVE_IMPLICIT_MACRO 75 # define gsl_FEATURE_HAVE_IMPLICIT_MACRO 1 76 #endif 77 78 #ifndef gsl_FEATURE_HAVE_OWNER_MACRO 79 # define gsl_FEATURE_HAVE_OWNER_MACRO 1 80 #endif 81 82 #ifndef gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD 83 # define gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD 0 84 #endif 85 86 // Configuration: Other 87 88 #ifndef gsl_CONFIG_DEPRECATE_TO_LEVEL 89 # define gsl_CONFIG_DEPRECATE_TO_LEVEL 0 90 #endif 91 92 #ifndef gsl_CONFIG_SPAN_INDEX_TYPE 93 # define gsl_CONFIG_SPAN_INDEX_TYPE size_t 94 #endif 95 96 #ifndef gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR 97 # define gsl_CONFIG_NOT_NULL_EXPLICIT_CTOR 0 98 #endif 99 100 #ifndef gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF 101 # define gsl_CONFIG_NOT_NULL_GET_BY_CONST_REF 0 102 #endif 103 104 #ifndef gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS 105 # define gsl_CONFIG_CONFIRMS_COMPILATION_ERRORS 0 106 #endif 107 108 #ifndef gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON 109 # define gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON 1 110 #endif 111 112 #ifndef gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR 113 # define gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR 0 114 #endif 115 116 #if defined( gsl_CONFIG_CONTRACT_LEVEL_ON ) 117 # define gsl_CONFIG_CONTRACT_LEVEL_MASK 0x11 118 #elif defined( gsl_CONFIG_CONTRACT_LEVEL_OFF ) 119 # define gsl_CONFIG_CONTRACT_LEVEL_MASK 0x00 120 #elif defined( gsl_CONFIG_CONTRACT_LEVEL_EXPECTS_ONLY ) 121 # define gsl_CONFIG_CONTRACT_LEVEL_MASK 0x01 122 #elif defined( gsl_CONFIG_CONTRACT_LEVEL_ENSURES_ONLY ) 123 # define gsl_CONFIG_CONTRACT_LEVEL_MASK 0x10 124 #else 125 # define gsl_CONFIG_CONTRACT_LEVEL_MASK 0x11 126 #endif 127 128 #if !defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) && \ 129 !defined( gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES ) 130 # define gsl_CONFIG_CONTRACT_VIOLATION_THROWS_V 0 131 #elif defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) && \ 132 !defined( gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES ) 133 # define gsl_CONFIG_CONTRACT_VIOLATION_THROWS_V 1 134 #elif !defined( gsl_CONFIG_CONTRACT_VIOLATION_THROWS ) && \ 135 defined( gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES ) 136 # define gsl_CONFIG_CONTRACT_VIOLATION_THROWS_V 0 137 #else 138 # error only one of gsl_CONFIG_CONTRACT_VIOLATION_THROWS and gsl_CONFIG_CONTRACT_VIOLATION_TERMINATES may be defined. 139 #endif 140 141 // C++ language version detection (C++20 is speculative): 142 // Note: VC14.0/1900 (VS2015) lacks too much from C++14. 143 144 #ifndef gsl_CPLUSPLUS 145 # ifdef _MSVC_LANG 146 # define gsl_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) 147 # else 148 # define gsl_CPLUSPLUS __cplusplus 149 # endif 150 #endif 151 152 #define gsl_CPP98_OR_GREATER ( gsl_CPLUSPLUS >= 199711L ) 153 #define gsl_CPP11_OR_GREATER ( gsl_CPLUSPLUS >= 201103L ) 154 #define gsl_CPP14_OR_GREATER ( gsl_CPLUSPLUS >= 201402L ) 155 #define gsl_CPP17_OR_GREATER ( gsl_CPLUSPLUS >= 201703L ) 156 #define gsl_CPP20_OR_GREATER ( gsl_CPLUSPLUS >= 202000L ) 157 158 // C++ language version (represent 98 as 3): 159 160 #define gsl_CPLUSPLUS_V ( gsl_CPLUSPLUS / 100 - (gsl_CPLUSPLUS > 200000 ? 2000 : 1994) ) 161 162 // half-open range [lo..hi): 163 #define gsl_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) 164 165 #if defined( _MSC_VER ) && !defined( __clang__ ) 166 # define gsl_COMPILER_MSVC_VERSION ( _MSC_VER / 10 - 10 * ( 5 + ( _MSC_VER < 1900 ) ) ) 167 #else 168 # define gsl_COMPILER_MSVC_VERSION 0 169 #endif 170 171 #define gsl_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) 172 173 #if defined __clang__ 174 # define gsl_COMPILER_CLANG_VERSION gsl_COMPILER_VERSION( __clang_major__, __clang_minor__, __clang_patchlevel__ ) 175 #else 176 # define gsl_COMPILER_CLANG_VERSION 0 177 #endif 178 179 #if defined __GNUC__ 180 # define gsl_COMPILER_GNUC_VERSION gsl_COMPILER_VERSION( __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ ) 181 #else 182 # define gsl_COMPILER_GNUC_VERSION 0 183 #endif 184 185 // Compiler non-strict aliasing: 186 187 #if defined __clang__ || defined __GNUC__ 188 # define gsl_may_alias __attribute__((__may_alias__)) 189 #else 190 # define gsl_may_alias 191 #endif 192 193 // Presence of gsl, language and library features: 194 195 #define gsl_IN_STD( v ) ( (v) == 98 || (v) >= gsl_CPLUSPLUS_V ) 196 197 #define gsl_DEPRECATE_TO_LEVEL( level ) ( level <= gsl_CONFIG_DEPRECATE_TO_LEVEL ) 198 #define gsl_FEATURE_TO_STD( feature ) ( gsl_IN_STD( gsl_FEATURE( feature##_TO_STD ) ) ) 199 #define gsl_FEATURE( feature ) ( gsl_FEATURE_##feature ) 200 #define gsl_CONFIG( feature ) ( gsl_CONFIG_##feature ) 201 #define gsl_HAVE( feature ) ( gsl_HAVE_##feature ) 202 203 // Presence of wide character support: 204 205 #ifdef __DJGPP__ 206 # define gsl_HAVE_WCHAR 0 207 #else 208 # define gsl_HAVE_WCHAR 1 209 #endif 210 211 // Presence of language & library features: 212 213 #ifdef _HAS_CPP0X 214 # define gsl_HAS_CPP0X _HAS_CPP0X 215 #else 216 # define gsl_HAS_CPP0X 0 217 #endif 218 219 #define gsl_CPP11_100 (gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 100) 220 #define gsl_CPP11_110 (gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 110) 221 #define gsl_CPP11_120 (gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120) 222 #define gsl_CPP11_140 (gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 140) 223 224 #define gsl_CPP14_000 (gsl_CPP14_OR_GREATER) 225 #define gsl_CPP14_120 (gsl_CPP14_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120) 226 #define gsl_CPP14_140 (gsl_CPP14_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 140) 227 228 #define gsl_CPP17_000 (gsl_CPP17_OR_GREATER) 229 #define gsl_CPP17_140 (gsl_CPP17_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 140) 230 231 #define gsl_CPP11_140_CPP0X_90 (gsl_CPP11_140 || (gsl_COMPILER_MSVC_VERSION >= 90 && gsl_HAS_CPP0X)) 232 #define gsl_CPP11_140_CPP0X_100 (gsl_CPP11_140 || (gsl_COMPILER_MSVC_VERSION >= 100 && gsl_HAS_CPP0X)) 233 234 // Presence of C++11 language features: 235 236 #define gsl_HAVE_AUTO gsl_CPP11_100 237 #define gsl_HAVE_NULLPTR gsl_CPP11_100 238 #define gsl_HAVE_RVALUE_REFERENCE gsl_CPP11_100 239 240 #define gsl_HAVE_ENUM_CLASS gsl_CPP11_110 241 242 #define gsl_HAVE_ALIAS_TEMPLATE gsl_CPP11_120 243 #define gsl_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG gsl_CPP11_120 244 #define gsl_HAVE_EXPLICIT gsl_CPP11_120 245 #define gsl_HAVE_INITIALIZER_LIST gsl_CPP11_120 246 247 #define gsl_HAVE_CONSTEXPR_11 gsl_CPP11_140 248 #define gsl_HAVE_IS_DEFAULT gsl_CPP11_140 249 #define gsl_HAVE_IS_DELETE gsl_CPP11_140 250 #define gsl_HAVE_NOEXCEPT gsl_CPP11_140 251 252 #if gsl_CPP11_OR_GREATER 253 // see above 254 #endif 255 256 // Presence of C++14 language features: 257 258 #define gsl_HAVE_CONSTEXPR_14 gsl_CPP14_000 259 #define gsl_HAVE_DECLTYPE_AUTO gsl_CPP14_140 260 261 // Presence of C++17 language features: 262 // MSVC: template parameter deduction guides since Visual Studio 2017 v15.7 263 264 #define gsl_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE gsl_CPP17_000 265 #define gsl_HAVE_DEDUCTION_GUIDES (gsl_CPP17_000 && ! gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 1, 999 ) ) 266 267 // Presence of C++ library features: 268 269 #define gsl_HAVE_ADDRESSOF gsl_CPP17_000 270 #define gsl_HAVE_ARRAY gsl_CPP11_110 271 #define gsl_HAVE_TYPE_TRAITS gsl_CPP11_110 272 #define gsl_HAVE_TR1_TYPE_TRAITS gsl_CPP11_110 273 274 #define gsl_HAVE_CONTAINER_DATA_METHOD gsl_CPP11_140_CPP0X_90 275 #define gsl_HAVE_STD_DATA gsl_CPP17_000 276 277 #define gsl_HAVE_SIZED_TYPES gsl_CPP11_140 278 279 #define gsl_HAVE_MAKE_SHARED gsl_CPP11_140_CPP0X_100 280 #define gsl_HAVE_SHARED_PTR gsl_CPP11_140_CPP0X_100 281 #define gsl_HAVE_UNIQUE_PTR gsl_CPP11_140_CPP0X_100 282 283 #define gsl_HAVE_MAKE_UNIQUE gsl_CPP14_120 284 285 #define gsl_HAVE_UNCAUGHT_EXCEPTIONS gsl_CPP17_140 286 287 #define gsl_HAVE_ADD_CONST gsl_HAVE_TYPE_TRAITS 288 #define gsl_HAVE_INTEGRAL_CONSTANT gsl_HAVE_TYPE_TRAITS 289 #define gsl_HAVE_REMOVE_CONST gsl_HAVE_TYPE_TRAITS 290 #define gsl_HAVE_REMOVE_REFERENCE gsl_HAVE_TYPE_TRAITS 291 292 #define gsl_HAVE_TR1_ADD_CONST gsl_HAVE_TR1_TYPE_TRAITS 293 #define gsl_HAVE_TR1_INTEGRAL_CONSTANT gsl_HAVE_TR1_TYPE_TRAITS 294 #define gsl_HAVE_TR1_REMOVE_CONST gsl_HAVE_TR1_TYPE_TRAITS 295 #define gsl_HAVE_TR1_REMOVE_REFERENCE gsl_HAVE_TR1_TYPE_TRAITS 296 297 // C++ feature usage: 298 299 #if gsl_HAVE( ADDRESSOF ) 300 # define gsl_ADDRESSOF(x) std::addressof(x) 301 #else 302 # define gsl_ADDRESSOF(x) (&x) 303 #endif 304 305 #if gsl_HAVE( CONSTEXPR_11 ) 306 # define gsl_constexpr constexpr 307 #else 308 # define gsl_constexpr /*constexpr*/ 309 #endif 310 311 #if gsl_HAVE( CONSTEXPR_14 ) 312 # define gsl_constexpr14 constexpr 313 #else 314 # define gsl_constexpr14 /*constexpr*/ 315 #endif 316 317 #if gsl_HAVE( EXPLICIT ) 318 # define gsl_explicit explicit 319 #else 320 # define gsl_explicit /*explicit*/ 321 #endif 322 323 #if gsl_FEATURE( HAVE_IMPLICIT_MACRO ) 324 # define implicit /*implicit*/ 325 #endif 326 327 #if gsl_HAVE( IS_DELETE ) 328 # define gsl_is_delete = delete 329 #else 330 # define gsl_is_delete 331 #endif 332 333 #if gsl_HAVE( IS_DELETE ) 334 # define gsl_is_delete_access public 335 #else 336 # define gsl_is_delete_access private 337 #endif 338 339 #if !gsl_HAVE( NOEXCEPT ) || gsl_CONFIG( CONTRACT_VIOLATION_THROWS_V ) 340 # define gsl_noexcept /*noexcept*/ 341 #else 342 # define gsl_noexcept noexcept 343 #endif 344 345 #if gsl_HAVE( NULLPTR ) 346 # define gsl_nullptr nullptr 347 #else 348 # define gsl_nullptr NULL 349 #endif 350 351 #define gsl_DIMENSION_OF( a ) ( sizeof(a) / sizeof(0[a]) ) 352 353 // Other features: 354 355 #define gsl_HAVE_CONSTRAINED_SPAN_CONTAINER_CTOR \ 356 ( gsl_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG && gsl_HAVE_CONTAINER_DATA_METHOD ) 357 358 // Note: !defined(__NVCC__) doesn't work with nvcc here: 359 #define gsl_HAVE_UNCONSTRAINED_SPAN_CONTAINER_CTOR \ 360 ( gsl_CONFIG_ALLOWS_UNCONSTRAINED_SPAN_CONTAINER_CTOR && (__NVCC__== 0) ) 361 362 // GSL API (e.g. for CUDA platform): 363 364 #ifndef gsl_api 365 # ifdef __CUDACC__ 366 # define gsl_api __host__ __device__ 367 # else 368 # define gsl_api /*gsl_api*/ 369 # endif 370 #endif 371 372 // Additional includes: 373 374 #if gsl_HAVE( ARRAY ) 375 # include <array> 376 #endif 377 378 #if gsl_HAVE( TYPE_TRAITS ) 379 # include <type_traits> 380 #elif gsl_HAVE( TR1_TYPE_TRAITS ) 381 # include <tr1/type_traits> 382 #endif 383 384 #if gsl_HAVE( SIZED_TYPES ) 385 # include <cstdint> 386 #endif 387 388 // MSVC warning suppression macros: 389 390 #if gsl_COMPILER_MSVC_VERSION >= 140 391 # define gsl_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]] 392 # define gsl_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) ) 393 # define gsl_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes)) 394 # define gsl_RESTORE_MSVC_WARNINGS() __pragma(warning(pop )) 395 #else 396 # define gsl_SUPPRESS_MSGSL_WARNING(expr) 397 # define gsl_SUPPRESS_MSVC_WARNING(code, descr) 398 # define gsl_DISABLE_MSVC_WARNINGS(codes) 399 # define gsl_RESTORE_MSVC_WARNINGS() 400 #endif 401 402 // Suppress the following MSVC GSL warnings: 403 // - C26410: gsl::r.32: the parameter 'ptr' is a reference to const unique pointer, use const T* or const T& instead 404 // - C26415: gsl::r.30: smart pointer parameter 'ptr' is used only to access contained pointer. Use T* or T& instead 405 // - C26418: gsl::r.36: shared pointer parameter 'ptr' is not copied or moved. Use T* or T& instead 406 // - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions; 407 // use brace initialization, gsl::narrow_cast or gsl::narow 408 // - C26439, gsl::f.6 : special function 'function' can be declared 'noexcept' 409 // - C26440, gsl::f.6 : function 'function' can be declared 'noexcept' 410 // - C26473: gsl::t.1 : don't cast between pointer types where the source type and the target type are the same 411 // - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead 412 // - C26482, gsl::b.2 : only index into arrays using constant expressions 413 // - C26490: gsl::t.1 : don't use reinterpret_cast 414 415 gsl_DISABLE_MSVC_WARNINGS( 26410 26415 26418 26472 26439 26440 26473 26481 26482 26490 ) 416 417 namespace gsl { 418 419 // forward declare span<>: 420 421 template< class T > 422 class span; 423 424 namespace details { 425 426 // C++11 emulation: 427 428 #if gsl_HAVE( ADD_CONST ) 429 430 using std::add_const; 431 432 #elif gsl_HAVE( TR1_ADD_CONST ) 433 434 using std::tr1::add_const; 435 436 #else 437 438 template< class T > struct add_const { typedef const T type; }; 439 440 #endif // gsl_HAVE( ADD_CONST ) 441 442 #if gsl_HAVE( REMOVE_CONST ) 443 444 using std::remove_cv; 445 using std::remove_const; 446 using std::remove_volatile; 447 448 #elif gsl_HAVE( TR1_REMOVE_CONST ) 449 450 using std::tr1::remove_cv; 451 using std::tr1::remove_const; 452 using std::tr1::remove_volatile; 453 454 #else 455 456 template< class T > struct remove_const { typedef T type; }; 457 template< class T > struct remove_const<T const> { typedef T type; }; 458 459 template< class T > struct remove_volatile { typedef T type; }; 460 template< class T > struct remove_volatile<T volatile> { typedef T type; }; 461 462 template< class T > 463 struct remove_cv 464 { 465 typedef typename details::remove_volatile<typename details::remove_const<T>::type>::type type; 466 }; 467 468 #endif // gsl_HAVE( REMOVE_CONST ) 469 470 #if gsl_HAVE( INTEGRAL_CONSTANT ) 471 472 using std::integral_constant; 473 using std::true_type; 474 using std::false_type; 475 476 #elif gsl_HAVE( TR1_INTEGRAL_CONSTANT ) 477 478 using std::tr1::integral_constant; 479 using std::tr1::true_type; 480 using std::tr1::false_type; 481 482 #else 483 484 template< int v > struct integral_constant { enum { value = v }; }; 485 typedef integral_constant< true > true_type; 486 typedef integral_constant< false > false_type; 487 488 #endif 489 490 #if gsl_HAVE( TYPE_TRAITS ) 491 492 template< class Q > 493 struct is_span_oracle : std::false_type{}; 494 495 template< class T> 496 struct is_span_oracle< span<T> > : std::true_type{}; 497 498 template< class Q > 499 struct is_span : is_span_oracle< typename std::remove_cv<Q>::type >{}; 500 501 template< class Q > 502 struct is_std_array_oracle : std::false_type{}; 503 504 #if gsl_HAVE( ARRAY ) 505 506 template< class T, std::size_t Extent > 507 struct is_std_array_oracle< std::array<T, Extent> > : std::true_type{}; 508 509 #endif 510 511 template< class Q > 512 struct is_std_array : is_std_array_oracle< typename std::remove_cv<Q>::type >{}; 513 514 template< class Q > 515 struct is_array : std::false_type {}; 516 517 template< class T > 518 struct is_array<T[]> : std::true_type {}; 519 520 template< class T, std::size_t N > 521 struct is_array<T[N]> : std::true_type {}; 522 523 #endif // gsl_HAVE( TYPE_TRAITS ) 524 525 } // namespace details 526 527 // 528 // GSL.util: utilities 529 // 530 531 // index type for all container indexes/subscripts/sizes 532 typedef gsl_CONFIG_SPAN_INDEX_TYPE index; // p0122r3 uses std::ptrdiff_t 533 534 // 535 // GSL.owner: ownership pointers 536 // 537 #if gsl_HAVE( SHARED_PTR ) 538 using std::unique_ptr; 539 using std::shared_ptr; 540 using std::make_shared; 541 # if gsl_HAVE( MAKE_UNIQUE ) 542 using std::make_unique; 543 # endif 544 #endif 545 546 #if gsl_HAVE( ALIAS_TEMPLATE ) 547 # if gsl_HAVE( TYPE_TRAITS ) 548 template< class T, class = typename std::enable_if< std::is_pointer<T>::value >::type > 549 using owner = T; 550 # else 551 template< class T > using owner = T; 552 # endif 553 #else 554 template< class T > struct owner { typedef T type; }; 555 #endif 556 557 #define gsl_HAVE_OWNER_TEMPLATE gsl_HAVE_ALIAS_TEMPLATE 558 559 #if gsl_FEATURE( HAVE_OWNER_MACRO ) 560 # if gsl_HAVE( OWNER_TEMPLATE ) 561 # define Owner(t) ::gsl::owner<t> 562 # else 563 # define Owner(t) ::gsl::owner<t>::type 564 # endif 565 #endif 566 567 // 568 // GSL.assert: assertions 569 // 570 571 #define gsl_ELIDE_CONTRACT_EXPECTS ( 0 == ( gsl_CONFIG_CONTRACT_LEVEL_MASK & 0x01 ) ) 572 #define gsl_ELIDE_CONTRACT_ENSURES ( 0 == ( gsl_CONFIG_CONTRACT_LEVEL_MASK & 0x10 ) ) 573 574 #if gsl_ELIDE_CONTRACT_EXPECTS 575 # define Expects( x ) /* Expects elided */ 576 #elif gsl_CONFIG( CONTRACT_VIOLATION_THROWS_V ) 577 # define Expects( x ) ::gsl::fail_fast_assert( (x), "GSL: Precondition failure at " __FILE__ ":" gsl_STRINGIFY(__LINE__) ); 578 #else 579 # define Expects( x ) ::gsl::fail_fast_assert( (x) ) 580 #endif 581 582 #if gsl_ELIDE_CONTRACT_EXPECTS 583 # define gsl_EXPECTS_UNUSED_PARAM( x ) /* Make param unnamed if Expects elided */ 584 #else 585 # define gsl_EXPECTS_UNUSED_PARAM( x ) x 586 #endif 587 588 #if gsl_ELIDE_CONTRACT_ENSURES 589 # define Ensures( x ) /* Ensures elided */ 590 #elif gsl_CONFIG( CONTRACT_VIOLATION_THROWS_V ) 591 # define Ensures( x ) ::gsl::fail_fast_assert( (x), "GSL: Postcondition failure at " __FILE__ ":" gsl_STRINGIFY(__LINE__) ); 592 #else 593 # define Ensures( x ) ::gsl::fail_fast_assert( (x) ) 594 #endif 595 596 #define gsl_STRINGIFY( x ) gsl_STRINGIFY_( x ) 597 #define gsl_STRINGIFY_( x ) #x 598 599 struct fail_fast : public std::logic_error 600 { 601 gsl_api explicit fail_fast( char const * const message ) 602 : std::logic_error( message ) {} 603 }; 604 605 // workaround for gcc 5 throw/terminate constexpr bug: 606 607 #if gsl_BETWEEN( gsl_COMPILER_GNUC_VERSION, 430, 600 ) && gsl_HAVE( CONSTEXPR_14 ) 608 609 # if gsl_CONFIG( CONTRACT_VIOLATION_THROWS_V ) 610 611 gsl_api inline gsl_constexpr14 auto fail_fast_assert( bool cond, char const * const message ) -> void 612 { 613 !cond ? throw fail_fast( message ) : 0; 614 } 615 616 # else 617 618 gsl_api inline gsl_constexpr14 auto fail_fast_assert( bool cond ) -> void 619 { 620 struct F { static gsl_constexpr14 void f(){}; }; 621 622 !cond ? std::terminate() : F::f(); 623 } 624 625 # endif 626 627 #else // workaround 628 629 # if gsl_CONFIG( CONTRACT_VIOLATION_THROWS_V ) 630 631 gsl_api inline gsl_constexpr14 void fail_fast_assert( bool cond, char const * const message ) 632 { 633 if ( !cond ) 634 throw fail_fast( message ); 635 } 636 637 # else 638 639 gsl_api inline gsl_constexpr14 void fail_fast_assert( bool cond ) gsl_noexcept 640 { 641 if ( !cond ) 642 std::terminate(); 643 } 644 645 # endif 646 #endif // workaround 647 648 // 649 // GSL.util: utilities 650 // 651 652 #if gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) 653 654 // Add uncaught_exceptions for pre-2017 MSVC, GCC and Clang 655 // Return unsigned char to save stack space, uncaught_exceptions can only increase by 1 in a scope 656 657 namespace details { 658 659 inline unsigned char to_uchar( unsigned x ) gsl_noexcept 660 { 661 return static_cast<unsigned char>( x ); 662 } 663 664 #if gsl_HAVE( UNCAUGHT_EXCEPTIONS ) 665 666 inline unsigned char uncaught_exceptions() gsl_noexcept 667 { 668 return to_uchar( std::uncaught_exceptions() ); 669 } 670 671 #elif gsl_COMPILER_MSVC_VERSION 672 673 extern "C" char * __cdecl _getptd(); 674 inline unsigned char uncaught_exceptions() gsl_noexcept 675 { 676 return to_uchar( *reinterpret_cast<unsigned*>(_getptd() + (sizeof(void*) == 8 ? 0x100 : 0x90) ) ); 677 } 678 679 #elif gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_GNUC_VERSION 680 681 extern "C" char * __cxa_get_globals(); 682 inline unsigned char uncaught_exceptions() gsl_noexcept 683 { 684 return to_uchar( *reinterpret_cast<unsigned*>(__cxa_get_globals() + sizeof(void*) ) ); 685 } 686 #endif 687 } 688 #endif 689 690 #if gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 110 691 692 template< class F > 693 class final_action 694 { 695 public: 696 gsl_api explicit final_action( F action ) gsl_noexcept 697 : action_( std::move( action ) ) 698 , invoke_( true ) 699 {} 700 701 gsl_api final_action( final_action && other ) gsl_noexcept 702 : action_( std::move( other.action_ ) ) 703 , invoke_( other.invoke_ ) 704 { 705 other.invoke_ = false; 706 } 707 708 gsl_api virtual ~final_action() gsl_noexcept 709 { 710 if ( invoke_ ) 711 action_(); 712 } 713 714 gsl_is_delete_access: 715 gsl_api final_action( final_action const & ) gsl_is_delete; 716 gsl_api final_action & operator=( final_action const & ) gsl_is_delete; 717 gsl_api final_action & operator=( final_action && ) gsl_is_delete; 718 719 protected: 720 gsl_api void dismiss() gsl_noexcept 721 { 722 invoke_ = false; 723 } 724 725 private: 726 F action_; 727 bool invoke_; 728 }; 729 730 template< class F > 731 gsl_api inline final_action<F> finally( F const & action ) gsl_noexcept 732 { 733 return final_action<F>( action ); 734 } 735 736 template< class F > 737 gsl_api inline final_action<F> finally( F && action ) gsl_noexcept 738 { 739 return final_action<F>( std::forward<F>( action ) ); 740 } 741 742 #if gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) 743 744 template< class F > 745 class final_action_return : public final_action<F> 746 { 747 public: 748 gsl_api explicit final_action_return( F && action ) gsl_noexcept 749 : final_action<F>( std::move( action ) ) 750 , exception_count( details::uncaught_exceptions() ) 751 {} 752 753 gsl_api final_action_return( final_action_return && other ) gsl_noexcept 754 : final_action<F>( std::move( other ) ) 755 , exception_count( details::uncaught_exceptions() ) 756 {} 757 758 gsl_api ~final_action_return() override 759 { 760 if ( details::uncaught_exceptions() != exception_count ) 761 this->dismiss(); 762 } 763 764 gsl_is_delete_access: 765 gsl_api final_action_return( final_action_return const & ) gsl_is_delete; 766 gsl_api final_action_return & operator=( final_action_return const & ) gsl_is_delete; 767 768 private: 769 unsigned char exception_count; 770 }; 771 772 template< class F > 773 gsl_api inline final_action_return<F> on_return( F const & action ) gsl_noexcept 774 { 775 return final_action_return<F>( action ); 776 } 777 778 template< class F > 779 gsl_api inline final_action_return<F> on_return( F && action ) gsl_noexcept 780 { 781 return final_action_return<F>( std::forward<F>( action ) ); 782 } 783 784 template< class F > 785 class final_action_error : public final_action<F> 786 { 787 public: 788 gsl_api explicit final_action_error( F && action ) gsl_noexcept 789 : final_action<F>( std::move( action ) ) 790 , exception_count( details::uncaught_exceptions() ) 791 {} 792 793 gsl_api final_action_error( final_action_error && other ) gsl_noexcept 794 : final_action<F>( std::move( other ) ) 795 , exception_count( details::uncaught_exceptions() ) 796 {} 797 798 gsl_api ~final_action_error() override 799 { 800 if ( details::uncaught_exceptions() == exception_count ) 801 this->dismiss(); 802 } 803 804 gsl_is_delete_access: 805 gsl_api final_action_error( final_action_error const & ) gsl_is_delete; 806 gsl_api final_action_error & operator=( final_action_error const & ) gsl_is_delete; 807 808 private: 809 unsigned char exception_count; 810 }; 811 812 template< class F > 813 gsl_api inline final_action_error<F> on_error( F const & action ) gsl_noexcept 814 { 815 return final_action_error<F>( action ); 816 } 817 818 template< class F > 819 gsl_api inline final_action_error<F> on_error( F && action ) gsl_noexcept 820 { 821 return final_action_error<F>( std::forward<F>( action ) ); 822 } 823 824 #endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) 825 826 #else // gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 110 827 828 class final_action 829 { 830 public: 831 typedef void (*Action)(); 832 833 gsl_api final_action( Action action ) 834 : action_( action ) 835 , invoke_( true ) 836 {} 837 838 gsl_api final_action( final_action const & other ) 839 : action_( other.action_ ) 840 , invoke_( other.invoke_ ) 841 { 842 other.invoke_ = false; 843 } 844 845 gsl_api virtual ~final_action() 846 { 847 if ( invoke_ ) 848 action_(); 849 } 850 851 protected: 852 gsl_api void dismiss() 853 { 854 invoke_ = false; 855 } 856 857 private: 858 gsl_api final_action & operator=( final_action const & ); 859 860 private: 861 Action action_; 862 mutable bool invoke_; 863 }; 864 865 template< class F > 866 gsl_api inline final_action finally( F const & f ) 867 { 868 return final_action(( f )); 869 } 870 871 #if gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) 872 873 class final_action_return : public final_action 874 { 875 public: 876 gsl_api explicit final_action_return( Action action ) 877 : final_action( action ) 878 , exception_count( details::uncaught_exceptions() ) 879 {} 880 881 gsl_api ~final_action_return() 882 { 883 if ( details::uncaught_exceptions() != exception_count ) 884 this->dismiss(); 885 } 886 887 private: 888 gsl_api final_action_return & operator=( final_action_return const & ); 889 890 private: 891 unsigned char exception_count; 892 }; 893 894 template< class F > 895 gsl_api inline final_action_return on_return( F const & action ) 896 { 897 return final_action_return( action ); 898 } 899 900 class final_action_error : public final_action 901 { 902 public: 903 gsl_api explicit final_action_error( Action action ) 904 : final_action( action ) 905 , exception_count( details::uncaught_exceptions() ) 906 {} 907 908 gsl_api ~final_action_error() 909 { 910 if ( details::uncaught_exceptions() == exception_count ) 911 this->dismiss(); 912 } 913 914 private: 915 gsl_api final_action_error & operator=( final_action_error const & ); 916 917 private: 918 unsigned char exception_count; 919 }; 920 921 template< class F > 922 gsl_api inline final_action_error on_error( F const & action ) 923 { 924 return final_action_error( action ); 925 } 926 927 #endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) 928 929 #endif // gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION == 110 930 931 #if gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120 932 933 template< class T, class U > 934 gsl_api inline gsl_constexpr T narrow_cast( U && u ) gsl_noexcept 935 { 936 return static_cast<T>( std::forward<U>( u ) ); 937 } 938 939 #else 940 941 template< class T, class U > 942 gsl_api inline T narrow_cast( U u ) gsl_noexcept 943 { 944 return static_cast<T>( u ); 945 } 946 947 #endif // gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120 948 949 struct narrowing_error : public std::exception {}; 950 951 #if gsl_HAVE( TYPE_TRAITS ) 952 953 namespace details 954 { 955 template< class T, class U > 956 struct is_same_signedness : public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value> 957 {}; 958 } 959 #endif 960 961 template< class T, class U > 962 gsl_api inline T narrow( U u ) 963 { 964 T t = narrow_cast<T>( u ); 965 966 if ( static_cast<U>( t ) != u ) 967 { 968 #if gsl_CONFIG( CONTRACT_VIOLATION_THROWS_V ) 969 throw narrowing_error(); 970 #else 971 std::terminate(); 972 #endif 973 } 974 975 #if gsl_HAVE( TYPE_TRAITS ) 976 # if gsl_COMPILER_MSVC_VERSION 977 // Suppress MSVC level 4 warning C4127 (conditional expression is constant) 978 if ( 0, ! details::is_same_signedness<T, U>::value && ( ( t < T() ) != ( u < U() ) ) ) 979 # else 980 if ( ! details::is_same_signedness<T, U>::value && ( ( t < T() ) != ( u < U() ) ) ) 981 # endif 982 #else 983 // Don't assume T() works: 984 if ( ( t < 0 ) != ( u < 0 ) ) 985 #endif 986 { 987 #if gsl_CONFIG( CONTRACT_VIOLATION_THROWS_V ) 988 throw narrowing_error(); 989 #else 990 std::terminate(); 991 #endif 992 } 993 return t; 994 } 995 996 // 997 // at() - Bounds-checked way of accessing static arrays, std::array, std::vector. 998 // 999 1000 template< class T, size_t N > 1001 gsl_api inline gsl_constexpr14 T & at( T(&arr)[N], size_t index ) 1002 { 1003 Expects( index < N ); 1004 return arr[index]; 1005 } 1006 1007 #if gsl_HAVE( ARRAY ) 1008 1009 template< class T, size_t N > 1010 gsl_api inline gsl_constexpr14 T & at( std::array<T, N> & arr, size_t index ) 1011 { 1012 Expects( index < N ); 1013 return arr[index]; 1014 } 1015 #endif 1016 1017 template< class Container > 1018 gsl_api inline gsl_constexpr14 auto at(Container & cont, size_t index)->decltype(cont[0]) 1019 { 1020 Expects( index < cont.size() ); 1021 return cont[index]; 1022 } 1023 1024 #if gsl_HAVE( INITIALIZER_LIST ) 1025 1026 template< class T > 1027 gsl_api inline const gsl_constexpr14 T & at( std::initializer_list<T> cont, size_t index ) 1028 { 1029 Expects( index < cont.size() ); 1030 return *( cont.begin() + index ); 1031 } 1032 #endif 1033 1034 template< class T > 1035 gsl_api inline gsl_constexpr T & at( span<T> s, size_t index ) 1036 { 1037 return s.at( index ); 1038 } 1039 1040 // 1041 // GSL.views: views 1042 // 1043 1044 // 1045 // not_null<> - Wrap any indirection and enforce non-null. 1046 // 1047 template< class T > 1048 class not_null 1049 { 1050 #if gsl_CONFIG( NOT_NULL_EXPLICIT_CTOR ) 1051 # define gsl_not_null_explicit explicit 1052 #else 1053 # define gsl_not_null_explicit /*explicit*/ 1054 #endif 1055 1056 #if gsl_CONFIG( NOT_NULL_GET_BY_CONST_REF ) 1057 typedef T const & get_result_t; 1058 #else 1059 typedef T get_result_t; 1060 #endif 1061 1062 public: 1063 #if gsl_HAVE( TYPE_TRAITS ) 1064 static_assert( std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr." ); 1065 #endif 1066 1067 template< class U 1068 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 1069 , class Dummy = typename std::enable_if<std::is_constructible<T, U>::value>::type 1070 #endif 1071 > 1072 gsl_api gsl_constexpr14 gsl_not_null_explicit 1073 #if gsl_HAVE( RVALUE_REFERENCE ) 1074 not_null( U && u ) 1075 : ptr_( std::forward<U>( u ) ) 1076 #else 1077 not_null( U const & u ) 1078 : ptr_( u ) 1079 #endif 1080 { 1081 Expects( ptr_ != gsl_nullptr ); 1082 } 1083 #undef gsl_not_null_explicit 1084 1085 #if gsl_HAVE( IS_DEFAULT ) 1086 gsl_api ~not_null() = default; 1087 gsl_api gsl_constexpr not_null( not_null && other ) = default; 1088 gsl_api gsl_constexpr not_null( not_null const & other ) = default; 1089 gsl_api not_null & operator=( not_null && other ) = default; 1090 gsl_api not_null & operator=( not_null const & other ) = default; 1091 #else 1092 gsl_api ~not_null() {}; 1093 gsl_api gsl_constexpr not_null( not_null const & other ) : ptr_ ( other.ptr_ ) {} 1094 gsl_api not_null & operator=( not_null const & other ) { ptr_ = other.ptr_; return *this; } 1095 # if gsl_HAVE( RVALUE_REFERENCE ) 1096 gsl_api gsl_constexpr not_null( not_null && other ) : ptr_( std::move( other.get() ) ) {} 1097 gsl_api not_null & operator=( not_null && other ) { ptr_ = std::move( other.get() ); return *this; } 1098 # endif 1099 #endif 1100 1101 template< class U 1102 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 1103 , class Dummy = typename std::enable_if<std::is_convertible<U, T>::value>::type 1104 #endif 1105 > 1106 gsl_api gsl_constexpr not_null( not_null<U> const & other ) 1107 : ptr_( other.get() ) 1108 {} 1109 1110 gsl_api gsl_constexpr14 get_result_t get() const 1111 { 1112 // Without cheating and changing ptr_ from the outside, this check is superfluous: 1113 Ensures( ptr_ != gsl_nullptr ); 1114 return ptr_; 1115 } 1116 1117 gsl_api gsl_constexpr operator get_result_t () const { return get(); } 1118 gsl_api gsl_constexpr get_result_t operator->() const { return get(); } 1119 1120 #if gsl_HAVE( DECLTYPE_AUTO ) 1121 gsl_api gsl_constexpr decltype(auto) operator*() const { return *get(); } 1122 #endif 1123 1124 gsl_is_delete_access: 1125 // prevent compilation when initialized with a nullptr or literal 0: 1126 #if gsl_HAVE( NULLPTR ) 1127 gsl_api not_null( std::nullptr_t ) gsl_is_delete; 1128 gsl_api not_null & operator=( std::nullptr_t ) gsl_is_delete; 1129 #else 1130 gsl_api not_null( int ) gsl_is_delete; 1131 gsl_api not_null & operator=( int ) gsl_is_delete; 1132 #endif 1133 1134 // unwanted operators...pointers only point to single objects! 1135 gsl_api not_null & operator++() gsl_is_delete; 1136 gsl_api not_null & operator--() gsl_is_delete; 1137 gsl_api not_null operator++( int ) gsl_is_delete; 1138 gsl_api not_null operator--( int ) gsl_is_delete; 1139 gsl_api not_null & operator+ ( size_t ) gsl_is_delete; 1140 gsl_api not_null & operator+=( size_t ) gsl_is_delete; 1141 gsl_api not_null & operator- ( size_t ) gsl_is_delete; 1142 gsl_api not_null & operator-=( size_t ) gsl_is_delete; 1143 gsl_api not_null & operator+=( std::ptrdiff_t ) gsl_is_delete; 1144 gsl_api not_null & operator-=( std::ptrdiff_t ) gsl_is_delete; 1145 gsl_api void operator[]( std::ptrdiff_t ) const gsl_is_delete; 1146 1147 private: 1148 T ptr_; 1149 }; 1150 1151 // not_null with implicit constructor, allowing copy-initialization: 1152 1153 template< class T > 1154 class not_null_ic : public not_null<T> 1155 { 1156 public: 1157 template< class U 1158 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 1159 , class Dummy = typename std::enable_if<std::is_constructible<T, U>::value>::type 1160 #endif 1161 > 1162 gsl_api gsl_constexpr14 1163 #if gsl_HAVE( RVALUE_REFERENCE ) 1164 not_null_ic( U && u ) 1165 : not_null<T>( std::forward<U>( u ) ) 1166 #else 1167 not_null_ic( U const & u ) 1168 : not_null<T>( u ) 1169 #endif 1170 {} 1171 }; 1172 1173 // more not_null unwanted operators 1174 1175 template< class T, class U > 1176 std::ptrdiff_t operator-( not_null<T> const &, not_null<U> const & ) gsl_is_delete; 1177 1178 template< class T > 1179 not_null<T> operator-( not_null<T> const &, std::ptrdiff_t ) gsl_is_delete; 1180 1181 template< class T > 1182 not_null<T> operator+( not_null<T> const &, std::ptrdiff_t ) gsl_is_delete; 1183 1184 template< class T > 1185 not_null<T> operator+( std::ptrdiff_t, not_null<T> const & ) gsl_is_delete; 1186 1187 // not_null comparisons 1188 1189 template< class T, class U > 1190 gsl_api inline gsl_constexpr bool operator==( not_null<T> const & l, not_null<U> const & r ) 1191 { 1192 return l.get() == r.get(); 1193 } 1194 1195 template< class T, class U > 1196 gsl_api inline gsl_constexpr bool operator< ( not_null<U> const & l, not_null<U> const & r ) 1197 { 1198 return l.get() < r.get(); 1199 } 1200 1201 template< class T, class U > 1202 gsl_api inline gsl_constexpr bool operator!=( not_null<U> const & l, not_null<U> const & r ) 1203 { 1204 return !( l == r ); 1205 } 1206 1207 template< class T, class U > 1208 gsl_api inline gsl_constexpr bool operator<=( not_null<U> const & l, not_null<U> const & r ) 1209 { 1210 return !( r < l ); 1211 } 1212 1213 template< class T, class U > 1214 gsl_api inline gsl_constexpr bool operator> ( not_null<U> const & l, not_null<U> const & r ) 1215 { 1216 return ( r < l ); 1217 } 1218 1219 template< class T, class U > 1220 gsl_api inline gsl_constexpr bool operator>=( not_null<U> const & l, not_null<U> const & r ) 1221 { 1222 return !( l < r ); 1223 } 1224 1225 // 1226 // Byte-specific type. 1227 // 1228 #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) 1229 enum class gsl_may_alias byte : unsigned char {}; 1230 #else 1231 struct gsl_may_alias byte { typedef unsigned char type; type v; }; 1232 #endif 1233 1234 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 1235 # define gsl_ENABLE_IF_INTEGRAL_T(T) \ 1236 , class = typename std::enable_if<std::is_integral<T>::value>::type 1237 #else 1238 # define gsl_ENABLE_IF_INTEGRAL_T(T) 1239 #endif 1240 1241 template< class T > 1242 gsl_api inline gsl_constexpr byte to_byte( T v ) gsl_noexcept 1243 { 1244 #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) 1245 return static_cast<byte>( v ); 1246 #elif gsl_HAVE( CONSTEXPR_11 ) 1247 return { static_cast<typename byte::type>( v ) }; 1248 #else 1249 byte b = { static_cast<typename byte::type>( v ) }; return b; 1250 #endif 1251 } 1252 1253 template< class IntegerType gsl_ENABLE_IF_INTEGRAL_T( IntegerType ) > 1254 gsl_api inline gsl_constexpr IntegerType to_integer( byte b ) gsl_noexcept 1255 { 1256 #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) 1257 return static_cast<typename std::underlying_type<byte>::type>( b ); 1258 #else 1259 return b.v; 1260 #endif 1261 } 1262 1263 gsl_api inline gsl_constexpr unsigned char to_uchar( byte b ) gsl_noexcept 1264 { 1265 return to_integer<unsigned char>( b ); 1266 } 1267 1268 gsl_api inline gsl_constexpr unsigned char to_uchar( int i ) gsl_noexcept 1269 { 1270 return static_cast<unsigned char>( i ); 1271 } 1272 1273 #if ! gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) 1274 1275 gsl_api inline gsl_constexpr bool operator==( byte l, byte r ) gsl_noexcept 1276 { 1277 return l.v == r.v; 1278 } 1279 1280 gsl_api inline gsl_constexpr bool operator!=( byte l, byte r ) gsl_noexcept 1281 { 1282 return !( l == r ); 1283 } 1284 1285 gsl_api inline gsl_constexpr bool operator< ( byte l, byte r ) gsl_noexcept 1286 { 1287 return l.v < r.v; 1288 } 1289 1290 gsl_api inline gsl_constexpr bool operator<=( byte l, byte r ) gsl_noexcept 1291 { 1292 return !( r < l ); 1293 } 1294 1295 gsl_api inline gsl_constexpr bool operator> ( byte l, byte r ) gsl_noexcept 1296 { 1297 return ( r < l ); 1298 } 1299 1300 gsl_api inline gsl_constexpr bool operator>=( byte l, byte r ) gsl_noexcept 1301 { 1302 return !( l < r ); 1303 } 1304 #endif 1305 1306 template< class IntegerType gsl_ENABLE_IF_INTEGRAL_T( IntegerType ) > 1307 gsl_api inline gsl_constexpr14 byte & operator<<=( byte & b, IntegerType shift ) gsl_noexcept 1308 { 1309 #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) 1310 return b = to_byte( to_uchar( b ) << shift ); 1311 #else 1312 b.v = to_uchar( b.v << shift ); return b; 1313 #endif 1314 } 1315 1316 template< class IntegerType gsl_ENABLE_IF_INTEGRAL_T( IntegerType ) > 1317 gsl_api inline gsl_constexpr byte operator<<( byte b, IntegerType shift ) gsl_noexcept 1318 { 1319 return to_byte( to_uchar( b ) << shift ); 1320 } 1321 1322 template< class IntegerType gsl_ENABLE_IF_INTEGRAL_T( IntegerType ) > 1323 gsl_api inline gsl_constexpr14 byte & operator>>=( byte & b, IntegerType shift ) gsl_noexcept 1324 { 1325 #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) 1326 return b = to_byte( to_uchar( b ) >> shift ); 1327 #else 1328 b.v = to_uchar( b.v >> shift ); return b; 1329 #endif 1330 } 1331 1332 template< class IntegerType gsl_ENABLE_IF_INTEGRAL_T( IntegerType ) > 1333 gsl_api inline gsl_constexpr byte operator>>( byte b, IntegerType shift ) gsl_noexcept 1334 { 1335 return to_byte( to_uchar( b ) >> shift ); 1336 } 1337 1338 gsl_api inline gsl_constexpr14 byte & operator|=( byte & l, byte r ) gsl_noexcept 1339 { 1340 #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) 1341 return l = to_byte( to_uchar( l ) | to_uchar( r ) ); 1342 #else 1343 l.v = to_uchar( l ) | to_uchar( r ); return l; 1344 #endif 1345 } 1346 1347 gsl_api inline gsl_constexpr byte operator|( byte l, byte r ) gsl_noexcept 1348 { 1349 return to_byte( to_uchar( l ) | to_uchar( r ) ); 1350 } 1351 1352 gsl_api inline gsl_constexpr14 byte & operator&=( byte & l, byte r ) gsl_noexcept 1353 { 1354 #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) 1355 return l = to_byte( to_uchar( l ) & to_uchar( r ) ); 1356 #else 1357 l.v = to_uchar( l ) & to_uchar( r ); return l; 1358 #endif 1359 } 1360 1361 gsl_api inline gsl_constexpr byte operator&( byte l, byte r ) gsl_noexcept 1362 { 1363 return to_byte( to_uchar( l ) & to_uchar( r ) ); 1364 } 1365 1366 gsl_api inline gsl_constexpr14 byte & operator^=( byte & l, byte r ) gsl_noexcept 1367 { 1368 #if gsl_HAVE( ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE ) 1369 return l = to_byte( to_uchar( l ) ^ to_uchar (r ) ); 1370 #else 1371 l.v = to_uchar( l ) ^ to_uchar (r ); return l; 1372 #endif 1373 } 1374 1375 gsl_api inline gsl_constexpr byte operator^( byte l, byte r ) gsl_noexcept 1376 { 1377 return to_byte( to_uchar( l ) ^ to_uchar( r ) ); 1378 } 1379 1380 gsl_api inline gsl_constexpr byte operator~( byte b ) gsl_noexcept 1381 { 1382 return to_byte( ~to_uchar( b ) ); 1383 } 1384 1385 #if gsl_FEATURE_TO_STD( WITH_CONTAINER ) 1386 1387 // Tag to select span constructor taking a container (prevent ms-gsl warning C26426): 1388 1389 struct with_container_t { gsl_constexpr with_container_t() gsl_noexcept {} }; 1390 const gsl_constexpr with_container_t with_container; 1391 1392 #endif 1393 1394 #if gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) 1395 1396 namespace details { 1397 1398 // Can construct from containers that: 1399 1400 template< 1401 class Container, class ElementType 1402 , class = typename std::enable_if< 1403 ! details::is_span< Container >::value && 1404 ! details::is_array< Container >::value && 1405 ! details::is_std_array< Container >::value && 1406 std::is_convertible<typename std::remove_pointer<decltype(std::declval<Container>().data())>::type(*)[], ElementType(*)[] >::value 1407 >::type 1408 #if gsl_HAVE( STD_DATA ) 1409 // data(cont) and size(cont) well-formed: 1410 , class = decltype( std::data( std::declval<Container>() ) ) 1411 , class = decltype( std::size( std::declval<Container>() ) ) 1412 #endif 1413 > 1414 struct can_construct_span_from : details::true_type{}; 1415 1416 } // namespace details 1417 #endif 1418 1419 // 1420 // span<> - A 1D view of contiguous T's, replace (*,len). 1421 // 1422 template< class T > 1423 class span 1424 { 1425 template< class U > friend class span; 1426 1427 public: 1428 typedef index index_type; 1429 1430 typedef T element_type; 1431 typedef typename details::remove_cv< T >::type value_type; 1432 1433 typedef T & reference; 1434 typedef T * pointer; 1435 typedef T const * const_pointer; 1436 typedef T const & const_reference; 1437 1438 typedef pointer iterator; 1439 typedef const_pointer const_iterator; 1440 1441 typedef std::reverse_iterator< iterator > reverse_iterator; 1442 typedef std::reverse_iterator< const_iterator > const_reverse_iterator; 1443 1444 typedef typename std::iterator_traits< iterator >::difference_type difference_type; 1445 1446 // 26.7.3.2 Constructors, copy, and assignment [span.cons] 1447 1448 gsl_api gsl_constexpr14 span() gsl_noexcept 1449 : first_( gsl_nullptr ) 1450 , last_ ( gsl_nullptr ) 1451 { 1452 Expects( size() == 0 ); 1453 } 1454 1455 #if ! gsl_DEPRECATE_TO_LEVEL( 5 ) 1456 1457 #if gsl_HAVE( NULLPTR ) 1458 gsl_api gsl_constexpr14 span( std::nullptr_t, index_type gsl_EXPECTS_UNUSED_PARAM( size_in ) ) 1459 : first_( nullptr ) 1460 , last_ ( nullptr ) 1461 { 1462 Expects( size_in == 0 ); 1463 } 1464 #endif 1465 1466 #if gsl_HAVE( IS_DELETE ) 1467 gsl_api gsl_constexpr span( reference data_in ) 1468 : span( &data_in, 1 ) 1469 {} 1470 1471 gsl_api gsl_constexpr span( element_type && ) = delete; 1472 #endif 1473 1474 #endif // deprecate 1475 1476 gsl_api gsl_constexpr14 span( pointer data_in, index_type size_in ) 1477 : first_( data_in ) 1478 , last_ ( data_in + size_in ) 1479 { 1480 Expects( size_in == 0 || ( size_in > 0 && data_in != gsl_nullptr ) ); 1481 } 1482 1483 gsl_api gsl_constexpr14 span( pointer first_in, pointer last_in ) 1484 : first_( first_in ) 1485 , last_ ( last_in ) 1486 { 1487 Expects( first_in <= last_in ); 1488 } 1489 1490 #if ! gsl_DEPRECATE_TO_LEVEL( 5 ) 1491 1492 template< class U > 1493 gsl_api gsl_constexpr14 span( U * & data_in, index_type size_in ) 1494 : first_( data_in ) 1495 , last_ ( data_in + size_in ) 1496 { 1497 Expects( size_in == 0 || ( size_in > 0 && data_in != gsl_nullptr ) ); 1498 } 1499 1500 template< class U > 1501 gsl_api gsl_constexpr14 span( U * const & data_in, index_type size_in ) 1502 : first_( data_in ) 1503 , last_ ( data_in + size_in ) 1504 { 1505 Expects( size_in == 0 || ( size_in > 0 && data_in != gsl_nullptr ) ); 1506 } 1507 1508 #endif // deprecate 1509 1510 #if ! gsl_DEPRECATE_TO_LEVEL( 5 ) 1511 template< class U, size_t N > 1512 gsl_api gsl_constexpr span( U (&arr)[N] ) gsl_noexcept 1513 : first_( gsl_ADDRESSOF( arr[0] ) ) 1514 , last_ ( gsl_ADDRESSOF( arr[0] ) + N ) 1515 {} 1516 #else 1517 template< size_t N 1518 # if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 1519 , class = typename std::enable_if< 1520 std::is_convertible<value_type(*)[], element_type(*)[] >::value 1521 >::type 1522 # endif 1523 > 1524 gsl_api gsl_constexpr span( element_type (&arr)[N] ) gsl_noexcept 1525 : first_( gsl_ADDRESSOF( arr[0] ) ) 1526 , last_ ( gsl_ADDRESSOF( arr[0] ) + N ) 1527 {} 1528 #endif // deprecate 1529 1530 #if gsl_HAVE( ARRAY ) 1531 #if ! gsl_DEPRECATE_TO_LEVEL( 5 ) 1532 1533 template< class U, size_t N > 1534 gsl_api gsl_constexpr span( std::array< U, N > & arr ) 1535 : first_( arr.data() ) 1536 , last_ ( arr.data() + N ) 1537 {} 1538 1539 template< class U, size_t N > 1540 gsl_api gsl_constexpr span( std::array< U, N > const & arr ) 1541 : first_( arr.data() ) 1542 , last_ ( arr.data() + N ) 1543 {} 1544 1545 #else 1546 1547 template< size_t N 1548 # if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 1549 , class = typename std::enable_if< 1550 std::is_convertible<value_type(*)[], element_type(*)[] >::value 1551 >::type 1552 # endif 1553 > 1554 gsl_api gsl_constexpr span( std::array< value_type, N > & arr ) 1555 : first_( arr.data() ) 1556 , last_ ( arr.data() + N ) 1557 {} 1558 1559 template< size_t N 1560 # if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 1561 , class = typename std::enable_if< 1562 std::is_convertible<value_type(*)[], element_type(*)[] >::value 1563 >::type 1564 # endif 1565 > 1566 gsl_api gsl_constexpr span( std::array< value_type, N > const & arr ) 1567 : first_( arr.data() ) 1568 , last_ ( arr.data() + N ) 1569 {} 1570 1571 #endif // deprecate 1572 #endif // gsl_HAVE( ARRAY ) 1573 1574 #if gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) 1575 template< class Container 1576 , class = typename std::enable_if< 1577 details::can_construct_span_from< Container, element_type >::value 1578 >::type 1579 > 1580 gsl_api gsl_constexpr span( Container & cont ) 1581 : first_( cont.data() ) 1582 , last_ ( cont.data() + cont.size() ) 1583 {} 1584 1585 template< class Container 1586 , class = typename std::enable_if< 1587 std::is_const< element_type >::value && 1588 details::can_construct_span_from< Container, element_type >::value 1589 >::type 1590 > 1591 gsl_api gsl_constexpr span( Container const & cont ) 1592 : first_( cont.data() ) 1593 , last_ ( cont.data() + cont.size() ) 1594 {} 1595 1596 #elif gsl_HAVE( UNCONSTRAINED_SPAN_CONTAINER_CTOR ) 1597 1598 template< class Container > 1599 gsl_api gsl_constexpr span( Container & cont ) 1600 : first_( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) ) 1601 , last_ ( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) + cont.size() ) 1602 {} 1603 1604 template< class Container > 1605 gsl_api gsl_constexpr span( Container const & cont ) 1606 : first_( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) ) 1607 , last_ ( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) + cont.size() ) 1608 {} 1609 1610 #endif 1611 1612 #if gsl_FEATURE_TO_STD( WITH_CONTAINER ) 1613 1614 template< class Container > 1615 gsl_api gsl_constexpr span( with_container_t, Container & cont ) 1616 : first_( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) ) 1617 , last_ ( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) + cont.size() ) 1618 {} 1619 1620 template< class Container > 1621 gsl_api gsl_constexpr span( with_container_t, Container const & cont ) 1622 : first_( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) ) 1623 , last_ ( cont.size() == 0 ? gsl_nullptr : gsl_ADDRESSOF( cont[0] ) + cont.size() ) 1624 {} 1625 1626 #endif 1627 1628 #if ! gsl_DEPRECATE_TO_LEVEL( 4 ) 1629 // constructor taking shared_ptr deprecated since 0.29.0 1630 1631 #if gsl_HAVE( SHARED_PTR ) 1632 gsl_api gsl_constexpr span( shared_ptr<element_type> const & ptr ) 1633 : first_( ptr.get() ) 1634 , last_ ( ptr.get() ? ptr.get() + 1 : 0 ) 1635 {} 1636 #endif 1637 1638 // constructors taking unique_ptr deprecated since 0.29.0 1639 1640 #if gsl_HAVE( UNIQUE_PTR ) 1641 # if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 1642 template< class ArrayElementType = typename std::add_pointer<element_type>::type > 1643 # else 1644 template< class ArrayElementType > 1645 # endif 1646 gsl_api gsl_constexpr span( unique_ptr<ArrayElementType> const & ptr, index_type count ) 1647 : first_( ptr.get() ) 1648 , last_ ( ptr.get() + count ) 1649 {} 1650 1651 gsl_api gsl_constexpr span( unique_ptr<element_type> const & ptr ) 1652 : first_( ptr.get() ) 1653 , last_ ( ptr.get() ? ptr.get() + 1 : 0 ) 1654 {} 1655 #endif 1656 1657 #endif // deprecate shared_ptr, unique_ptr 1658 1659 #if gsl_HAVE( IS_DEFAULT ) && ! gsl_BETWEEN( gsl_COMPILER_GNUC_VERSION, 430, 600) 1660 gsl_api gsl_constexpr span( span && ) gsl_noexcept = default; 1661 gsl_api gsl_constexpr span( span const & ) = default; 1662 #else 1663 gsl_api gsl_constexpr span( span const & other ) 1664 : first_( other.begin() ) 1665 , last_ ( other.end() ) 1666 {} 1667 #endif 1668 1669 #if gsl_HAVE( IS_DEFAULT ) 1670 ~span() = default; 1671 #else 1672 ~span() {} 1673 #endif 1674 1675 #if gsl_HAVE( IS_DEFAULT ) 1676 gsl_api gsl_constexpr14 span & operator=( span && ) gsl_noexcept = default; 1677 gsl_api gsl_constexpr14 span & operator=( span const & ) gsl_noexcept = default; 1678 #else 1679 gsl_api span & operator=( span other ) gsl_noexcept 1680 { 1681 other.swap( *this ); 1682 return *this; 1683 } 1684 #endif 1685 1686 template< class U 1687 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 1688 , class = typename std::enable_if< 1689 std::is_convertible<U(*)[], element_type(*)[]>::value 1690 >::type 1691 #endif 1692 > 1693 gsl_api gsl_constexpr span( span<U> const & other ) 1694 : first_( other.begin() ) 1695 , last_ ( other.end() ) 1696 {} 1697 1698 #if 0 1699 // Converting from other span ? 1700 template< class U > operator=(); 1701 #endif 1702 1703 // 26.7.3.3 Subviews [span.sub] 1704 1705 gsl_api gsl_constexpr14 span first( index_type count ) const gsl_noexcept 1706 { 1707 Expects( 0 <= count && count <= this->size() ); 1708 return span( this->data(), count ); 1709 } 1710 1711 gsl_api gsl_constexpr14 span last( index_type count ) const gsl_noexcept 1712 { 1713 Expects( 0 <= count && count <= this->size() ); 1714 return span( this->data() + this->size() - count, count ); 1715 } 1716 1717 gsl_api gsl_constexpr14 span subspan( index_type offset ) const gsl_noexcept 1718 { 1719 Expects( 0 <= offset && offset <= this->size() ); 1720 return span( this->data() + offset, this->size() - offset ); 1721 } 1722 1723 gsl_api gsl_constexpr14 span subspan( index_type offset, index_type count ) const gsl_noexcept 1724 { 1725 Expects( 1726 0 <= offset && offset <= this->size() && 1727 0 <= count && count + offset <= this->size() ); 1728 return span( this->data() + offset, count ); 1729 } 1730 1731 // 26.7.3.4 Observers [span.obs] 1732 1733 gsl_api gsl_constexpr index_type size() const gsl_noexcept 1734 { 1735 return narrow_cast<index_type>( last_ - first_ ); 1736 } 1737 1738 gsl_api gsl_constexpr index_type size_bytes() const gsl_noexcept 1739 { 1740 return size() * narrow_cast<index_type>( sizeof( element_type ) ); 1741 } 1742 1743 gsl_api gsl_constexpr bool empty() const gsl_noexcept 1744 { 1745 return size() == 0; 1746 } 1747 1748 // 26.7.3.5 Element access [span.elem] 1749 1750 gsl_api gsl_constexpr reference operator[]( index_type index ) const 1751 { 1752 return at( index ); 1753 } 1754 1755 gsl_api gsl_constexpr reference operator()( index_type index ) const 1756 { 1757 return at( index ); 1758 } 1759 1760 gsl_api gsl_constexpr14 reference at( index_type index ) const 1761 { 1762 Expects( index < size() ); 1763 return first_[ index ]; 1764 } 1765 1766 gsl_api gsl_constexpr pointer data() const gsl_noexcept 1767 { 1768 return first_; 1769 } 1770 1771 // 26.7.3.6 Iterator support [span.iterators] 1772 1773 gsl_api gsl_constexpr iterator begin() const gsl_noexcept 1774 { 1775 return iterator( first_ ); 1776 } 1777 1778 gsl_api gsl_constexpr iterator end() const gsl_noexcept 1779 { 1780 return iterator( last_ ); 1781 } 1782 1783 gsl_api gsl_constexpr const_iterator cbegin() const gsl_noexcept 1784 { 1785 #if gsl_CPP11_OR_GREATER 1786 return { begin() }; 1787 #else 1788 return const_iterator( begin() ); 1789 #endif 1790 } 1791 1792 gsl_api gsl_constexpr const_iterator cend() const gsl_noexcept 1793 { 1794 #if gsl_CPP11_OR_GREATER 1795 return { end() }; 1796 #else 1797 return const_iterator( end() ); 1798 #endif 1799 } 1800 1801 gsl_api gsl_constexpr reverse_iterator rbegin() const gsl_noexcept 1802 { 1803 return reverse_iterator( end() ); 1804 } 1805 1806 gsl_api gsl_constexpr reverse_iterator rend() const gsl_noexcept 1807 { 1808 return reverse_iterator( begin() ); 1809 } 1810 1811 gsl_api gsl_constexpr const_reverse_iterator crbegin() const gsl_noexcept 1812 { 1813 return const_reverse_iterator( cend() ); 1814 } 1815 1816 gsl_api gsl_constexpr const_reverse_iterator crend() const gsl_noexcept 1817 { 1818 return const_reverse_iterator( cbegin() ); 1819 } 1820 1821 gsl_api void swap( span & other ) gsl_noexcept 1822 { 1823 using std::swap; 1824 swap( first_, other.first_ ); 1825 swap( last_ , other.last_ ); 1826 } 1827 1828 #if ! gsl_DEPRECATE_TO_LEVEL( 3 ) 1829 // member length() deprecated since 0.29.0 1830 1831 gsl_api gsl_constexpr index_type length() const gsl_noexcept 1832 { 1833 return size(); 1834 } 1835 1836 // member length_bytes() deprecated since 0.29.0 1837 1838 gsl_api gsl_constexpr index_type length_bytes() const gsl_noexcept 1839 { 1840 return size_bytes(); 1841 } 1842 #endif 1843 1844 #if ! gsl_DEPRECATE_TO_LEVEL( 2 ) 1845 // member as_bytes(), as_writeable_bytes deprecated since 0.17.0 1846 1847 gsl_api span< const byte > as_bytes() const gsl_noexcept 1848 { 1849 return span< const byte >( reinterpret_cast<const byte *>( data() ), size_bytes() ); // NOLINT 1850 } 1851 1852 gsl_api span< byte > as_writeable_bytes() const gsl_noexcept 1853 { 1854 return span< byte >( reinterpret_cast<byte *>( data() ), size_bytes() ); // NOLINT 1855 } 1856 1857 #endif 1858 1859 template< class U > 1860 gsl_api span< U > as_span() const gsl_noexcept 1861 { 1862 Expects( ( this->size_bytes() % sizeof(U) ) == 0 ); 1863 return span< U >( reinterpret_cast<U *>( this->data() ), this->size_bytes() / sizeof( U ) ); // NOLINT 1864 } 1865 1866 private: 1867 pointer first_; 1868 pointer last_; 1869 }; 1870 1871 // class template argument deduction guides: 1872 1873 #if gsl_HAVE( DEDUCTION_GUIDES ) // gsl_CPP17_OR_GREATER 1874 1875 template< class T, size_t N > 1876 span( T (&)[N] ) -> span<T /*, N*/>; 1877 1878 template< class T, size_t N > 1879 span( std::array<T, N> & ) -> span<T /*, N*/>; 1880 1881 template< class T, size_t N > 1882 span( std::array<T, N> const & ) -> span<const T /*, N*/>; 1883 1884 template< class Container > 1885 span( Container& ) -> span<typename Container::value_type>; 1886 1887 template< class Container > 1888 span( Container const & ) -> span<const typename Container::value_type>; 1889 1890 #endif // gsl_HAVE( DEDUCTION_GUIDES ) 1891 1892 // 26.7.3.7 Comparison operators [span.comparison] 1893 1894 #if gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) 1895 1896 template< class T, class U > 1897 gsl_api inline gsl_constexpr bool operator==( span<T> const & l, span<U> const & r ) 1898 { 1899 return l.size() == r.size() 1900 && (l.begin() == r.begin() || std::equal( l.begin(), l.end(), r.begin() ) ); 1901 } 1902 1903 template< class T, class U > 1904 gsl_api inline gsl_constexpr bool operator< ( span<T> const & l, span<U> const & r ) 1905 { 1906 return std::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); 1907 } 1908 1909 #else 1910 1911 template< class T > 1912 gsl_api inline gsl_constexpr bool operator==( span<T> const & l, span<T> const & r ) 1913 { 1914 return l.size() == r.size() 1915 && (l.begin() == r.begin() || std::equal( l.begin(), l.end(), r.begin() ) ); 1916 } 1917 1918 template< class T > 1919 gsl_api inline gsl_constexpr bool operator< ( span<T> const & l, span<T> const & r ) 1920 { 1921 return std::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); 1922 } 1923 #endif 1924 1925 template< class T, class U > 1926 gsl_api inline gsl_constexpr bool operator!=( span<T> const & l, span<U> const & r ) 1927 { 1928 return !( l == r ); 1929 } 1930 1931 template< class T, class U > 1932 gsl_api inline gsl_constexpr bool operator<=( span<T> const & l, span<U> const & r ) 1933 { 1934 return !( r < l ); 1935 } 1936 1937 template< class T, class U > 1938 gsl_api inline gsl_constexpr bool operator> ( span<T> const & l, span<U> const & r ) 1939 { 1940 return ( r < l ); 1941 } 1942 1943 template< class T, class U > 1944 gsl_api inline gsl_constexpr bool operator>=( span<T> const & l, span<U> const & r ) 1945 { 1946 return !( l < r ); 1947 } 1948 1949 // span algorithms 1950 1951 namespace details { 1952 1953 template< class II, class N, class OI > 1954 gsl_api inline OI copy_n( II first, N count, OI result ) 1955 { 1956 if ( count > 0 ) 1957 { 1958 *result++ = *first; 1959 for ( N i = 1; i < count; ++i ) 1960 { 1961 *result++ = *++first; 1962 } 1963 } 1964 return result; 1965 } 1966 } 1967 1968 template< class T, class U > 1969 gsl_api inline void copy( span<T> src, span<U> dest ) 1970 { 1971 #if gsl_CPP14_OR_GREATER // gsl_HAVE( TYPE_TRAITS ) (circumvent Travis clang 3.4) 1972 static_assert( std::is_assignable<U &, T const &>::value, "Cannot assign elements of source span to elements of destination span" ); 1973 #endif 1974 Expects( dest.size() >= src.size() ); 1975 details::copy_n( src.data(), src.size(), dest.data() ); 1976 } 1977 1978 // span creator functions (see ctors) 1979 1980 template< class T > 1981 gsl_api inline span< const byte > as_bytes( span<T> spn ) gsl_noexcept 1982 { 1983 return span< const byte >( reinterpret_cast<const byte *>( spn.data() ), spn.size_bytes() ); // NOLINT 1984 } 1985 1986 template< class T> 1987 gsl_api inline span< byte > as_writeable_bytes( span<T> spn ) gsl_noexcept 1988 { 1989 return span< byte >( reinterpret_cast<byte *>( spn.data() ), spn.size_bytes() ); // NOLINT 1990 } 1991 1992 #if gsl_FEATURE_TO_STD( MAKE_SPAN ) 1993 1994 template< class T > 1995 gsl_api inline gsl_constexpr span<T> 1996 make_span( T * ptr, typename span<T>::index_type count ) 1997 { 1998 return span<T>( ptr, count ); 1999 } 2000 2001 template< class T > 2002 gsl_api inline gsl_constexpr span<T> 2003 make_span( T * first, T * last ) 2004 { 2005 return span<T>( first, last ); 2006 } 2007 2008 template< class T, size_t N > 2009 gsl_api inline gsl_constexpr span<T> 2010 make_span( T (&arr)[N] ) 2011 { 2012 return span<T>( gsl_ADDRESSOF( arr[0] ), N ); 2013 } 2014 2015 #if gsl_HAVE( ARRAY ) 2016 2017 template< class T, size_t N > 2018 gsl_api inline gsl_constexpr span<T> 2019 make_span( std::array<T,N> & arr ) 2020 { 2021 return span<T>( arr ); 2022 } 2023 2024 template< class T, size_t N > 2025 gsl_api inline gsl_constexpr span<const T> 2026 make_span( std::array<T,N> const & arr ) 2027 { 2028 return span<const T>( arr ); 2029 } 2030 #endif 2031 2032 #if gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) && gsl_HAVE( AUTO ) 2033 2034 template< class Container, class = decltype(std::declval<Container>().data()) > 2035 gsl_api inline gsl_constexpr auto 2036 make_span( Container & cont ) -> span< typename Container::value_type > 2037 { 2038 return span< typename Container::value_type >( cont ); 2039 } 2040 2041 template< class Container, class = decltype(std::declval<Container>().data()) > 2042 gsl_api inline gsl_constexpr auto 2043 make_span( Container const & cont ) -> span< const typename Container::value_type > 2044 { 2045 return span< const typename Container::value_type >( cont ); 2046 } 2047 2048 #else 2049 2050 template< class T > 2051 gsl_api inline span<T> 2052 make_span( std::vector<T> & cont ) 2053 { 2054 return span<T>( with_container, cont ); 2055 } 2056 2057 template< class T > 2058 gsl_api inline span<const T> 2059 make_span( std::vector<T> const & cont ) 2060 { 2061 return span<const T>( with_container, cont ); 2062 } 2063 #endif 2064 2065 #if gsl_FEATURE_TO_STD( WITH_CONTAINER ) 2066 2067 template< class Container > 2068 gsl_api inline gsl_constexpr span<typename Container::value_type> 2069 make_span( with_container_t, Container & cont ) gsl_noexcept 2070 { 2071 return span< typename Container::value_type >( with_container, cont ); 2072 } 2073 2074 template< class Container > 2075 gsl_api inline gsl_constexpr span<const typename Container::value_type> 2076 make_span( with_container_t, Container const & cont ) gsl_noexcept 2077 { 2078 return span< const typename Container::value_type >( with_container, cont ); 2079 } 2080 2081 #endif // gsl_FEATURE_TO_STD( WITH_CONTAINER ) 2082 2083 template< class Ptr > 2084 gsl_api inline span<typename Ptr::element_type> 2085 make_span( Ptr & ptr ) 2086 { 2087 return span<typename Ptr::element_type>( ptr ); 2088 } 2089 2090 template< class Ptr > 2091 gsl_api inline span<typename Ptr::element_type> 2092 make_span( Ptr & ptr, typename span<typename Ptr::element_type>::index_type count ) 2093 { 2094 return span<typename Ptr::element_type>( ptr, count); 2095 } 2096 2097 #endif // gsl_FEATURE_TO_STD( MAKE_SPAN ) 2098 2099 #if gsl_FEATURE_TO_STD( BYTE_SPAN ) 2100 2101 template< class T > 2102 gsl_api inline gsl_constexpr span<byte> 2103 byte_span( T & t ) gsl_noexcept 2104 { 2105 return span<byte>( reinterpret_cast<byte *>( &t ), sizeof(T) ); 2106 } 2107 2108 template< class T > 2109 gsl_api inline gsl_constexpr span<const byte> 2110 byte_span( T const & t ) gsl_noexcept 2111 { 2112 return span<const byte>( reinterpret_cast<byte const *>( &t ), sizeof(T) ); 2113 } 2114 2115 #endif // gsl_FEATURE_TO_STD( BYTE_SPAN ) 2116 2117 // 2118 // basic_string_span: 2119 // 2120 2121 template< class T > 2122 class basic_string_span; 2123 2124 namespace details { 2125 2126 template< class T > 2127 struct is_basic_string_span_oracle : false_type {}; 2128 2129 template< class T > 2130 struct is_basic_string_span_oracle< basic_string_span<T> > : true_type {}; 2131 2132 template< class T > 2133 struct is_basic_string_span : is_basic_string_span_oracle< typename remove_cv<T>::type > {}; 2134 2135 template< class T > 2136 gsl_api inline gsl_constexpr14 std::size_t string_length( T * ptr, std::size_t max ) 2137 { 2138 if ( ptr == gsl_nullptr || max <= 0 ) 2139 return 0; 2140 2141 std::size_t len = 0; 2142 while ( len < max && ptr[len] ) // NOLINT 2143 ++len; 2144 2145 return len; 2146 } 2147 2148 } // namespace details 2149 2150 // 2151 // basic_string_span<> - A view of contiguous characters, replace (*,len). 2152 // 2153 template< class T > 2154 class basic_string_span 2155 { 2156 public: 2157 typedef T element_type; 2158 typedef span<T> span_type; 2159 2160 typedef typename span_type::index_type index_type; 2161 typedef typename span_type::difference_type difference_type; 2162 2163 typedef typename span_type::pointer pointer ; 2164 typedef typename span_type::reference reference ; 2165 2166 typedef typename span_type::iterator iterator ; 2167 typedef typename span_type::const_iterator const_iterator ; 2168 typedef typename span_type::reverse_iterator reverse_iterator; 2169 typedef typename span_type::const_reverse_iterator const_reverse_iterator; 2170 2171 // construction: 2172 2173 #if gsl_HAVE( IS_DEFAULT ) 2174 gsl_api gsl_constexpr basic_string_span() gsl_noexcept = default; 2175 #else 2176 gsl_api gsl_constexpr basic_string_span() gsl_noexcept {} 2177 #endif 2178 2179 #if gsl_HAVE( NULLPTR ) 2180 gsl_api gsl_constexpr basic_string_span( std::nullptr_t ptr ) gsl_noexcept 2181 : span_( ptr, index_type( 0 ) ) 2182 {} 2183 #endif 2184 2185 gsl_api gsl_constexpr basic_string_span( pointer ptr ) 2186 : span_( remove_z( ptr, std::numeric_limits<index_type>::max() ) ) 2187 {} 2188 2189 gsl_api gsl_constexpr basic_string_span( pointer ptr, index_type count ) 2190 : span_( ptr, count ) 2191 {} 2192 2193 gsl_api gsl_constexpr basic_string_span( pointer firstElem, pointer lastElem ) 2194 : span_( firstElem, lastElem ) 2195 {} 2196 2197 template< std::size_t N > 2198 gsl_api gsl_constexpr basic_string_span( element_type (&arr)[N] ) 2199 : span_( remove_z( gsl_ADDRESSOF( arr[0] ), N ) ) 2200 {} 2201 2202 #if gsl_HAVE( ARRAY ) 2203 2204 template< std::size_t N > 2205 gsl_api gsl_constexpr basic_string_span( std::array< typename details::remove_const<element_type>::type, N> & arr ) 2206 : span_( remove_z( arr ) ) 2207 {} 2208 2209 template< std::size_t N > 2210 gsl_api gsl_constexpr basic_string_span( std::array< typename details::remove_const<element_type>::type, N> const & arr ) 2211 : span_( remove_z( arr ) ) 2212 {} 2213 2214 #endif 2215 2216 #if gsl_HAVE( CONSTRAINED_SPAN_CONTAINER_CTOR ) 2217 2218 // Exclude: array, [basic_string,] basic_string_span 2219 2220 template< 2221 class Container, 2222 class = typename std::enable_if< 2223 ! details::is_std_array< Container >::value 2224 && ! details::is_basic_string_span< Container >::value 2225 && std::is_convertible< typename Container::pointer, pointer >::value 2226 && std::is_convertible< typename Container::pointer, decltype(std::declval<Container>().data()) >::value 2227 >::type 2228 > 2229 gsl_api gsl_constexpr basic_string_span( Container & cont ) 2230 : span_( ( cont ) ) 2231 {} 2232 2233 // Exclude: array, [basic_string,] basic_string_span 2234 2235 template< 2236 class Container, 2237 class = typename std::enable_if< 2238 ! details::is_std_array< Container >::value 2239 && ! details::is_basic_string_span< Container >::value 2240 && std::is_convertible< typename Container::pointer, pointer >::value 2241 && std::is_convertible< typename Container::pointer, decltype(std::declval<Container const &>().data()) >::value 2242 >::type 2243 > 2244 gsl_api gsl_constexpr basic_string_span( Container const & cont ) 2245 : span_( ( cont ) ) 2246 {} 2247 2248 #elif gsl_HAVE( UNCONSTRAINED_SPAN_CONTAINER_CTOR ) 2249 2250 template< class Container > 2251 gsl_api gsl_constexpr basic_string_span( Container & cont ) 2252 : span_( cont ) 2253 {} 2254 2255 template< class Container > 2256 gsl_api gsl_constexpr basic_string_span( Container const & cont ) 2257 : span_( cont ) 2258 {} 2259 2260 #else 2261 2262 template< class U > 2263 gsl_api gsl_constexpr basic_string_span( span<U> const & rhs ) 2264 : span_( rhs ) 2265 {} 2266 2267 #endif 2268 2269 #if gsl_FEATURE_TO_STD( WITH_CONTAINER ) 2270 2271 template< class Container > 2272 gsl_api gsl_constexpr basic_string_span( with_container_t, Container & cont ) 2273 : span_( with_container, cont ) 2274 {} 2275 #endif 2276 2277 #if gsl_HAVE( IS_DEFAULT ) 2278 # if gsl_BETWEEN( gsl_COMPILER_GNUC_VERSION, 440, 600 ) 2279 gsl_api gsl_constexpr basic_string_span( basic_string_span const & rhs ) = default; 2280 2281 gsl_api gsl_constexpr basic_string_span( basic_string_span && rhs ) = default; 2282 # else 2283 gsl_api gsl_constexpr basic_string_span( basic_string_span const & rhs ) gsl_noexcept = default; 2284 2285 gsl_api gsl_constexpr basic_string_span( basic_string_span && rhs ) gsl_noexcept = default; 2286 # endif 2287 #endif 2288 2289 template< class U 2290 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 2291 , class = typename std::enable_if< std::is_convertible<typename basic_string_span<U>::pointer, pointer>::value >::type 2292 #endif 2293 > 2294 gsl_api gsl_constexpr basic_string_span( basic_string_span<U> const & rhs ) 2295 : span_( reinterpret_cast<pointer>( rhs.data() ), rhs.length() ) // NOLINT 2296 {} 2297 2298 #if gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120 2299 template< class U 2300 , class = typename std::enable_if< std::is_convertible<typename basic_string_span<U>::pointer, pointer>::value >::type 2301 > 2302 gsl_api gsl_constexpr basic_string_span( basic_string_span<U> && rhs ) 2303 : span_( reinterpret_cast<pointer>( rhs.data() ), rhs.length() ) // NOLINT 2304 {} 2305 #endif 2306 2307 template< class CharTraits, class Allocator > 2308 gsl_api gsl_constexpr basic_string_span( 2309 std::basic_string< typename details::remove_const<element_type>::type, CharTraits, Allocator > & str ) 2310 : span_( gsl_ADDRESSOF( str[0] ), str.length() ) 2311 {} 2312 2313 template< class CharTraits, class Allocator > 2314 gsl_api gsl_constexpr basic_string_span( 2315 std::basic_string< typename details::remove_const<element_type>::type, CharTraits, Allocator > const & str ) 2316 : span_( gsl_ADDRESSOF( str[0] ), str.length() ) 2317 {} 2318 2319 // destruction, assignment: 2320 2321 #if gsl_HAVE( IS_DEFAULT ) 2322 gsl_api ~basic_string_span() gsl_noexcept = default; 2323 2324 gsl_api basic_string_span & operator=( basic_string_span const & rhs ) gsl_noexcept = default; 2325 2326 gsl_api basic_string_span & operator=( basic_string_span && rhs ) gsl_noexcept = default; 2327 #endif 2328 2329 // sub span: 2330 2331 gsl_api gsl_constexpr basic_string_span first( index_type count ) const 2332 { 2333 return span_.first( count ); 2334 } 2335 2336 gsl_api gsl_constexpr basic_string_span last( index_type count ) const 2337 { 2338 return span_.last( count ); 2339 } 2340 2341 gsl_api gsl_constexpr basic_string_span subspan( index_type offset ) const 2342 { 2343 return span_.subspan( offset ); 2344 } 2345 2346 gsl_api gsl_constexpr basic_string_span subspan( index_type offset, index_type count ) const 2347 { 2348 return span_.subspan( offset, count ); 2349 } 2350 2351 // observers: 2352 2353 gsl_api gsl_constexpr index_type length() const gsl_noexcept 2354 { 2355 return span_.size(); 2356 } 2357 2358 gsl_api gsl_constexpr index_type size() const gsl_noexcept 2359 { 2360 return span_.size(); 2361 } 2362 2363 gsl_api gsl_constexpr index_type length_bytes() const gsl_noexcept 2364 { 2365 return span_.size_bytes(); 2366 } 2367 2368 gsl_api gsl_constexpr index_type size_bytes() const gsl_noexcept 2369 { 2370 return span_.size_bytes(); 2371 } 2372 2373 gsl_api gsl_constexpr bool empty() const gsl_noexcept 2374 { 2375 return size() == 0; 2376 } 2377 2378 gsl_api gsl_constexpr reference operator[]( index_type idx ) const 2379 { 2380 return span_[idx]; 2381 } 2382 2383 gsl_api gsl_constexpr reference operator()( index_type idx ) const 2384 { 2385 return span_[idx]; 2386 } 2387 2388 gsl_api gsl_constexpr pointer data() const gsl_noexcept 2389 { 2390 return span_.data(); 2391 } 2392 2393 gsl_api iterator begin() const gsl_noexcept 2394 { 2395 return span_.begin(); 2396 } 2397 2398 gsl_api iterator end() const gsl_noexcept 2399 { 2400 return span_.end(); 2401 } 2402 2403 gsl_api reverse_iterator rbegin() const gsl_noexcept 2404 { 2405 return span_.rbegin(); 2406 } 2407 2408 gsl_api reverse_iterator rend() const gsl_noexcept 2409 { 2410 return span_.rend(); 2411 } 2412 2413 // const version not in p0123r2: 2414 2415 gsl_api const_iterator cbegin() const gsl_noexcept 2416 { 2417 return span_.cbegin(); 2418 } 2419 2420 gsl_api const_iterator cend() const gsl_noexcept 2421 { 2422 return span_.cend(); 2423 } 2424 2425 gsl_api const_reverse_iterator crbegin() const gsl_noexcept 2426 { 2427 return span_.crbegin(); 2428 } 2429 2430 gsl_api const_reverse_iterator crend() const gsl_noexcept 2431 { 2432 return span_.crend(); 2433 } 2434 2435 private: 2436 gsl_api static gsl_constexpr14 span_type remove_z( pointer const & sz, std::size_t max ) 2437 { 2438 return span_type( sz, details::string_length( sz, max ) ); 2439 } 2440 2441 #if gsl_HAVE( ARRAY ) 2442 template< size_t N > 2443 gsl_api static gsl_constexpr14 span_type remove_z( std::array<typename details::remove_const<element_type>::type, N> & arr ) 2444 { 2445 return remove_z( gsl_ADDRESSOF( arr[0] ), narrow_cast< std::size_t >( N ) ); 2446 } 2447 2448 template< size_t N > 2449 gsl_api static gsl_constexpr14 span_type remove_z( std::array<typename details::remove_const<element_type>::type, N> const & arr ) 2450 { 2451 return remove_z( gsl_ADDRESSOF( arr[0] ), narrow_cast< std::size_t >( N ) ); 2452 } 2453 #endif 2454 2455 private: 2456 span_type span_; 2457 }; 2458 2459 // basic_string_span comparison functions: 2460 2461 #if gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) 2462 2463 template< class T, class U > 2464 gsl_api inline gsl_constexpr14 bool operator==( basic_string_span<T> const & l, U const & u ) gsl_noexcept 2465 { 2466 const basic_string_span< typename details::add_const<T>::type > r( u ); 2467 2468 return l.size() == r.size() 2469 && std::equal( l.begin(), l.end(), r.begin() ); 2470 } 2471 2472 template< class T, class U > 2473 gsl_api inline gsl_constexpr14 bool operator<( basic_string_span<T> const & l, U const & u ) gsl_noexcept 2474 { 2475 const basic_string_span< typename details::add_const<T>::type > r( u ); 2476 2477 return std::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); 2478 } 2479 2480 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 2481 2482 template< class T, class U, 2483 class = typename std::enable_if<!details::is_basic_string_span<U>::value >::type > 2484 gsl_api inline gsl_constexpr14 bool operator==( U const & u, basic_string_span<T> const & r ) gsl_noexcept 2485 { 2486 const basic_string_span< typename details::add_const<T>::type > l( u ); 2487 2488 return l.size() == r.size() 2489 && std::equal( l.begin(), l.end(), r.begin() ); 2490 } 2491 2492 template< class T, class U, 2493 class = typename std::enable_if<!details::is_basic_string_span<U>::value >::type > 2494 gsl_api inline gsl_constexpr14 bool operator<( U const & u, basic_string_span<T> const & r ) gsl_noexcept 2495 { 2496 const basic_string_span< typename details::add_const<T>::type > l( u ); 2497 2498 return std::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); 2499 } 2500 #endif 2501 2502 #else //gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) 2503 2504 template< class T > 2505 gsl_api inline gsl_constexpr14 bool operator==( basic_string_span<T> const & l, basic_string_span<T> const & r ) gsl_noexcept 2506 { 2507 return l.size() == r.size() 2508 && std::equal( l.begin(), l.end(), r.begin() ); 2509 } 2510 2511 template< class T > 2512 gsl_api inline gsl_constexpr14 bool operator<( basic_string_span<T> const & l, basic_string_span<T> const & r ) gsl_noexcept 2513 { 2514 return std::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() ); 2515 } 2516 2517 #endif // gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) 2518 2519 template< class T, class U > 2520 gsl_api inline gsl_constexpr14 bool operator!=( basic_string_span<T> const & l, U const & r ) gsl_noexcept 2521 { 2522 return !( l == r ); 2523 } 2524 2525 template< class T, class U > 2526 gsl_api inline gsl_constexpr14 bool operator<=( basic_string_span<T> const & l, U const & r ) gsl_noexcept 2527 { 2528 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) || ! gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) 2529 return !( r < l ); 2530 #else 2531 basic_string_span< typename details::add_const<T>::type > rr( r ); 2532 return !( rr < l ); 2533 #endif 2534 } 2535 2536 template< class T, class U > 2537 gsl_api inline gsl_constexpr14 bool operator>( basic_string_span<T> const & l, U const & r ) gsl_noexcept 2538 { 2539 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) || ! gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) 2540 return ( r < l ); 2541 #else 2542 basic_string_span< typename details::add_const<T>::type > rr( r ); 2543 return ( rr < l ); 2544 #endif 2545 } 2546 2547 template< class T, class U > 2548 gsl_api inline gsl_constexpr14 bool operator>=( basic_string_span<T> const & l, U const & r ) gsl_noexcept 2549 { 2550 return !( l < r ); 2551 } 2552 2553 #if gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 2554 2555 template< class T, class U, 2556 class = typename std::enable_if<!details::is_basic_string_span<U>::value >::type > 2557 gsl_api inline gsl_constexpr14 bool operator!=( U const & l, basic_string_span<T> const & r ) gsl_noexcept 2558 { 2559 return !( l == r ); 2560 } 2561 2562 template< class T, class U, 2563 class = typename std::enable_if<!details::is_basic_string_span<U>::value >::type > 2564 gsl_api inline gsl_constexpr14 bool operator<=( U const & l, basic_string_span<T> const & r ) gsl_noexcept 2565 { 2566 return !( r < l ); 2567 } 2568 2569 template< class T, class U, 2570 class = typename std::enable_if<!details::is_basic_string_span<U>::value >::type > 2571 gsl_api inline gsl_constexpr14 bool operator>( U const & l, basic_string_span<T> const & r ) gsl_noexcept 2572 { 2573 return ( r < l ); 2574 } 2575 2576 template< class T, class U, 2577 class = typename std::enable_if<!details::is_basic_string_span<U>::value >::type > 2578 gsl_api inline gsl_constexpr14 bool operator>=( U const & l, basic_string_span<T> const & r ) gsl_noexcept 2579 { 2580 return !( l < r ); 2581 } 2582 2583 #endif // gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) 2584 2585 // convert basic_string_span to byte span: 2586 2587 template< class T > 2588 gsl_api inline span< const byte > as_bytes( basic_string_span<T> spn ) gsl_noexcept 2589 { 2590 return span< const byte >( reinterpret_cast<const byte *>( spn.data() ), spn.size_bytes() ); // NOLINT 2591 } 2592 2593 // 2594 // String types: 2595 // 2596 2597 typedef char * zstring; 2598 typedef const char * czstring; 2599 2600 #if gsl_HAVE( WCHAR ) 2601 typedef wchar_t * zwstring; 2602 typedef const wchar_t * cwzstring; 2603 #endif 2604 2605 typedef basic_string_span< char > string_span; 2606 typedef basic_string_span< char const > cstring_span; 2607 2608 #if gsl_HAVE( WCHAR ) 2609 typedef basic_string_span< wchar_t > wstring_span; 2610 typedef basic_string_span< wchar_t const > cwstring_span; 2611 #endif 2612 2613 // to_string() allow (explicit) conversions from string_span to string 2614 2615 #if 0 2616 2617 template< class T > 2618 gsl_api inline std::basic_string< typename std::remove_const<T>::type > to_string( basic_string_span<T> spn ) 2619 { 2620 std::string( spn.data(), spn.length() ); 2621 } 2622 2623 #else 2624 2625 gsl_api inline std::string to_string( string_span const & spn ) 2626 { 2627 return std::string( spn.data(), spn.length() ); 2628 } 2629 2630 gsl_api inline std::string to_string( cstring_span const & spn ) 2631 { 2632 return std::string( spn.data(), spn.length() ); 2633 } 2634 2635 #if gsl_HAVE( WCHAR ) 2636 2637 gsl_api inline std::wstring to_string( wstring_span const & spn ) 2638 { 2639 return std::wstring( spn.data(), spn.length() ); 2640 } 2641 2642 gsl_api inline std::wstring to_string( cwstring_span const & spn ) 2643 { 2644 return std::wstring( spn.data(), spn.length() ); 2645 } 2646 2647 #endif // gsl_HAVE( WCHAR ) 2648 #endif // to_string() 2649 2650 // 2651 // Stream output for string_span types 2652 // 2653 2654 namespace details { 2655 2656 template< class Stream > 2657 gsl_api void write_padding( Stream & os, std::streamsize n ) 2658 { 2659 for ( std::streamsize i = 0; i < n; ++i ) 2660 os.rdbuf()->sputc( os.fill() ); 2661 } 2662 2663 template< class Stream, class Span > 2664 gsl_api Stream & write_to_stream( Stream & os, Span const & spn ) 2665 { 2666 typename Stream::sentry sentry( os ); 2667 2668 if ( !os ) 2669 return os; 2670 2671 const std::streamsize length = narrow<std::streamsize>( spn.length() ); 2672 2673 // Whether, and how, to pad 2674 const bool pad = ( length < os.width() ); 2675 const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right; 2676 2677 if ( left_pad ) 2678 write_padding( os, os.width() - length ); 2679 2680 // Write span characters 2681 os.rdbuf()->sputn( spn.begin(), length ); 2682 2683 if ( pad && !left_pad ) 2684 write_padding( os, os.width() - length ); 2685 2686 // Reset output stream width 2687 os.width(0); 2688 2689 return os; 2690 } 2691 2692 } // namespace details 2693 2694 template< typename Traits > 2695 gsl_api std::basic_ostream< char, Traits > & operator<<( std::basic_ostream< char, Traits > & os, string_span const & spn ) 2696 { 2697 return details::write_to_stream( os, spn ); 2698 } 2699 2700 template< typename Traits > 2701 gsl_api std::basic_ostream< char, Traits > & operator<<( std::basic_ostream< char, Traits > & os, cstring_span const & spn ) 2702 { 2703 return details::write_to_stream( os, spn ); 2704 } 2705 2706 #if gsl_HAVE( WCHAR ) 2707 2708 template< typename Traits > 2709 gsl_api std::basic_ostream< wchar_t, Traits > & operator<<( std::basic_ostream< wchar_t, Traits > & os, wstring_span const & spn ) 2710 { 2711 return details::write_to_stream( os, spn ); 2712 } 2713 2714 template< typename Traits > 2715 gsl_api std::basic_ostream< wchar_t, Traits > & operator<<( std::basic_ostream< wchar_t, Traits > & os, cwstring_span const & spn ) 2716 { 2717 return details::write_to_stream( os, spn ); 2718 } 2719 2720 #endif // gsl_HAVE( WCHAR ) 2721 2722 // 2723 // ensure_sentinel() 2724 // 2725 // Provides a way to obtain a span from a contiguous sequence 2726 // that ends with a (non-inclusive) sentinel value. 2727 // 2728 // Will fail-fast if sentinel cannot be found before max elements are examined. 2729 // 2730 namespace details { 2731 2732 template< class T, class SizeType, const T Sentinel > 2733 gsl_api static span<T> ensure_sentinel( T * seq, SizeType max = std::numeric_limits<SizeType>::max() ) 2734 { 2735 typedef T * pointer; 2736 2737 gsl_SUPPRESS_MSVC_WARNING( 26429, "f.23: symbol 'cur' is never tested for nullness, it can be marked as not_null" ) 2738 2739 pointer cur = seq; 2740 2741 while ( static_cast<SizeType>( cur - seq ) < max && *cur != Sentinel ) 2742 ++cur; 2743 2744 Expects( *cur == Sentinel ); 2745 2746 return span<T>( seq, narrow_cast< typename span<T>::index_type >( cur - seq ) ); 2747 } 2748 } // namespace details 2749 2750 // 2751 // ensure_z - creates a string_span for a czstring or cwzstring. 2752 // Will fail fast if a null-terminator cannot be found before 2753 // the limit of size_type. 2754 // 2755 2756 template< class T > 2757 gsl_api inline span<T> ensure_z( T * const & sz, size_t max = std::numeric_limits<size_t>::max() ) 2758 { 2759 return details::ensure_sentinel<T, size_t, 0>( sz, max ); 2760 } 2761 2762 template< class T, size_t N > 2763 gsl_api inline span<T> ensure_z( T (&sz)[N] ) 2764 { 2765 return ensure_z( gsl_ADDRESSOF( sz[0] ), N ); 2766 } 2767 2768 # if gsl_HAVE( TYPE_TRAITS ) 2769 2770 template< class Container > 2771 gsl_api inline span< typename std::remove_pointer<typename Container::pointer>::type > 2772 ensure_z( Container & cont ) 2773 { 2774 return ensure_z( cont.data(), cont.length() ); 2775 } 2776 # endif 2777 2778 } // namespace gsl 2779 2780 #if gsl_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VERSION >= 120 2781 2782 namespace std { 2783 2784 template<> 2785 struct hash< gsl::byte > 2786 { 2787 public: 2788 std::size_t operator()( gsl::byte v ) const gsl_noexcept 2789 { 2790 return gsl::to_integer<std::size_t>( v ); 2791 } 2792 }; 2793 2794 } // namespace std 2795 2796 #endif 2797 2798 gsl_RESTORE_MSVC_WARNINGS() 2799 2800 #endif // GSL_GSL_LITE_HPP_INCLUDED 2801 2802 // end of file