diff --git a/include/boost/range/const_iterator.hpp b/include/boost/range/const_iterator.hpp index 727fdad05..6aa90062d 100644 --- a/include/boost/range/const_iterator.hpp +++ b/include/boost/range/const_iterator.hpp @@ -23,6 +23,9 @@ #include #include #include +#if __cpp_lib_span >= 201902L +# include +#endif namespace boost { @@ -60,6 +63,20 @@ struct range_const_iterator_helper< T[sz] > typedef const T* type; }; +////////////////////////////////////////////////////////////////////////// +// span +////////////////////////////////////////////////////////////////////////// + +#if __cpp_lib_span >= 201902L + +template< typename T, std::size_t sz > +struct range_const_iterator_helper< std::span > +{ + typedef typename std::span::iterator type; +}; + +#endif + } // namespace range_detail template diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index cd2774e9f..73b5db59e 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -209,6 +209,7 @@ test-suite range : [ range-test reversible_range ] [ range-test size_type ] [ range-test std_container ] + [ run std_span.cpp /boost/test//boost_unit_test_framework : : : 20 ] [ range-test string ] [ range-test sub_range ] [ range-test ticket_5486 ] diff --git a/test/std_span.cpp b/test/std_span.cpp new file mode 100644 index 000000000..07b19a4f7 --- /dev/null +++ b/test/std_span.cpp @@ -0,0 +1,92 @@ + // Boost.Range library +// +// Copyright Thorsten Ottosen 2003-2004. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range/ +// + + +#include + +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // suppress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include +#include +#include +#include +#include +#include +#include + +void check_std_span() +{ + // const_iterator was removed from std::span for C++20: https://cplusplus.github.io/LWG/issue3320 + // but see https://github.com/cplusplus/papers/issues/971 - it may be reintroduced as a std::const_iterator + // Check that boost::begin etc. behave consistently with their respective member methods; this may require + // additional work in future. + + std::array arr = {1, 2, 3}; + using span_t = std::span; + span_t sp = arr; + const span_t spc = sp; + using cspan_t = std::span; + cspan_t csp = sp; + const cspan_t cspc = csp; + + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value::type, span_t::value_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator::type, span_t::iterator >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference::type, span_t::difference_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size::type, span_t::size_type >::value )); + + BOOST_CHECK( boost::begin( sp ) == sp.begin() ); + BOOST_CHECK( boost::end( sp ) == sp.end() ); + BOOST_CHECK( boost::empty( sp ) == sp.empty() ); + BOOST_CHECK( static_cast(boost::size( sp )) == sp.size() ); + + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value::type, span_t::value_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator::type, span_t::iterator >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference::type, span_t::difference_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size::type, span_t::size_type >::value )); + + BOOST_CHECK( boost::begin( spc ) == spc.begin() ); + BOOST_CHECK( boost::end( spc ) == spc.end() ); + BOOST_CHECK( boost::empty( spc ) == spc.empty() ); + BOOST_CHECK( static_cast(boost::size( spc )) == spc.size() ); + + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value::type, cspan_t::value_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator::type, cspan_t::iterator >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference::type, cspan_t::difference_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size::type, cspan_t::size_type >::value )); + + BOOST_CHECK( boost::begin( csp ) == csp.begin() ); + BOOST_CHECK( boost::end( csp ) == csp.end() ); + BOOST_CHECK( boost::empty( csp ) == csp.empty() ); + BOOST_CHECK( static_cast(boost::size( csp )) == csp.size() ); + + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_value::type, cspan_t::value_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_iterator::type, cspan_t::iterator >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_difference::type, cspan_t::difference_type >::value )); + BOOST_STATIC_ASSERT(( boost::is_same< boost::range_size::type, cspan_t::size_type >::value )); + + BOOST_CHECK( boost::begin( cspc ) == cspc.begin() ); + BOOST_CHECK( boost::end( cspc ) == cspc.end() ); + BOOST_CHECK( boost::empty( cspc ) == cspc.empty() ); + BOOST_CHECK( static_cast(boost::size( cspc )) == cspc.size() ); +} + +#include + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); + + test->add( BOOST_TEST_CASE( &check_std_span ) ); + + return test; +}