2016-02-24 11:26:28 -08:00
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GSL_SPAN_H
#define GSL_SPAN_H
2025-01-07 06:42:38 -08:00
#include "gsl/assert" // for Expects
#include "gsl/byte" // for byte
#include "gsl/span_ext" // for span specialization of gsl::at and other span-related extensions
#include "gsl/util" // for narrow_cast
2017-04-20 07:51:37 -07:00
2022-01-31 22:06:42 +01:00
#include <array> // for array
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t
#include <iterator> // for reverse_iterator, distance, random_access_...
2022-03-22 13:20:54 -07:00
#include <memory> // for pointer_traits
2022-01-31 22:06:42 +01:00
#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
2016-02-24 11:26:28 -08:00
2022-03-22 13:20:54 -07:00
#if defined(__has_include) && __has_include(<version>)
#include <version>
#endif
2019-01-15 10:27:34 -08:00
#if defined(_MSC_VER) && !defined(__clang__)
2017-04-20 07:51:37 -07:00
#pragma warning(push)
2016-02-24 11:26:28 -08:00
2017-04-20 07:51:37 -07:00
// turn off some warnings that are noisy about our Expects statements
#pragma warning(disable : 4127) // conditional expression is constant
2020-02-03 10:56:31 -08:00
#pragma warning( \
disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
2017-07-13 13:53:56 -07:00
#pragma warning(disable : 4702) // unreachable code
2016-03-31 12:01:07 -07:00
2018-08-12 21:44:17 -07:00
// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
2024-01-18 06:25:07 +07:00
#pragma warning(disable : 26495) // uninitialized member when constructor calls constructor
2018-08-12 21:44:17 -07:00
#pragma warning(disable : 26446) // parser bug does not allow attributes on some templates
2016-02-24 11:26:28 -08:00
2018-08-17 11:36:06 -07:00
#endif // _MSC_VER
2018-03-03 19:12:45 -08:00
// See if we have enough C++17 power to use a static constexpr data member
// without needing an out-of-line definition
#if !(defined(__cplusplus) && (__cplusplus >= 201703L))
#define GSL_USE_STATIC_CONSTEXPR_WORKAROUND
#endif // !(defined(__cplusplus) && (__cplusplus >= 201703L))
2024-01-18 06:25:07 +07:00
// GCC 7 does not like the signed unsigned mismatch (size_t ptrdiff_t)
2018-08-12 21:44:17 -07:00
// While there is a conversion from signed to unsigned, it happens at
2020-01-17 14:32:37 +09:00
// compiletime, so the compiler wouldn't have to warn indiscriminately, but
2018-08-12 21:44:17 -07:00
// could check if the source value actually doesn't fit into the target type
2018-06-08 20:41:06 +02:00
// and only warn in those cases.
2019-01-15 10:27:34 -08:00
#if defined(__GNUC__) && __GNUC__ > 6
2018-06-08 20:41:06 +02:00
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
2024-02-26 13:17:12 -08:00
// Turn off clang unsafe buffer warnings as all accessed are guarded by runtime checks
2024-10-12 02:46:21 +02:00
#if defined(__clang__)
#if __has_warning("-Wunsafe-buffer-usage")
2024-02-26 13:17:12 -08:00
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
2024-10-12 02:46:21 +02:00
#endif // __has_warning("-Wunsafe-buffer-usage")
#endif // defined(__clang__)
2024-02-26 13:17:12 -08:00
2016-02-24 11:26:28 -08:00
namespace gsl
{
2016-06-12 18:28:19 -07:00
// implementation details
2016-03-01 12:11:41 -08:00
namespace details
{
2016-07-20 13:17:47 -07:00
template < class T >
struct is_span_oracle : std :: false_type
2016-05-29 13:52:28 -07:00
{
2016-07-20 13:17:47 -07:00
};
2020-02-03 10:56:31 -08:00
template < class ElementType , std :: size_t Extent >
2016-07-20 13:17:47 -07:00
struct is_span_oracle < gsl :: span < ElementType , Extent >> : std :: true_type
{
};
template < class T >
2016-07-26 18:34:27 -07:00
struct is_span : public is_span_oracle < std :: remove_cv_t < T >>
{
};
template < class T >
struct is_std_array_oracle : std :: false_type
{
};
2017-02-13 12:11:45 -08:00
template < class ElementType , std :: size_t Extent >
2016-07-26 18:34:27 -07:00
struct is_std_array_oracle < std :: array < ElementType , Extent >> : std :: true_type
{
};
template < class T >
2020-02-14 15:24:46 -08:00
struct is_std_array : is_std_array_oracle < std :: remove_cv_t < T >>
2016-07-20 13:17:47 -07:00
{
};
2020-02-03 10:56:31 -08:00
template < std :: size_t From , std :: size_t To >
2016-07-20 13:17:47 -07:00
struct is_allowed_extent_conversion
2020-07-15 13:11:57 -07:00
: std :: integral_constant < bool , From == To || To == dynamic_extent >
2016-07-20 13:17:47 -07:00
{
};
template < class From , class To >
struct is_allowed_element_type_conversion
2020-02-14 15:24:46 -08:00
: std :: integral_constant < bool , std :: is_convertible < From ( * )[], To ( * )[] >:: value >
2016-07-20 13:17:47 -07:00
{
};
2020-02-03 18:13:14 -08:00
template < class Type >
2016-08-01 21:41:20 -07:00
class span_iterator
2016-07-20 13:17:47 -07:00
{
public :
2022-03-22 13:20:54 -07:00
#if defined(__cpp_lib_ranges) || (defined(_MSVC_STL_VERSION) && defined(__cpp_lib_concepts))
using iterator_concept = std :: contiguous_iterator_tag ;
#endif // __cpp_lib_ranges
2016-07-20 13:17:47 -07:00
using iterator_category = std :: random_access_iterator_tag ;
2020-02-03 18:13:14 -08:00
using value_type = std :: remove_cv_t < Type > ;
using difference_type = std :: ptrdiff_t ;
using pointer = Type * ;
using reference = Type & ;
2016-07-20 13:17:47 -07:00
2020-02-03 16:26:36 -08:00
#ifdef _MSC_VER
2020-02-03 18:13:14 -08:00
using _Unchecked_type = pointer ;
2023-03-14 13:50:34 -07:00
using _Prevent_inheriting_unwrap = span_iterator ;
2020-02-11 16:36:07 -08:00
#endif // _MSC_VER
2020-02-10 17:09:58 -08:00
constexpr span_iterator () = default ;
constexpr span_iterator ( pointer begin , pointer end , pointer current )
: begin_ ( begin ), end_ ( end ), current_ ( current )
2024-11-12 15:41:21 -06:00
{
Expects ( begin_ <= current_ && current <= end_ );
}
2020-02-10 17:09:58 -08:00
2020-02-03 18:13:14 -08:00
constexpr operator span_iterator < const Type > () const noexcept
2016-07-20 13:17:47 -07:00
{
2020-02-03 16:26:36 -08:00
return { begin_ , end_ , current_ };
2016-07-20 13:17:47 -07:00
}
2016-08-01 18:49:48 -07:00
2020-02-03 18:13:14 -08:00
constexpr reference operator * () const noexcept
{
2024-11-12 15:41:21 -06:00
Expects ( current_ != end_ );
2020-02-03 18:13:14 -08:00
return * current_ ;
}
2016-07-20 13:17:47 -07:00
2020-02-03 16:26:36 -08:00
constexpr pointer operator -> () const noexcept
{
2024-11-12 15:41:21 -06:00
Expects ( current_ != end_ );
2020-02-03 16:26:36 -08:00
return current_ ;
}
2020-01-08 12:34:11 -08:00
constexpr span_iterator & operator ++ () noexcept
2016-07-20 13:17:47 -07:00
{
2024-11-12 15:41:21 -06:00
Expects ( current_ != end_ );
2020-11-11 22:47:58 +01:00
// clang-format off
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
// clang-format on
2020-02-03 16:26:36 -08:00
++ current_ ;
2016-07-20 13:17:47 -07:00
return * this ;
}
2020-01-08 12:34:11 -08:00
constexpr span_iterator operator ++ ( int ) noexcept
2016-08-01 18:49:48 -07:00
{
2020-02-05 14:36:34 -08:00
span_iterator ret = * this ;
2020-02-03 16:26:36 -08:00
++* this ;
2016-08-01 18:49:48 -07:00
return ret ;
}
2016-07-20 13:17:47 -07:00
2020-01-08 12:34:11 -08:00
constexpr span_iterator & operator -- () noexcept
2016-07-20 13:17:47 -07:00
{
2024-11-12 15:41:21 -06:00
Expects ( begin_ != current_ );
2020-02-03 16:26:36 -08:00
-- current_ ;
2016-07-20 13:17:47 -07:00
return * this ;
}
2020-01-08 12:34:11 -08:00
constexpr span_iterator operator -- ( int ) noexcept
2016-08-01 18:49:48 -07:00
{
2020-02-05 14:36:34 -08:00
span_iterator ret = * this ;
2020-02-03 16:26:36 -08:00
--* this ;
2016-08-01 18:49:48 -07:00
return ret ;
}
2016-07-20 13:17:47 -07:00
2020-02-03 16:26:36 -08:00
constexpr span_iterator & operator += ( const difference_type n ) noexcept
2016-07-20 13:17:47 -07:00
{
2020-02-04 13:30:03 -08:00
if ( n != 0 ) Expects ( begin_ && current_ && end_ );
2020-02-03 16:26:36 -08:00
if ( n > 0 ) Expects ( end_ - current_ >= n );
2020-02-03 18:12:32 -08:00
if ( n < 0 ) Expects ( current_ - begin_ >= - n );
2020-11-11 22:47:58 +01:00
// clang-format off
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
// clang-format on
2020-02-03 16:26:36 -08:00
current_ += n ;
return * this ;
}
constexpr span_iterator operator + ( const difference_type n ) const noexcept
{
2020-02-05 14:36:34 -08:00
span_iterator ret = * this ;
2020-02-18 15:36:15 -08:00
ret += n ;
return ret ;
2016-07-20 13:17:47 -07:00
}
2020-02-03 16:26:36 -08:00
friend constexpr span_iterator operator + ( const difference_type n ,
2020-02-03 18:13:14 -08:00
const span_iterator & rhs ) noexcept
2018-05-09 14:01:22 -07:00
{
return rhs + n ;
}
2020-02-03 16:26:36 -08:00
constexpr span_iterator & operator -= ( const difference_type n ) noexcept
2016-07-20 13:17:47 -07:00
{
2020-02-04 13:30:03 -08:00
if ( n != 0 ) Expects ( begin_ && current_ && end_ );
2020-02-03 18:31:50 -08:00
if ( n > 0 ) Expects ( current_ - begin_ >= n );
2020-02-03 16:26:36 -08:00
if ( n < 0 ) Expects ( end_ - current_ >= - n );
2023-03-15 00:57:46 +01:00
GSL_SUPPRESS ( bounds .1 )
2020-02-03 16:26:36 -08:00
current_ -= n ;
2016-08-01 18:49:48 -07:00
return * this ;
2016-07-20 13:17:47 -07:00
}
2020-02-03 16:26:36 -08:00
constexpr span_iterator operator - ( const difference_type n ) const noexcept
2016-07-20 13:17:47 -07:00
{
2020-02-05 14:36:34 -08:00
span_iterator ret = * this ;
2020-02-18 15:36:15 -08:00
ret -= n ;
return ret ;
2016-07-20 13:17:47 -07:00
}
2020-02-03 16:26:36 -08:00
template <
2020-02-03 18:13:14 -08:00
class Type2 ,
std :: enable_if_t < std :: is_same < std :: remove_cv_t < Type2 > , value_type >:: value , int > = 0 >
constexpr difference_type operator - ( const span_iterator < Type2 >& rhs ) const noexcept
2016-07-20 13:17:47 -07:00
{
2020-02-03 18:13:14 -08:00
Expects ( begin_ == rhs . begin_ && end_ == rhs . end_ );
2020-02-03 16:26:36 -08:00
return current_ - rhs . current_ ;
2016-07-20 13:17:47 -07:00
}
2020-02-03 16:26:36 -08:00
constexpr reference operator []( const difference_type n ) const noexcept
2016-07-20 13:17:47 -07:00
{
2020-02-03 16:26:36 -08:00
return * ( * this + n );
2016-07-20 13:17:47 -07:00
}
2020-02-03 16:26:36 -08:00
template <
2020-02-03 18:13:14 -08:00
class Type2 ,
std :: enable_if_t < std :: is_same < std :: remove_cv_t < Type2 > , value_type >:: value , int > = 0 >
constexpr bool operator == ( const span_iterator < Type2 >& rhs ) const noexcept
2016-07-20 13:17:47 -07:00
{
2020-02-05 12:58:49 -08:00
Expects ( begin_ == rhs . begin_ && end_ == rhs . end_ );
return current_ == rhs . current_ ;
2016-07-20 13:17:47 -07:00
}
2020-02-03 16:26:36 -08:00
template <
2020-02-03 18:13:14 -08:00
class Type2 ,
std :: enable_if_t < std :: is_same < std :: remove_cv_t < Type2 > , value_type >:: value , int > = 0 >
constexpr bool operator != ( const span_iterator < Type2 >& rhs ) const noexcept
2016-07-20 13:17:47 -07:00
{
2020-02-03 16:26:36 -08:00
return ! ( * this == rhs );
2016-07-20 13:17:47 -07:00
}
2020-02-03 16:26:36 -08:00
template <
2020-02-03 18:13:14 -08:00
class Type2 ,
std :: enable_if_t < std :: is_same < std :: remove_cv_t < Type2 > , value_type >:: value , int > = 0 >
constexpr bool operator < ( const span_iterator < Type2 >& rhs ) const noexcept
2016-07-20 13:17:47 -07:00
{
2020-02-03 18:13:14 -08:00
Expects ( begin_ == rhs . begin_ && end_ == rhs . end_ );
2020-02-03 16:26:36 -08:00
return current_ < rhs . current_ ;
2016-08-08 12:06:47 -07:00
}
2020-02-03 16:26:36 -08:00
template <
2020-02-03 18:13:14 -08:00
class Type2 ,
std :: enable_if_t < std :: is_same < std :: remove_cv_t < Type2 > , value_type >:: value , int > = 0 >
constexpr bool operator > ( const span_iterator < Type2 >& rhs ) const noexcept
2016-08-08 12:06:47 -07:00
{
2020-02-03 18:31:21 -08:00
return rhs < * this ;
2020-02-03 16:26:36 -08:00
}
template <
2020-02-03 18:13:14 -08:00
class Type2 ,
std :: enable_if_t < std :: is_same < std :: remove_cv_t < Type2 > , value_type >:: value , int > = 0 >
constexpr bool operator <= ( const span_iterator < Type2 >& rhs ) const noexcept
2020-02-03 16:26:36 -08:00
{
2020-02-03 18:27:09 -08:00
return ! ( rhs < * this );
2020-02-03 16:26:36 -08:00
}
template <
2020-02-03 18:13:14 -08:00
class Type2 ,
std :: enable_if_t < std :: is_same < std :: remove_cv_t < Type2 > , value_type >:: value , int > = 0 >
constexpr bool operator >= ( const span_iterator < Type2 >& rhs ) const noexcept
2020-02-03 16:26:36 -08:00
{
2020-02-03 18:27:09 -08:00
return ! ( * this < rhs );
2016-07-20 13:17:47 -07:00
}
2018-05-22 18:07:49 -07:00
#ifdef _MSC_VER
// MSVC++ iterator debugging support; allows STL algorithms in 15.8+
// to unwrap span_iterator to a pointer type after a range check in STL
// algorithm calls
2018-08-12 21:44:17 -07:00
friend constexpr void _Verify_range ( span_iterator lhs , span_iterator rhs ) noexcept
{ // test that [lhs, rhs) forms a valid range inside an STL algorithm
2020-02-03 18:13:14 -08:00
Expects ( lhs . begin_ == rhs . begin_ // range spans have to match
&& lhs . end_ == rhs . end_ &&
lhs . current_ <= rhs . current_ ); // range must not be transposed
2018-05-22 18:07:49 -07:00
}
constexpr void _Verify_offset ( const difference_type n ) const noexcept
2020-02-04 13:30:03 -08:00
{ // test that *this + n is within the range of this call
2020-02-04 15:31:33 -08:00
if ( n != 0 ) Expects ( begin_ && current_ && end_ );
if ( n > 0 ) Expects ( end_ - current_ >= n );
if ( n < 0 ) Expects ( current_ - begin_ >= - n );
2018-05-22 18:07:49 -07:00
}
2020-02-07 14:09:57 -08:00
// clang-format off
2020-02-03 18:18:14 -08:00
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
2020-02-07 14:09:57 -08:00
// clang-format on
2018-05-22 18:07:49 -07:00
constexpr pointer _Unwrapped () const noexcept
2018-08-12 21:44:17 -07:00
{ // after seeking *this to a high water mark, or using one of the
2018-05-22 18:07:49 -07:00
// _Verify_xxx functions above, unwrap this span_iterator to a raw
// pointer
2020-02-03 16:26:36 -08:00
return current_ ;
2018-05-22 18:07:49 -07:00
}
// Tell the STL that span_iterator should not be unwrapped if it can't
// validate in advance, even in release / optimized builds:
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
static constexpr const bool _Unwrap_when_unverified = false ;
#else
static constexpr bool _Unwrap_when_unverified = false ;
#endif
2020-02-07 14:09:57 -08:00
// clang-format off
2020-02-03 18:18:14 -08:00
GSL_SUPPRESS ( con .3 ) // NO-FORMAT: attribute // TODO: false positive
2020-02-07 14:09:57 -08:00
// clang-format on
2018-05-22 18:07:49 -07:00
constexpr void _Seek_to ( const pointer p ) noexcept
2018-08-12 21:44:17 -07:00
{ // adjust the position of *this to previously verified location p
2018-05-22 18:07:49 -07:00
// after _Unwrapped
2020-02-03 16:26:36 -08:00
current_ = p ;
2018-05-22 18:07:49 -07:00
}
#endif
2020-02-03 16:26:36 -08:00
pointer begin_ = nullptr ;
pointer end_ = nullptr ;
pointer current_ = nullptr ;
2016-07-20 13:17:47 -07:00
2022-03-22 13:20:54 -07:00
template < typename Ptr >
friend struct std :: pointer_traits ;
};
}} // namespace gsl::details
2022-08-18 21:28:11 +02:00
namespace std
{
2022-03-22 13:20:54 -07:00
template < class Type >
2022-08-18 21:28:11 +02:00
struct pointer_traits <:: gsl :: details :: span_iterator < Type >>
{
using pointer = :: gsl :: details :: span_iterator < Type > ;
using element_type = Type ;
2022-03-22 13:20:54 -07:00
using difference_type = ptrdiff_t ;
2022-08-18 21:28:11 +02:00
static constexpr element_type * to_address ( const pointer i ) noexcept { return i . current_ ; }
2022-03-22 13:20:54 -07:00
};
2022-08-18 21:28:11 +02:00
} // namespace std
2022-03-22 13:20:54 -07:00
namespace gsl { namespace details {
2020-02-03 10:56:31 -08:00
template < std :: size_t Ext >
2016-07-26 18:34:27 -07:00
class extent_type
{
public :
2020-02-04 12:01:27 -08:00
using size_type = std :: size_t ;
2016-07-26 18:34:27 -07:00
2020-02-18 14:09:11 -08:00
constexpr extent_type () noexcept = default ;
2016-07-26 18:34:27 -07:00
2020-05-20 16:50:50 -07:00
constexpr explicit extent_type ( extent_type < dynamic_extent > );
2016-07-26 18:34:27 -07:00
2020-05-20 16:50:50 -07:00
constexpr explicit extent_type ( size_type size ) { Expects ( size == Ext ); }
2016-07-26 18:34:27 -07:00
2020-02-04 12:01:27 -08:00
constexpr size_type size () const noexcept { return Ext ; }
2020-03-27 13:14:23 +06:00
private :
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
static constexpr const size_type size_ = Ext ; // static size equal to Ext
#else
static constexpr size_type size_ = Ext ; // static size equal to Ext
#endif
2016-07-26 18:34:27 -07:00
};
template <>
class extent_type < dynamic_extent >
{
public :
2020-02-04 12:01:27 -08:00
using size_type = std :: size_t ;
2016-07-26 18:34:27 -07:00
2020-02-04 12:01:27 -08:00
template < size_type Other >
2020-05-20 16:50:50 -07:00
constexpr explicit extent_type ( extent_type < Other > ext ) : size_ ( ext . size ())
2018-08-17 11:36:06 -07:00
{}
2016-07-26 18:34:27 -07:00
2020-05-20 16:50:50 -07:00
constexpr explicit extent_type ( size_type size ) : size_ ( size )
2020-02-03 10:56:31 -08:00
{
Expects ( size != dynamic_extent );
}
2016-07-26 18:34:27 -07:00
2020-02-04 12:01:27 -08:00
constexpr size_type size () const noexcept { return size_ ; }
2016-07-26 18:34:27 -07:00
private :
2020-02-04 12:01:27 -08:00
size_type size_ ;
2016-07-26 18:34:27 -07:00
};
2018-03-03 19:12:45 -08:00
2020-05-20 13:11:37 -07:00
template < std :: size_t Ext >
constexpr extent_type < Ext >:: extent_type ( extent_type < dynamic_extent > ext )
{
Expects ( ext . size () == Ext );
}
2020-02-03 10:56:31 -08:00
template < class ElementType , std :: size_t Extent , std :: size_t Offset , std :: size_t Count >
2018-03-03 19:12:45 -08:00
struct calculate_subspan_type
{
2018-08-12 21:44:17 -07:00
using type = span < ElementType , Count != dynamic_extent
? Count
: ( Extent != dynamic_extent ? Extent - Offset : Extent ) > ;
2018-03-03 19:12:45 -08:00
};
2016-03-01 12:11:41 -08:00
} // namespace details
2016-07-20 13:17:47 -07:00
// [span], class template span
2020-02-03 10:56:31 -08:00
template < class ElementType , std :: size_t Extent >
2016-07-20 13:17:47 -07:00
class span
{
2016-02-24 16:11:33 -08:00
public :
2016-07-20 13:17:47 -07:00
// constants and types
2016-02-24 16:11:33 -08:00
using element_type = ElementType ;
2017-04-20 07:51:37 -07:00
using value_type = std :: remove_cv_t < ElementType > ;
2020-02-04 12:01:27 -08:00
using size_type = std :: size_t ;
2016-02-24 16:11:33 -08:00
using pointer = element_type * ;
2020-02-07 14:09:57 -08:00
using const_pointer = const element_type * ;
2016-02-24 16:11:33 -08:00
using reference = element_type & ;
2020-02-07 14:09:57 -08:00
using const_reference = const element_type & ;
2020-02-03 10:56:31 -08:00
using difference_type = std :: ptrdiff_t ;
2016-05-29 13:52:28 -07:00
2020-02-03 16:26:36 -08:00
using iterator = details :: span_iterator < ElementType > ;
2016-02-24 16:11:33 -08:00
using reverse_iterator = std :: reverse_iterator < iterator > ;
2016-05-29 13:52:28 -07:00
2018-03-03 19:12:45 -08:00
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
2020-02-04 12:01:27 -08:00
static constexpr const size_type extent { Extent };
2018-03-03 19:12:45 -08:00
#else
2020-02-04 12:01:27 -08:00
static constexpr size_type extent { Extent };
2018-03-03 19:12:45 -08:00
#endif
2016-02-24 16:11:33 -08:00
2016-07-20 13:17:47 -07:00
// [span.cons], span constructors, copy, assignment, and destructor
2017-01-28 00:08:48 -08:00
template < bool Dependent = false ,
2020-02-07 14:09:57 -08:00
// "Dependent" is needed to make "std::enable_if_t<Dependent || Extent == 0 || Extent
// == dynamic_extent>" SFINAE, since "std::enable_if_t<Extent == 0 || Extent ==
// dynamic_extent>" is ill-formed when Extent is greater than 0.
2020-02-10 13:17:22 -08:00
class = std :: enable_if_t < ( Dependent ||
details :: is_allowed_extent_conversion < 0 , Extent >:: value ) >>
2018-03-15 12:14:29 -07:00
constexpr span () noexcept : storage_ ( nullptr , details :: extent_type < 0 > ())
2018-08-17 11:36:06 -07:00
{}
2016-02-25 11:42:26 -08:00
2020-07-15 13:11:57 -07:00
template < std :: size_t MyExtent = Extent , std :: enable_if_t < MyExtent != dynamic_extent , int > = 0 >
2020-05-20 10:59:57 -07:00
constexpr explicit span ( pointer ptr , size_type count ) noexcept : storage_ ( ptr , count )
2020-02-07 14:09:57 -08:00
{
2020-05-19 16:27:46 -07:00
Expects ( count == Extent );
2020-02-07 14:09:57 -08:00
}
2016-02-25 11:42:26 -08:00
2020-07-15 13:11:57 -07:00
template < std :: size_t MyExtent = Extent , std :: enable_if_t < MyExtent == dynamic_extent , int > = 0 >
2020-05-20 10:59:57 -07:00
constexpr span ( pointer ptr , size_type count ) noexcept : storage_ ( ptr , count )
2020-05-19 16:27:46 -07:00
{}
2020-07-15 13:11:57 -07:00
template < std :: size_t MyExtent = Extent , std :: enable_if_t < MyExtent != dynamic_extent , int > = 0 >
2020-05-20 10:59:57 -07:00
constexpr explicit span ( pointer firstElem , pointer lastElem ) noexcept
2020-10-20 00:44:02 +02:00
: storage_ ( firstElem , narrow_cast < std :: size_t > ( lastElem - firstElem ))
2020-02-07 14:09:57 -08:00
{
2020-05-19 16:27:46 -07:00
Expects ( lastElem - firstElem == static_cast < difference_type > ( Extent ));
2020-02-07 14:09:57 -08:00
}
2016-02-29 13:16:48 -08:00
2020-07-15 13:11:57 -07:00
template < std :: size_t MyExtent = Extent , std :: enable_if_t < MyExtent == dynamic_extent , int > = 0 >
2020-05-19 16:27:46 -07:00
constexpr span ( pointer firstElem , pointer lastElem ) noexcept
2020-10-20 00:44:11 +02:00
: storage_ ( firstElem , narrow_cast < std :: size_t > ( lastElem - firstElem ))
2020-05-19 16:27:46 -07:00
{}
2020-02-10 13:17:22 -08:00
template < std :: size_t N ,
std :: enable_if_t < details :: is_allowed_extent_conversion < N , Extent >:: value , int > = 0 >
2018-03-15 12:14:29 -07:00
constexpr span ( element_type ( & arr )[ N ]) noexcept
2020-10-29 10:54:37 -07:00
: storage_ ( KnownNotNull { arr }, details :: extent_type < N > ())
2018-08-17 11:36:06 -07:00
{}
2016-07-26 19:19:47 -07:00
2020-03-17 15:04:58 -07:00
template <
class T , std :: size_t N ,
std :: enable_if_t < ( details :: is_allowed_extent_conversion < N , Extent >:: value &&
details :: is_allowed_element_type_conversion < T , element_type >:: value ),
int > = 0 >
2020-03-17 13:53:13 -07:00
constexpr span ( std :: array < T , N >& arr ) noexcept
: storage_ ( KnownNotNull { arr . data ()}, details :: extent_type < N > ())
{}
2020-02-07 14:09:57 -08:00
2020-03-17 13:53:13 -07:00
template < class T , std :: size_t N ,
2020-03-17 15:04:58 -07:00
std :: enable_if_t <
( details :: is_allowed_extent_conversion < N , Extent >:: value &&
details :: is_allowed_element_type_conversion < const T , element_type >:: value ),
int > = 0 >
2020-03-17 13:53:13 -07:00
constexpr span ( const std :: array < T , N >& arr ) noexcept
: storage_ ( KnownNotNull { arr . data ()}, details :: extent_type < N > ())
{}
2020-03-17 15:02:00 -07:00
2020-05-20 13:11:37 -07:00
// NB: the SFINAE on these constructors uses .data() as an incomplete/imperfect proxy for the
// requirement on Container to be a contiguous sequence container.
template < std :: size_t MyExtent = Extent , class Container ,
std :: enable_if_t <
2020-10-29 17:38:48 -07:00
MyExtent != dynamic_extent && ! details :: is_span < Container >:: value &&
! details :: is_std_array < Container >:: value &&
std :: is_pointer < decltype ( std :: declval < Container &> (). data ()) >:: value &&
std :: is_convertible <
std :: remove_pointer_t < decltype ( std :: declval < Container &> (). data ()) > ( * )[],
element_type ( * )[] >:: value ,
int > = 0 >
2020-05-20 13:11:37 -07:00
constexpr explicit span ( Container & cont ) noexcept : span ( cont . data (), cont . size ())
{}
template < std :: size_t MyExtent = Extent , class Container ,
std :: enable_if_t <
2020-10-29 17:38:48 -07:00
MyExtent == dynamic_extent && ! details :: is_span < Container >:: value &&
! details :: is_std_array < Container >:: value &&
std :: is_pointer < decltype ( std :: declval < Container &> (). data ()) >:: value &&
std :: is_convertible <
std :: remove_pointer_t < decltype ( std :: declval < Container &> (). data ()) > ( * )[],
element_type ( * )[] >:: value ,
int > = 0 >
2020-02-05 12:58:49 -08:00
constexpr span ( Container & cont ) noexcept : span ( cont . data (), cont . size ())
2018-08-17 11:36:06 -07:00
{}
2016-03-01 12:11:41 -08:00
2020-10-29 17:38:48 -07:00
template <
std :: size_t MyExtent = Extent , class Container ,
std :: enable_if_t <
MyExtent != dynamic_extent && std :: is_const < element_type >:: value &&
! details :: is_span < Container >:: value && ! details :: is_std_array < Container >:: value &&
std :: is_pointer < decltype ( std :: declval < const Container &> (). data ()) >:: value &&
std :: is_convertible <
std :: remove_pointer_t < decltype ( std :: declval < const Container &> (). data ()) > ( * )[],
element_type ( * )[] >:: value ,
int > = 0 >
2020-05-20 13:11:37 -07:00
constexpr explicit span ( const Container & cont ) noexcept : span ( cont . data (), cont . size ())
{}
2020-10-29 17:38:48 -07:00
template <
std :: size_t MyExtent = Extent , class Container ,
std :: enable_if_t <
MyExtent == dynamic_extent && std :: is_const < element_type >:: value &&
! details :: is_span < Container >:: value && ! details :: is_std_array < Container >:: value &&
std :: is_pointer < decltype ( std :: declval < const Container &> (). data ()) >:: value &&
std :: is_convertible <
std :: remove_pointer_t < decltype ( std :: declval < const Container &> (). data ()) > ( * )[],
element_type ( * )[] >:: value ,
int > = 0 >
2020-02-07 14:09:57 -08:00
constexpr span ( const Container & cont ) noexcept : span ( cont . data (), cont . size ())
2018-08-17 11:36:06 -07:00
{}
2016-03-17 17:20:33 -07:00
2018-03-15 12:14:29 -07:00
constexpr span ( const span & other ) noexcept = default ;
2016-03-16 19:39:55 -07:00
2020-10-29 17:38:48 -07:00
template < class OtherElementType , std :: size_t OtherExtent , std :: size_t MyExtent = Extent ,
std :: enable_if_t < ( MyExtent == dynamic_extent || MyExtent == OtherExtent ) &&
details :: is_allowed_element_type_conversion < OtherElementType ,
element_type >:: value ,
int > = 0 >
2020-01-08 11:51:15 -08:00
constexpr span ( const span < OtherElementType , OtherExtent >& other ) noexcept
2016-09-14 22:01:02 -07:00
: storage_ ( other . data (), details :: extent_type < OtherExtent > ( other . size ()))
2018-08-17 11:36:06 -07:00
{}
2016-07-20 13:17:47 -07:00
2020-10-29 17:38:48 -07:00
template < class OtherElementType , std :: size_t OtherExtent , std :: size_t MyExtent = Extent ,
std :: enable_if_t < MyExtent != dynamic_extent && OtherExtent == dynamic_extent &&
details :: is_allowed_element_type_conversion < OtherElementType ,
element_type >:: value ,
int > = 0 >
2020-05-19 16:27:46 -07:00
constexpr explicit span ( const span < OtherElementType , OtherExtent >& other ) noexcept
: storage_ ( other . data (), details :: extent_type < OtherExtent > ( other . size ()))
{}
2018-03-15 12:14:29 -07:00
~ span () noexcept = default ;
constexpr span & operator = ( const span & other ) noexcept = default ;
2018-05-09 14:01:22 -07:00
2016-07-20 13:17:47 -07:00
// [span.sub], span subviews
2020-02-03 10:56:31 -08:00
template < std :: size_t Count >
2020-01-08 11:51:15 -08:00
constexpr span < element_type , Count > first () const noexcept
2016-03-18 16:49:29 -07:00
{
2025-01-04 18:50:31 +01:00
static_assert ( Extent == dynamic_extent || Count <= Extent ,
"first() cannot extract more elements from a span than it contains." );
2020-02-03 10:56:31 -08:00
Expects ( Count <= size ());
2020-05-20 13:37:42 -07:00
return span < element_type , Count > { data (), Count };
2016-03-18 16:49:29 -07:00
}
2020-02-03 10:56:31 -08:00
template < std :: size_t Count >
2020-02-07 14:09:57 -08:00
// clang-format off
2020-02-03 18:18:14 -08:00
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
2020-03-17 15:04:58 -07:00
// clang-format on
constexpr span < element_type , Count > last () const noexcept
2016-03-18 16:49:29 -07:00
{
2025-01-04 18:50:31 +01:00
static_assert ( Extent == dynamic_extent || Count <= Extent ,
"last() cannot extract more elements from a span than it contains." );
2020-02-18 14:09:11 -08:00
Expects ( Count <= size ());
2020-05-20 13:37:42 -07:00
return span < element_type , Count > { data () + ( size () - Count ), Count };
2016-03-18 16:49:29 -07:00
}
2020-02-03 10:56:31 -08:00
template < std :: size_t Offset , std :: size_t Count = dynamic_extent >
2020-02-07 14:09:57 -08:00
// clang-format off
2020-02-03 18:18:14 -08:00
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
2020-03-17 15:04:58 -07:00
// clang-format on
constexpr auto subspan () const noexcept ->
typename details :: calculate_subspan_type < ElementType , Extent , Offset , Count >:: type
2016-03-18 16:49:29 -07:00
{
2025-01-04 18:50:31 +01:00
static_assert ( Extent == dynamic_extent || ( Extent >= Offset && ( Count == dynamic_extent ||
Count <= Extent - Offset )),
"subspan() cannot extract more elements from a span than it contains." );
2020-02-03 18:13:14 -08:00
Expects (( size () >= Offset ) && ( Count == dynamic_extent || ( Count <= size () - Offset )));
2020-10-29 17:38:48 -07:00
using type =
typename details :: calculate_subspan_type < ElementType , Extent , Offset , Count >:: type ;
2020-05-20 16:50:50 -07:00
return type { data () + Offset , Count == dynamic_extent ? size () - Offset : Count };
2016-03-18 16:49:29 -07:00
}
2020-02-04 12:01:27 -08:00
constexpr span < element_type , dynamic_extent > first ( size_type count ) const noexcept
2016-03-18 16:49:29 -07:00
{
2020-02-03 10:56:31 -08:00
Expects ( count <= size ());
2020-05-20 10:59:57 -07:00
return { data (), count };
2016-03-18 16:49:29 -07:00
}
2020-02-04 12:01:27 -08:00
constexpr span < element_type , dynamic_extent > last ( size_type count ) const noexcept
2016-03-18 16:49:29 -07:00
{
2020-02-03 10:56:31 -08:00
Expects ( count <= size ());
2017-11-03 16:13:39 -07:00
return make_subspan ( size () - count , dynamic_extent , subspan_selector < Extent > {});
2016-03-18 16:49:29 -07:00
}
2020-10-29 17:38:48 -07:00
constexpr span < element_type , dynamic_extent >
subspan ( size_type offset , size_type count = dynamic_extent ) const noexcept
2016-03-18 16:49:29 -07:00
{
2017-11-03 16:13:39 -07:00
return make_subspan ( offset , count , subspan_selector < Extent > {});
2016-03-18 16:49:29 -07:00
}
2016-07-20 13:17:47 -07:00
// [span.obs], span observers
2020-02-04 12:01:27 -08:00
constexpr size_type size () const noexcept { return storage_ . size (); }
2020-02-05 12:58:49 -08:00
2023-05-09 09:05:26 -07:00
constexpr size_type size_bytes () const noexcept { return size () * sizeof ( element_type ); }
2020-02-05 12:58:49 -08:00
2018-03-15 12:14:29 -07:00
constexpr bool empty () const noexcept { return size () == 0 ; }
2016-02-24 16:11:33 -08:00
2016-07-20 13:17:47 -07:00
// [span.elem], span element access
2020-02-07 14:09:57 -08:00
// clang-format off
2020-02-03 18:18:14 -08:00
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
2020-02-07 14:09:57 -08:00
// clang-format on
2020-02-04 12:01:27 -08:00
constexpr reference operator []( size_type idx ) const noexcept
2016-02-25 11:42:26 -08:00
{
2020-02-03 18:12:57 -08:00
Expects ( idx < size ());
2016-07-20 09:24:49 -07:00
return data ()[ idx ];
2016-02-25 11:42:26 -08:00
}
2016-10-26 15:11:24 -06:00
2020-01-09 12:13:12 -08:00
constexpr reference front () const noexcept
2019-11-19 16:03:55 -08:00
{
2020-02-03 13:53:38 -08:00
Expects ( size () > 0 );
2019-11-19 16:03:55 -08:00
return data ()[ 0 ];
}
2020-01-09 12:13:12 -08:00
constexpr reference back () const noexcept
2019-11-19 16:03:55 -08:00
{
2020-02-03 13:53:38 -08:00
Expects ( size () > 0 );
2019-11-19 16:03:55 -08:00
return data ()[ size () - 1 ];
}
2020-02-03 10:56:31 -08:00
2018-03-15 12:14:29 -07:00
constexpr pointer data () const noexcept { return storage_ . data (); }
2016-05-29 13:52:28 -07:00
2016-07-20 13:17:47 -07:00
// [span.iter], span iterator support
2020-02-04 12:01:27 -08:00
constexpr iterator begin () const noexcept
{
const auto data = storage_ . data ();
2020-04-19 16:41:12 +02:00
// clang-format off
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
// clang-format on
2020-02-04 12:01:27 -08:00
return { data , data + size (), data };
}
constexpr iterator end () const noexcept
{
const auto data = storage_ . data ();
2020-04-19 16:41:12 +02:00
// clang-format off
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
// clang-format on
2020-02-18 14:09:11 -08:00
const auto endData = data + storage_ . size ();
return { data , endData , endData };
2020-02-04 12:01:27 -08:00
}
2018-03-15 12:14:29 -07:00
constexpr reverse_iterator rbegin () const noexcept { return reverse_iterator { end ()}; }
constexpr reverse_iterator rend () const noexcept { return reverse_iterator { begin ()}; }
2016-07-18 11:38:01 -07:00
2018-05-09 14:01:22 -07:00
#ifdef _MSC_VER
// Tell MSVC how to unwrap spans in range-based-for
constexpr pointer _Unchecked_begin () const noexcept { return data (); }
2018-08-17 11:36:06 -07:00
constexpr pointer _Unchecked_end () const noexcept
2018-08-12 21:44:17 -07:00
{
2020-02-07 14:09:57 -08:00
// clang-format off
2020-02-03 18:18:14 -08:00
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
2020-02-07 14:09:57 -08:00
// clang-format on
2018-08-12 21:44:17 -07:00
return data () + size ();
}
2018-05-09 14:01:22 -07:00
#endif // _MSC_VER
2016-02-24 16:11:33 -08:00
private :
2018-03-15 12:14:29 -07:00
// Needed to remove unnecessary null check in subspans
2018-05-09 14:01:22 -07:00
struct KnownNotNull
2018-03-15 12:14:29 -07:00
{
pointer p ;
};
2016-07-20 13:17:47 -07:00
// this implementation detail class lets us take advantage of the
2016-02-28 00:50:53 -08:00
// empty base class optimization to pay for only storage of a single
// pointer in the case of fixed-size spans
template < class ExtentType >
class storage_type : public ExtentType
{
public :
2018-05-09 14:01:22 -07:00
// KnownNotNull parameter is needed to remove unnecessary null check
2018-03-15 12:14:29 -07:00
// in subspans and constructors from arrays
2016-02-28 00:50:53 -08:00
template < class OtherExtentType >
2018-08-12 21:44:17 -07:00
constexpr storage_type ( KnownNotNull data , OtherExtentType ext )
: ExtentType ( ext ), data_ ( data . p )
2022-04-28 14:58:25 -07:00
{}
2016-02-28 00:50:53 -08:00
2018-03-15 12:14:29 -07:00
template < class OtherExtentType >
constexpr storage_type ( pointer data , OtherExtentType ext ) : ExtentType ( ext ), data_ ( data )
{
2018-08-12 21:44:17 -07:00
Expects ( data || ExtentType :: size () == 0 );
2018-03-15 12:14:29 -07:00
}
constexpr pointer data () const noexcept { return data_ ; }
2016-02-28 00:50:53 -08:00
private :
pointer data_ ;
};
2016-07-26 18:34:27 -07:00
storage_type < details :: extent_type < Extent >> storage_ ;
2017-11-03 16:13:39 -07:00
2018-03-15 12:14:29 -07:00
// The rest is needed to remove unnecessary null check
// in subspans and constructors from arrays
2020-02-14 15:24:46 -08:00
constexpr span ( KnownNotNull ptr , size_type count ) noexcept : storage_ ( ptr , count ) {}
2017-11-03 16:13:39 -07:00
2020-02-03 10:56:31 -08:00
template < std :: size_t CallerExtent >
2018-08-12 21:44:17 -07:00
class subspan_selector
{
};
2017-11-03 16:13:39 -07:00
2020-02-03 10:56:31 -08:00
template < std :: size_t CallerExtent >
2020-10-29 17:38:48 -07:00
constexpr span < element_type , dynamic_extent >
make_subspan ( size_type offset , size_type count , subspan_selector < CallerExtent > ) const noexcept
2017-11-03 16:13:39 -07:00
{
2018-08-12 21:44:17 -07:00
const span < element_type , dynamic_extent > tmp ( * this );
2017-11-03 16:13:39 -07:00
return tmp . subspan ( offset , count );
}
2020-02-07 14:09:57 -08:00
// clang-format off
2020-02-03 18:18:14 -08:00
GSL_SUPPRESS ( bounds .1 ) // NO-FORMAT: attribute
2020-02-07 14:09:57 -08:00
// clang-format on
2020-02-10 13:17:22 -08:00
constexpr span < element_type , dynamic_extent >
2020-02-14 15:24:46 -08:00
make_subspan ( size_type offset , size_type count , subspan_selector < dynamic_extent > ) const noexcept
2017-11-03 16:13:39 -07:00
{
2020-02-03 16:26:36 -08:00
Expects ( size () >= offset );
2018-08-12 21:44:17 -07:00
if ( count == dynamic_extent ) { return { KnownNotNull { data () + offset }, size () - offset }; }
2017-11-03 16:13:39 -07:00
2020-02-03 10:56:31 -08:00
Expects ( size () - offset >= count );
2018-08-12 21:44:17 -07:00
return { KnownNotNull { data () + offset }, count };
2017-11-03 16:13:39 -07:00
}
2016-02-24 16:11:33 -08:00
};
2020-02-07 14:09:57 -08:00
#if (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L))
// Deduction Guides
template < class Type , std :: size_t Extent >
2020-10-29 17:38:48 -07:00
span ( Type ( & )[ Extent ]) -> span < Type , Extent > ;
2020-02-07 14:09:57 -08:00
template < class Type , std :: size_t Size >
2020-10-29 17:38:48 -07:00
span ( std :: array < Type , Size >& ) -> span < Type , Size > ;
2020-02-07 14:09:57 -08:00
template < class Type , std :: size_t Size >
2020-10-29 17:38:48 -07:00
span ( const std :: array < Type , Size >& ) -> span < const Type , Size > ;
2020-02-07 14:09:57 -08:00
2020-05-28 18:00:40 -07:00
template < class Container ,
2020-10-29 17:38:48 -07:00
class Element = std :: remove_pointer_t < decltype ( std :: declval < Container &> (). data ()) >>
span ( Container & ) -> span < Element > ;
2020-05-28 14:04:31 -07:00
2020-05-28 18:00:40 -07:00
template < class Container ,
2020-10-29 17:38:48 -07:00
class Element = std :: remove_pointer_t < decltype ( std :: declval < const Container &> (). data ()) >>
span ( const Container & ) -> span < Element > ;
2020-05-28 14:04:31 -07:00
2020-02-07 14:09:57 -08:00
#endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) )
2018-03-03 19:12:45 -08:00
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
2023-09-11 10:06:40 -07:00
#if defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated" // Bug in clang-cl.exe which raises a C++17 -Wdeprecated warning about this static constexpr workaround in C++14 mode.
#endif // defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
2020-02-03 10:56:31 -08:00
template < class ElementType , std :: size_t Extent >
2020-02-04 12:01:27 -08:00
constexpr const typename span < ElementType , Extent >:: size_type span < ElementType , Extent >:: extent ;
2023-09-11 10:06:40 -07:00
#if defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
#pragma clang diagnostic pop
#endif // defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
2018-03-03 19:12:45 -08:00
#endif
2016-05-29 17:06:29 -07:00
namespace details
{
// if we only supported compilers with good constexpr support then
// this pair of classes could collapse down to a constexpr function
2017-02-13 12:11:45 -08:00
// we should use a narrow_cast<> to go to std::size_t, but older compilers may not see it as
2016-07-20 13:17:47 -07:00
// constexpr
2016-05-29 17:06:29 -07:00
// and so will fail compilation of the template
2020-02-03 10:56:31 -08:00
template < class ElementType , std :: size_t Extent >
struct calculate_byte_size : std :: integral_constant < std :: size_t , sizeof ( ElementType ) * Extent >
2016-07-20 13:17:47 -07:00
{
2020-02-18 14:09:11 -08:00
static_assert ( Extent < dynamic_extent / sizeof ( ElementType ), "Size is too big." );
2016-07-20 13:17:47 -07:00
};
2016-05-29 17:06:29 -07:00
template < class ElementType >
2016-07-20 13:17:47 -07:00
struct calculate_byte_size < ElementType , dynamic_extent >
2020-02-03 10:56:31 -08:00
: std :: integral_constant < std :: size_t , dynamic_extent >
2016-07-20 13:17:47 -07:00
{
};
2018-08-12 21:44:17 -07:00
} // namespace details
2016-05-29 17:06:29 -07:00
2016-07-20 13:17:47 -07:00
// [span.objectrep], views of object representation
2020-02-03 10:56:31 -08:00
template < class ElementType , std :: size_t Extent >
2016-07-20 13:17:47 -07:00
span < const byte , details :: calculate_byte_size < ElementType , Extent >:: value >
2018-03-15 12:14:29 -07:00
as_bytes ( span < ElementType , Extent > s ) noexcept
2016-07-20 13:17:47 -07:00
{
2020-05-20 17:52:03 -07:00
using type = span < const byte , details :: calculate_byte_size < ElementType , Extent >:: value > ;
2020-02-07 14:09:57 -08:00
// clang-format off
2020-02-03 18:18:14 -08:00
GSL_SUPPRESS ( type .1 ) // NO-FORMAT: attribute
2020-02-07 14:09:57 -08:00
// clang-format on
2020-05-20 16:50:50 -07:00
return type { reinterpret_cast < const byte *> ( s . data ()), s . size_bytes ()};
2016-07-20 13:17:47 -07:00
}
2016-02-24 16:11:33 -08:00
2020-02-03 10:56:31 -08:00
template < class ElementType , std :: size_t Extent ,
2020-02-07 14:09:57 -08:00
std :: enable_if_t <! std :: is_const < ElementType >:: value , int > = 0 >
2016-07-20 13:17:47 -07:00
span < byte , details :: calculate_byte_size < ElementType , Extent >:: value >
2020-02-07 14:09:57 -08:00
as_writable_bytes ( span < ElementType , Extent > s ) noexcept
{
2020-05-20 17:52:03 -07:00
using type = span < byte , details :: calculate_byte_size < ElementType , Extent >:: value > ;
2020-02-07 14:09:57 -08:00
// clang-format off
GSL_SUPPRESS ( type .1 ) // NO-FORMAT: attribute
// clang-format on
2020-05-20 16:50:50 -07:00
return type { reinterpret_cast < byte *> ( s . data ()), s . size_bytes ()};
2020-02-07 14:09:57 -08:00
}
2016-02-24 11:26:28 -08:00
} // namespace gsl
2019-01-15 10:27:34 -08:00
#if defined(_MSC_VER) && !defined(__clang__)
2016-02-24 11:26:28 -08:00
2017-04-20 07:51:37 -07:00
#pragma warning(pop)
2016-02-24 11:26:28 -08:00
#endif // _MSC_VER
2019-01-15 10:27:34 -08:00
#if defined(__GNUC__) && __GNUC__ > 6
2018-06-08 20:41:06 +02:00
#pragma GCC diagnostic pop
#endif // __GNUC__ > 6
2024-10-12 02:46:21 +02:00
#if defined(__clang__)
#if __has_warning("-Wunsafe-buffer-usage")
2024-02-26 13:17:12 -08:00
#pragma clang diagnostic pop
2024-10-12 02:46:21 +02:00
#endif // __has_warning("-Wunsafe-buffer-usage")
#endif // defined(__clang__)
2024-02-26 13:17:12 -08:00
2016-02-24 11:26:28 -08:00
#endif // GSL_SPAN_H