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