diff --git a/include/boost/core/string_view.hpp b/include/boost/core/string_view.hpp index 9fcdd84..7857fe1 100644 --- a/include/boost/core/string_view.hpp +++ b/include/boost/core/string_view.hpp @@ -13,7 +13,10 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include +#include #include +#include #include #include #include @@ -75,7 +78,8 @@ public: { } - BOOST_CXX14_CONSTEXPR basic_string_view( Ch const* begin, Ch const* end ) BOOST_NOEXCEPT: p_( begin ), n_( end - begin ) + template BOOST_CXX14_CONSTEXPR basic_string_view( Ch const* begin, End end, + typename boost::enable_if >::type* = 0 ) BOOST_NOEXCEPT: p_( begin ), n_( end - begin ) { BOOST_ASSERT( end - begin >= 0 ); } @@ -160,13 +164,13 @@ public: // element access - BOOST_CONSTEXPR const_reference operator[]( size_type pos ) const BOOST_NOEXCEPT + BOOST_CXX14_CONSTEXPR const_reference operator[]( size_type pos ) const BOOST_NOEXCEPT { BOOST_ASSERT( pos < size() ); return p_[ pos ]; } - BOOST_CONSTEXPR const_reference at( size_type pos ) const + BOOST_CXX14_CONSTEXPR const_reference at( size_type pos ) const { if( pos >= size() ) { @@ -176,13 +180,13 @@ public: return p_[ pos ]; } - BOOST_CONSTEXPR const_reference front() const BOOST_NOEXCEPT + BOOST_CXX14_CONSTEXPR const_reference front() const BOOST_NOEXCEPT { BOOST_ASSERT( !empty() ); return p_[ 0 ]; } - BOOST_CONSTEXPR const_reference back() const BOOST_NOEXCEPT + BOOST_CXX14_CONSTEXPR const_reference back() const BOOST_NOEXCEPT { BOOST_ASSERT( !empty() ); return p_[ n_ - 1 ]; @@ -516,7 +520,7 @@ public: } for( std::size_t i = pos; i > 0; --i ) - { + { if( p_[ i - 1 ] != c ) return i - 1; } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 0898060..1ed8fad 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -248,6 +248,7 @@ run bit_endian_test.cpp ; run type_name_test.cpp ; run sv_types_test.cpp ; +run sv_construct_test.cpp ; use-project /boost/core/swap : ./swap ; build-project ./swap ; diff --git a/test/sv_construct_test.cpp b/test/sv_construct_test.cpp new file mode 100644 index 0000000..af38943 --- /dev/null +++ b/test/sv_construct_test.cpp @@ -0,0 +1,305 @@ +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) +# include +#endif + +template std::reverse_iterator make_reverse_iterator( It it ) +{ + return std::reverse_iterator( it ); +} + +int main() +{ + { + boost::core::string_view sv; + + BOOST_TEST_EQ( sv.data(), static_cast(0) ); + BOOST_TEST_EQ( sv.size(), 0 ); + + BOOST_TEST_EQ( sv.begin(), sv.data() ); + BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() ); + + BOOST_TEST_EQ( sv.cbegin(), sv.data() ); + BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() ); + + BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.begin() ) ); + BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.end() ) ); + + BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cbegin() ) ); + BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cend() ) ); + + BOOST_TEST_EQ( sv.length(), sv.size() ); + BOOST_TEST_EQ( sv.empty(), sv.size() == 0 ); + + BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos ); + } + + { + char const* s = ""; + + boost::core::string_view sv( s ); + + BOOST_TEST_EQ( sv.data(), s ); + BOOST_TEST_EQ( sv.size(), 0 ); + + BOOST_TEST_EQ( sv.begin(), sv.data() ); + BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() ); + + BOOST_TEST_EQ( sv.cbegin(), sv.data() ); + BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() ); + + BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.begin() ) ); + BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.end() ) ); + + BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cbegin() ) ); + BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cend() ) ); + + BOOST_TEST_EQ( sv.length(), sv.size() ); + BOOST_TEST_EQ( sv.empty(), sv.size() == 0 ); + + BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos ); + + if( !sv.empty() ) + { + BOOST_TEST_EQ( &sv.front(), sv.data() ); + BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 ); + } + } + + { + char const* s = "123"; + + boost::core::string_view sv( s ); + + BOOST_TEST_EQ( sv.data(), s ); + BOOST_TEST_EQ( sv.size(), 3 ); + + BOOST_TEST_EQ( sv.begin(), sv.data() ); + BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() ); + + BOOST_TEST_EQ( sv.cbegin(), sv.data() ); + BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() ); + + BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.begin() ) ); + BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.end() ) ); + + BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cbegin() ) ); + BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cend() ) ); + + BOOST_TEST_EQ( sv.length(), sv.size() ); + BOOST_TEST_EQ( sv.empty(), sv.size() == 0 ); + + BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos ); + + if( !sv.empty() ) + { + BOOST_TEST_EQ( &sv.front(), sv.data() ); + BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 ); + } + } + + { + char const* s = "123"; + + boost::core::string_view sv( s, 0 ); + + BOOST_TEST_EQ( sv.data(), s ); + BOOST_TEST_EQ( sv.size(), 0 ); + + BOOST_TEST_EQ( sv.begin(), sv.data() ); + BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() ); + + BOOST_TEST_EQ( sv.cbegin(), sv.data() ); + BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() ); + + BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.begin() ) ); + BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.end() ) ); + + BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cbegin() ) ); + BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cend() ) ); + + BOOST_TEST_EQ( sv.length(), sv.size() ); + BOOST_TEST_EQ( sv.empty(), sv.size() == 0 ); + + BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos ); + + if( !sv.empty() ) + { + BOOST_TEST_EQ( &sv.front(), sv.data() ); + BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 ); + } + } + + { + char const* s = "123"; + + boost::core::string_view sv( s, 2 ); + + BOOST_TEST_EQ( sv.data(), s ); + BOOST_TEST_EQ( sv.size(), 2 ); + + BOOST_TEST_EQ( sv.begin(), sv.data() ); + BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() ); + + BOOST_TEST_EQ( sv.cbegin(), sv.data() ); + BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() ); + + BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.begin() ) ); + BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.end() ) ); + + BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cbegin() ) ); + BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cend() ) ); + + BOOST_TEST_EQ( sv.length(), sv.size() ); + BOOST_TEST_EQ( sv.empty(), sv.size() == 0 ); + + BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos ); + + if( !sv.empty() ) + { + BOOST_TEST_EQ( &sv.front(), sv.data() ); + BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 ); + } + } + + { + char const* s = "123"; + + boost::core::string_view sv( s, s ); + + BOOST_TEST_EQ( sv.data(), s ); + BOOST_TEST_EQ( sv.size(), 0 ); + + BOOST_TEST_EQ( sv.begin(), sv.data() ); + BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() ); + + BOOST_TEST_EQ( sv.cbegin(), sv.data() ); + BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() ); + + BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.begin() ) ); + BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.end() ) ); + + BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cbegin() ) ); + BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cend() ) ); + + BOOST_TEST_EQ( sv.length(), sv.size() ); + BOOST_TEST_EQ( sv.empty(), sv.size() == 0 ); + + BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos ); + + if( !sv.empty() ) + { + BOOST_TEST_EQ( &sv.front(), sv.data() ); + BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 ); + } + } + + { + char const* s = "123"; + + boost::core::string_view sv( s, s + 2 ); + + BOOST_TEST_EQ( sv.data(), s ); + BOOST_TEST_EQ( sv.size(), 2 ); + + BOOST_TEST_EQ( sv.begin(), sv.data() ); + BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() ); + + BOOST_TEST_EQ( sv.cbegin(), sv.data() ); + BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() ); + + BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.begin() ) ); + BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.end() ) ); + + BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cbegin() ) ); + BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cend() ) ); + + BOOST_TEST_EQ( sv.length(), sv.size() ); + BOOST_TEST_EQ( sv.empty(), sv.size() == 0 ); + + BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos ); + + if( !sv.empty() ) + { + BOOST_TEST_EQ( &sv.front(), sv.data() ); + BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 ); + } + } + + { + std::string str = "123"; + + boost::core::string_view sv( str ); + + BOOST_TEST_EQ( sv.data(), str.data() ); + BOOST_TEST_EQ( sv.size(), str.size() ); + + BOOST_TEST_EQ( sv.begin(), sv.data() ); + BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() ); + + BOOST_TEST_EQ( sv.cbegin(), sv.data() ); + BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() ); + + BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.begin() ) ); + BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.end() ) ); + + BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cbegin() ) ); + BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cend() ) ); + + BOOST_TEST_EQ( sv.length(), sv.size() ); + BOOST_TEST_EQ( sv.empty(), sv.size() == 0 ); + + BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos ); + + if( !sv.empty() ) + { + BOOST_TEST_EQ( &sv.front(), sv.data() ); + BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 ); + } + } + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + + { + std::string_view str = "123"; + + boost::core::string_view sv( str ); + + BOOST_TEST_EQ( sv.data(), str.data() ); + BOOST_TEST_EQ( sv.size(), str.size() ); + + BOOST_TEST_EQ( sv.begin(), sv.data() ); + BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() ); + + BOOST_TEST_EQ( sv.cbegin(), sv.data() ); + BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() ); + + BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.begin() ) ); + BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.end() ) ); + + BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cbegin() ) ); + BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cend() ) ); + + BOOST_TEST_EQ( sv.length(), sv.size() ); + BOOST_TEST_EQ( sv.empty(), sv.size() == 0 ); + + BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos ); + + if( !sv.empty() ) + { + BOOST_TEST_EQ( &sv.front(), sv.data() ); + BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 ); + } + } + +#endif + + return boost::report_errors(); +}