Skip to content

Commit

Permalink
Differentiate between extent_t and index_t
Browse files Browse the repository at this point in the history
Add configuration macro span_CONFIG_INDEX_TYPE, still using std::ptrdiff_t
  • Loading branch information
martinmoene committed Dec 26, 2018
1 parent c85a731 commit b157ba9
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 55 deletions.
88 changes: 49 additions & 39 deletions include/nonstd/span.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
# define span_CONFIG_SELECT_SPAN ( span_HAVE_STD_SPAN ? span_SPAN_STD : span_SPAN_NONSTD )
#endif

#ifndef span_CONFIG_INDEX_TYPE
# define span_CONFIG_INDEX_TYPE std::ptrdiff_t
#endif

// span configuration (features):

#ifndef span_FEATURE_WITH_CONTAINER_TO_STD
# define span_FEATURE_WITH_CONTAINER_TO_STD 0
#endif
Expand Down Expand Up @@ -302,7 +308,7 @@ span_DISABLE_MSVC_WARNINGS( 26439 26440 26472 26473 26481 26490 )

#ifdef NONSTD_BYTE_LITE_HPP
# define span_HAVE_NONSTD_BYTE 1
#else
#else
# define span_HAVE_NONSTD_BYTE 0
#endif

Expand Down Expand Up @@ -439,11 +445,13 @@ namespace span_lite {

// [views.constants], constants

typedef std::ptrdiff_t index_t;
typedef span_CONFIG_INDEX_TYPE index_t;

span_constexpr const index_t dynamic_extent = -1;
typedef std::ptrdiff_t extent_t;

template< class T, index_t Extent = dynamic_extent >
span_constexpr const extent_t dynamic_extent = -1;

template< class T, extent_t Extent = dynamic_extent >
class span;

// Tag to select span constructor taking a container (prevent ms-gsl warning C26426):
Expand Down Expand Up @@ -591,7 +599,7 @@ span_noreturn inline void report_contract_violation( char const * /*msg*/ ) span

// Prevent signed-unsigned mismatch:

#define span_sizeof(T) static_cast<index_t>( sizeof(T) )
#define span_sizeof(T) static_cast<extent_t>( sizeof(T) )

template< class T >
inline span_constexpr index_t to_size( T size )
Expand Down Expand Up @@ -624,7 +632,7 @@ struct can_construct_from : detail::true_type{};
//
// [views.span] - A view over a contiguous, single-dimension sequence of objects
//
template< class T, index_t Extent /*= dynamic_extent*/ >
template< class T, extent_t Extent /*= dynamic_extent*/ >
class span
{
public:
Expand All @@ -639,15 +647,17 @@ class span
typedef T const & const_reference;

typedef index_t index_type;
typedef index_t difference_type;
typedef extent_t extent_type;

typedef pointer iterator;
typedef const_pointer const_iterator;

typedef pointer iterator;
typedef const_pointer const_iterator;
typedef std::ptrdiff_t difference_type;

typedef std::reverse_iterator< iterator > reverse_iterator;
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;

// static constexpr index_type extent = Extent;
// static constexpr extent_type extent = Extent;
enum { extent = Extent };

// 26.7.3.2 Constructors, copy, and assignment [span.cons]
Expand Down Expand Up @@ -676,7 +686,7 @@ class span

span_constexpr_exp span( pointer firstElem, pointer lastElem )
: data_( firstElem )
, size_( std::distance( firstElem, lastElem ) )
, size_( to_size( std::distance( firstElem, lastElem ) ) )
{
span_EXPECTS(
std::distance( firstElem, lastElem ) >= 0
Expand Down Expand Up @@ -793,7 +803,7 @@ class span
}
#endif

template< class OtherElementType, index_type OtherExtent
template< class OtherElementType, extent_type OtherExtent
#if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
, class = typename std::enable_if<
(Extent == dynamic_extent || Extent == OtherExtent) &&
Expand All @@ -805,12 +815,12 @@ class span
: data_( reinterpret_cast<pointer>( other.data() ) )
, size_( other.size() )
{
span_EXPECTS( OtherExtent == dynamic_extent || other.size() == OtherExtent );
span_EXPECTS( OtherExtent == dynamic_extent || other.size() == to_size(OtherExtent) );
}

// 26.7.3.3 Subviews [span.sub]

template< index_type Count >
template< extent_type Count >
span_constexpr_exp span< element_type, Count >
first() const
{
Expand All @@ -819,7 +829,7 @@ class span
return span< element_type, Count >( data(), Count );
}

template< index_type Count >
template< extent_type Count >
span_constexpr_exp span< element_type, Count >
last() const
{
Expand All @@ -829,9 +839,9 @@ class span
}

#if span_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG )
template< index_type Offset, index_type Count = dynamic_extent >
template< index_type Offset, extent_type Count = dynamic_extent >
#else
template< index_type Offset, index_type Count /*= dynamic_extent*/ >
template< index_type Offset, extent_type Count /*= dynamic_extent*/ >
#endif
span_constexpr_exp span< element_type, Count >
subspan() const
Expand Down Expand Up @@ -861,14 +871,14 @@ class span
}

span_constexpr_exp span< element_type, dynamic_extent >
subspan( index_type offset, index_type count = dynamic_extent ) const
subspan( index_type offset, extent_type count = dynamic_extent ) const
{
span_EXPECTS(
( ( 0 <= offset && offset <= size() ) ) &&
( count == dynamic_extent || ( 0 <= count && offset + count <= size() ) )
( count == dynamic_extent || ( 0 <= count && offset + to_size(count) <= size() ) )
);

return span< element_type, dynamic_extent >( data() + offset, count == dynamic_extent ? size() - offset : count );
return span< element_type, dynamic_extent >( data() + offset, count == dynamic_extent ? size() - offset : to_size(count) );
}

// 26.7.3.4 Observers [span.obs]
Expand Down Expand Up @@ -1022,13 +1032,13 @@ class span
#if span_HAVE( DEDUCTION_GUIDES ) // span_CPP17_OR_GREATER

template< class T, size_t N >
span( T (&)[N] ) -> span<T, to_size(N)>;
span( T (&)[N] ) -> span<T, static_cast<extent_t>(N)>;

template< class T, size_t N >
span( std::array<T, N> & ) -> span<T, to_size(N)>;
span( std::array<T, N> & ) -> span<T, static_cast<extent_t>(N)>;

template< class T, size_t N >
span( std::array<T, N> const & ) -> span<const T, to_size(N)>;
span( std::array<T, N> const & ) -> span<const T, static_cast<extent_t>(N)>;

template< class Container >
span( Container& ) -> span<typename Container::value_type>;
Expand All @@ -1042,7 +1052,7 @@ span( Container const & ) -> span<const typename Container::value_type>;

#if span_FEATURE( SAME )

template< class T1, index_t E1, class T2, index_t E2 >
template< class T1, extent_t E1, class T2, extent_t E2 >
inline span_constexpr bool same( span<T1,E1> const & l, span<T2,E2> const & r ) span_noexcept
{
return detail::is_same<T1, T2>::value
Expand All @@ -1052,7 +1062,7 @@ inline span_constexpr bool same( span<T1,E1> const & l, span<T2,E2> const & r )

#endif

template< class T1, index_t E1, class T2, index_t E2 >
template< class T1, extent_t E1, class T2, extent_t E2 >
inline span_constexpr bool operator==( span<T1,E1> const & l, span<T2,E2> const & r )
{
return
Expand All @@ -1062,31 +1072,31 @@ inline span_constexpr bool operator==( span<T1,E1> const & l, span<T2,E2> const
( l.size() == r.size() && std::equal( l.begin(), l.end(), r.begin() ) );
}

template< class T1, index_t E1, class T2, index_t E2 >
template< class T1, extent_t E1, class T2, extent_t E2 >
inline span_constexpr bool operator<( span<T1,E1> const & l, span<T2,E2> const & r )
{
return std::lexicographical_compare( l.begin(), l.end(), r.begin(), r.end() );
}

template< class T1, index_t E1, class T2, index_t E2 >
template< class T1, extent_t E1, class T2, extent_t E2 >
inline span_constexpr bool operator!=( span<T1,E1> const & l, span<T2,E2> const & r )
{
return !( l == r );
}

template< class T1, index_t E1, class T2, index_t E2 >
template< class T1, extent_t E1, class T2, extent_t E2 >
inline span_constexpr bool operator<=( span<T1,E1> const & l, span<T2,E2> const & r )
{
return !( r < l );
}

template< class T1, index_t E1, class T2, index_t E2 >
template< class T1, extent_t E1, class T2, extent_t E2 >
inline span_constexpr bool operator>( span<T1,E1> const & l, span<T2,E2> const & r )
{
return ( r < l );
}

template< class T1, index_t E1, class T2, index_t E2 >
template< class T1, extent_t E1, class T2, extent_t E2 >
inline span_constexpr bool operator>=( span<T1,E1> const & l, span<T2,E2> const & r )
{
return !( l < r );
Expand All @@ -1096,7 +1106,7 @@ inline span_constexpr bool operator>=( span<T1,E1> const & l, span<T2,E2> const

#if span_HAVE( BYTE ) || span_HAVE( NONSTD_BYTE )

template< class T, index_t Extent >
template< class T, extent_t Extent >
inline span_constexpr span< const detail::byte, ( (Extent == dynamic_extent) ? dynamic_extent : (span_sizeof(T) * Extent) ) >
as_bytes( span<T,Extent> spn ) span_noexcept
{
Expand All @@ -1108,7 +1118,7 @@ as_bytes( span<T,Extent> spn ) span_noexcept
#endif
}

template< class T, index_t Extent >
template< class T, extent_t Extent >
inline span_constexpr span< detail::byte, ( (Extent == dynamic_extent) ? dynamic_extent : (span_sizeof(T) * Extent) ) >
as_writeable_bytes( span<T,Extent> spn ) span_noexcept
{
Expand Down Expand Up @@ -1176,26 +1186,26 @@ make_span( T * first, T * last ) span_noexcept
}

template< class T, size_t N >
inline span_constexpr span<T, static_cast<index_t>(N)>
inline span_constexpr span<T, static_cast<extent_t>(N)>
make_span( T ( &arr )[ N ] ) span_noexcept
{
return span<T, static_cast<index_t>(N)>( &arr[ 0 ], N );
return span<T, static_cast<extent_t>(N)>( &arr[ 0 ], N );
}

#if span_USES_STD_SPAN || span_HAVE( ARRAY )

template< class T, size_t N >
inline span_constexpr span<T, static_cast<index_t>(N)>
inline span_constexpr span<T, static_cast<extent_t>(N)>
make_span( std::array< T, N > & arr ) span_noexcept
{
return span<T, static_cast<index_t>(N)>( arr );
return span<T, static_cast<extent_t>(N)>( arr );
}

template< class T, size_t N >
inline span_constexpr span< const T, static_cast<index_t>(N) >
inline span_constexpr span< const T, static_cast<extent_t>(N) >
make_span( std::array< T, N > const & arr ) span_noexcept
{
return span<const T, static_cast<index_t>(N)>( arr );
return span<const T, static_cast<extent_t>(N)>( arr );
}

#endif // span_HAVE( ARRAY )
Expand Down Expand Up @@ -1268,7 +1278,7 @@ using span_lite::make_span;

namespace nonstd {
namespace span_lite {

template< class T >
inline span_constexpr auto
byte_span( T & t ) span_noexcept -> span< detail::byte, span_sizeof(T) >
Expand Down
33 changes: 17 additions & 16 deletions test/span.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Copyright (c) 2015 Martin Moene
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// Distributed under the Boost Software License, Version 1.0.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include "span-main.t.hpp"
Expand All @@ -14,7 +14,8 @@

using namespace nonstd;

typedef span<int>::index_type index_type;
typedef span<int>::index_type index_type;
typedef span<int>::extent_type extent_type;

CASE( "span<>: Terminates construction from a nullptr and a non-zero size (C++11)" )
{
Expand Down Expand Up @@ -109,10 +110,10 @@ CASE( "span<>: Throws on access outside the span via at(): std::out_of_range [s

EXPECT_THROWS_AS( v.at(42), std::out_of_range );
EXPECT_THROWS_AS( w.at(42), std::out_of_range );
struct F {
static void fail(lest::env & lest_env) {
int arr[] = { 1, 2, 3, }; span<int> v( arr ); EXPECT( (v.at(42), true) );

struct F {
static void fail(lest::env & lest_env) {
int arr[] = { 1, 2, 3, }; span<int> v( arr ); EXPECT( (v.at(42), true) );
}};

lest::test fail[] = { lest::test( "F", F::fail ) };
Expand Down Expand Up @@ -512,8 +513,8 @@ CASE( "span<>: Allows to create a sub span starting at a given offset with a giv
index_type offset = 1;
index_type length = 1;

span< int> s = v.subspan( offset, length );
span<const int> t = v.subspan( offset, length );
span< int> s = v.subspan( offset, extent_type(length) );
span<const int> t = v.subspan( offset, extent_type(length) );

EXPECT( s.size() == length );
EXPECT( t.size() == length );
Expand Down Expand Up @@ -725,8 +726,8 @@ CASE( "span<>: Allows to swap with another span [span_FEATURE_MEMBER_SWAP=1]" )

a.swap( b );

EXPECT( a.size() == 2 );
EXPECT( b.size() == 3 );
EXPECT( a.size() == index_type(2) );
EXPECT( b.size() == index_type(3) );
EXPECT( a[0] == 2 );
EXPECT( b[0] == 1 );
#else
Expand Down Expand Up @@ -764,7 +765,7 @@ CASE( "span<>: Allows reverse iteration" )
for ( span<int>::reverse_iterator pos = v.rbegin(); pos != v.rend(); ++pos )
{
// size_t dist = narrow<size_t>( std::distance(v.rbegin(), pos) );
index_type dist = std::distance(v.rbegin(), pos);
index_type dist = static_cast<index_type>( std::distance(v.rbegin(), pos) );
EXPECT( *pos == arr[ v.size() - 1 - dist ] );
}
}
Expand All @@ -777,7 +778,7 @@ CASE( "span<>: Allows const reverse iteration" )
for ( span<int>::const_reverse_iterator pos = v.crbegin(); pos != v.crend(); ++pos )
{
// size_t dist = narrow<size_t>( std::distance(v.crbegin(), pos) );
index_type dist = std::distance(v.crbegin(), pos);
index_type dist = static_cast<index_type>( std::distance(v.crbegin(), pos) );
EXPECT( *pos == arr[ v.size() - 1 - dist ] );
}
}
Expand Down Expand Up @@ -1042,15 +1043,15 @@ CASE( "span<>: Allows to view and change the elements as writable bytes" )
span<type> va( a );
span<byte> vb( as_writeable_bytes(va) );

for ( std::ptrdiff_t i = 0; i < std::ptrdiff_t( sizeof(type) ); ++i )
for ( index_type i = 0; i < index_type( sizeof(type) ); ++i )
{
EXPECT( vb[i] == byte{0} );
}

vb[0] = byte{0x42};

EXPECT( vb[0] == byte{0x42} );
for ( std::ptrdiff_t i = 1; i < std::ptrdiff_t( sizeof(type) ); ++i )
for ( index_type i = 1; i < index_type( sizeof(type) ); ++i )
{
EXPECT( vb[i] == byte{0} );
}
Expand Down Expand Up @@ -1272,7 +1273,7 @@ CASE( "byte_span(): Allows building a span of std::byte from a single object (C+

span<xstd::byte> spn = byte_span( x );

EXPECT( spn.size() == std::ptrdiff_t( sizeof x ) );
EXPECT( spn.size() == index_type( sizeof x ) );
#if span_HAVE( NONSTD_BYTE )
EXPECT( spn[0] == to_byte( 0xff ) );
#else
Expand All @@ -1290,7 +1291,7 @@ CASE( "byte_span(): Allows building a span of const std::byte from a single cons

span<const xstd::byte> spn = byte_span( x );

EXPECT( spn.size() == std::ptrdiff_t( sizeof x ) );
EXPECT( spn.size() == index_type( sizeof x ) );
#if span_HAVE( NONSTD_BYTE )
EXPECT( spn[0] == to_byte( 0xff ) );
#else
Expand Down

0 comments on commit b157ba9

Please sign in to comment.