#ifndef BOOST_CORE_STRING_VIEW_HPP_INCLUDED #define BOOST_CORE_STRING_VIEW_HPP_INCLUDED // MS compatible compilers support #pragma once #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif // boost::core::basic_string_view // // 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 #include #include #include #include #include #include #include #include #include #include #include #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) # include #endif #if !defined(BOOST_NO_CXX20_HDR_CONCEPTS) // std::common_reference_with # include #endif namespace boost { // forward declaration of boost::basic_string_view from Utility template class basic_string_view; // forward declaration of boost::hash_range from ContainerHash template std::size_t hash_range( It, It ); namespace core { namespace detail { template struct sv_to_uchar { typedef Ch type; }; template<> struct sv_to_uchar { typedef unsigned char type; }; #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wtype-limits" #endif template BOOST_CXX14_CONSTEXPR std::size_t find_first_of( Ch const* p_, std::size_t n_, Ch const* s, std::size_t pos, std::size_t n ) BOOST_NOEXCEPT { typedef typename sv_to_uchar::type UCh; unsigned char table[ 256 ] = {}; bool use_table = true; for( std::size_t j = 0; j < n; ++j ) { UCh ch = s[ j ]; if( ch >= 0 && ch < 256 ) { table[ ch ] = 1; } else { use_table = false; break; } } if( use_table ) { for( std::size_t i = pos; i < n_; ++i ) { UCh ch = p_[ i ]; if( ch >= 0 && ch < 256 && table[ ch ] ) return i; } } else if( n >= 16 ) { for( std::size_t i = pos; i < n_; ++i ) { Ch ch = p_[ i ]; if( std::char_traits::find( s, n, ch ) != 0 ) return i; } } else { for( std::size_t i = pos; i < n_; ++i ) { Ch ch = p_[ i ]; for( std::size_t j = 0; j < n; ++j ) { if( s[ j ] == ch ) return i; } } } return static_cast( -1 ); } template BOOST_CXX14_CONSTEXPR std::size_t find_last_of( Ch const* p_, Ch const* s, std::size_t pos, std::size_t n ) BOOST_NOEXCEPT { typedef typename sv_to_uchar::type UCh; unsigned char table[ 256 ] = {}; bool use_table = true; for( std::size_t j = 0; j < n; ++j ) { UCh ch = s[ j ]; if( ch >= 0 && ch < 256 ) { table[ ch ] = 1; } else { use_table = false; break; } } std::size_t const npos = static_cast< std::size_t >( -1 ); std::size_t i = pos; if( use_table ) { do { UCh ch = p_[ i ]; if( ch >= 0 && ch < 256 && table[ ch ] ) return i; --i; } while( i != npos ); } else if( n >= 16 ) { do { Ch ch = p_[ i ]; if( std::char_traits::find( s, n, ch ) != 0 ) return i; --i; } while( i != npos ); } else { do { Ch ch = p_[ i ]; for( std::size_t j = 0; j < n; ++j ) { if( s[ j ] == ch ) return i; } --i; } while( i != npos ); } return npos; } template BOOST_CXX14_CONSTEXPR std::size_t find_first_not_of( Ch const* p_, std::size_t n_, Ch const* s, std::size_t pos, std::size_t n ) BOOST_NOEXCEPT { typedef typename sv_to_uchar::type UCh; unsigned char table[ 256 ] = {}; bool use_table = true; for( std::size_t j = 0; j < n; ++j ) { UCh ch = s[ j ]; if( ch >= 0 && ch < 256 ) { table[ ch ] = 1; } else { use_table = false; break; } } if( use_table ) { for( std::size_t i = pos; i < n_; ++i ) { UCh ch = p_[ i ]; if( !( ch >= 0 && ch < 256 && table[ ch ] ) ) return i; } } else if( n >= 16 ) { for( std::size_t i = pos; i < n_; ++i ) { Ch ch = p_[ i ]; if( std::char_traits::find( s, n, ch ) == 0 ) return i; } } else { for( std::size_t i = pos; i < n_; ++i ) { Ch ch = p_[ i ]; bool r = false; for( std::size_t j = 0; j < n; ++j ) { if( s[ j ] == ch ) { r = true; break; } } if( !r ) return i; } } return static_cast( -1 ); } template BOOST_CXX14_CONSTEXPR std::size_t find_last_not_of( Ch const* p_, Ch const* s, std::size_t pos, std::size_t n ) BOOST_NOEXCEPT { typedef typename sv_to_uchar::type UCh; unsigned char table[ 256 ] = {}; bool use_table = true; for( std::size_t j = 0; j < n; ++j ) { UCh ch = s[ j ]; if( ch >= 0 && ch < 256 ) { table[ ch ] = 1; } else { use_table = false; break; } } std::size_t const npos = static_cast< std::size_t >( -1 ); std::size_t i = pos; if( use_table ) { do { UCh ch = p_[ i ]; if( !( ch >= 0 && ch < 256 && table[ ch ] ) ) return i; --i; } while( i != npos ); } else if( n >= 16 ) { do { Ch ch = p_[ i ]; if( std::char_traits::find( s, n, ch ) == 0 ) return i; --i; } while( i != npos ); } else { do { Ch ch = p_[ i ]; bool r = false; for( std::size_t j = 0; j < n; ++j ) { if( s[ j ] == ch ) { r = true; break; } } if( !r ) return i; --i; } while( i != npos ); } return npos; } #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406 # pragma GCC diagnostic pop #endif } // namespace detail template class basic_string_view { private: Ch const* p_; std::size_t n_; public: // types typedef std::char_traits traits_type; typedef Ch value_type; typedef Ch* pointer; typedef Ch const* const_pointer; typedef Ch& reference; typedef Ch const& const_reference; typedef Ch const* const_iterator; typedef const_iterator iterator; typedef std::reverse_iterator const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; // npos BOOST_STATIC_CONSTEXPR size_type npos = static_cast( -1 ); public: // construction and assignment BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT: p_(), n_() { } BOOST_CONSTEXPR basic_string_view( Ch const* str ) BOOST_NOEXCEPT: p_( str ), n_( traits_type::length( str ) ) { } BOOST_CONSTEXPR basic_string_view( Ch const* str, size_type len ) BOOST_NOEXCEPT: p_( str ), n_( len ) { } template BOOST_CXX14_CONSTEXPR basic_string_view( Ch const* first, End last, typename boost::enable_if >::type* = 0 ) BOOST_NOEXCEPT: p_( first ), n_( last - first ) { BOOST_ASSERT( last - first >= 0 ); } template basic_string_view( std::basic_string, A> const& str ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() ) { } #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) basic_string_view( std::basic_string_view > const& str ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() ) { } #endif template basic_string_view( boost::basic_string_view > const& str, typename boost::enable_if >::type* = 0 ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() ) { } // BOOST_CONSTEXPR basic_string_view& operator=( basic_string_view const& ) BOOST_NOEXCEPT & = default; // conversions template operator std::basic_string, A>() const { return std::basic_string, A>( data(), size() ); } #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) template >::type> operator std::basic_string_view() const BOOST_NOEXCEPT { return std::basic_string_view( data(), size() ); } #endif template operator boost::basic_string_view, std::char_traits >::type> () const BOOST_NOEXCEPT { return boost::basic_string_view< Ch, std::char_traits >( data(), size() ); } // iterator support BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return p_; } BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return p_ + n_; } BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return p_; } BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return p_ + n_; } BOOST_CONSTEXPR const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator( end() ); } BOOST_CONSTEXPR const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator( begin() ); } BOOST_CONSTEXPR const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator( end() ); } BOOST_CONSTEXPR const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator( begin() ); } // capacity BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return n_; } BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return n_; } BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return npos / sizeof( Ch ); } BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT { return n_ == 0; } // element access BOOST_CXX14_CONSTEXPR const_reference operator[]( size_type pos ) const BOOST_NOEXCEPT { BOOST_ASSERT( pos < size() ); return p_[ pos ]; } BOOST_CXX14_CONSTEXPR const_reference at( size_type pos ) const { if( pos >= size() ) { boost::throw_exception( std::out_of_range( "basic_string_view::at" ), BOOST_CURRENT_LOCATION ); } return p_[ pos ]; } BOOST_CXX14_CONSTEXPR const_reference front() const BOOST_NOEXCEPT { BOOST_ASSERT( !empty() ); return p_[ 0 ]; } BOOST_CXX14_CONSTEXPR const_reference back() const BOOST_NOEXCEPT { BOOST_ASSERT( !empty() ); return p_[ n_ - 1 ]; } BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return p_; } // modifiers BOOST_CXX14_CONSTEXPR void remove_prefix( size_type n ) BOOST_NOEXCEPT { BOOST_ASSERT( n <= size() ); p_ += n; n_ -= n; } BOOST_CXX14_CONSTEXPR void remove_suffix( size_type n ) BOOST_NOEXCEPT { BOOST_ASSERT( n <= size() ); n_ -= n; } BOOST_CXX14_CONSTEXPR void swap( basic_string_view& s ) BOOST_NOEXCEPT { std::swap( p_, s.p_ ); std::swap( n_, s.n_ ); } // string operations BOOST_CXX14_CONSTEXPR size_type copy( Ch* s, size_type n, size_type pos = 0 ) const { if( pos > size() ) { boost::throw_exception( std::out_of_range( "basic_string_view::copy" ), BOOST_CURRENT_LOCATION ); } std::size_t rlen = (std::min)( n, size() - pos ); traits_type::copy( s, data() + pos, rlen ); return rlen; } BOOST_CXX14_CONSTEXPR basic_string_view substr( size_type pos = 0, size_type n = npos ) const { if( pos > size() ) { boost::throw_exception( std::out_of_range( "basic_string_view::substr" ), BOOST_CURRENT_LOCATION ); } std::size_t rlen = (std::min)( n, size() - pos ); return basic_string_view( data() + pos, rlen ); } // compare BOOST_CXX14_CONSTEXPR int compare( basic_string_view str ) const BOOST_NOEXCEPT { std::size_t rlen = (std::min)( size(), str.size() ); int cmp = traits_type::compare( data(), str.data(), rlen ); if( cmp != 0 ) return cmp; if( size() == str.size() ) return 0; return size() < str.size()? -1: +1; } BOOST_CONSTEXPR int compare( size_type pos1, size_type n1, basic_string_view str ) const { return substr( pos1, n1 ).compare( str ); } BOOST_CONSTEXPR int compare( size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2 ) const { return substr( pos1, n1 ).compare( str.substr( pos2, n2 ) ); } BOOST_CONSTEXPR int compare( Ch const* s ) const BOOST_NOEXCEPT { return compare( basic_string_view( s ) ); } BOOST_CONSTEXPR int compare( size_type pos1, size_type n1, Ch const* s ) const { return substr( pos1, n1 ).compare( basic_string_view( s ) ); } BOOST_CONSTEXPR int compare( size_type pos1, size_type n1, Ch const* s, size_type n2 ) const { return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) ); } // starts_with BOOST_CONSTEXPR bool starts_with( basic_string_view x ) const BOOST_NOEXCEPT { return size() >= x.size() && traits_type::compare( data(), x.data(), x.size() ) == 0; } BOOST_CONSTEXPR bool starts_with( Ch x ) const BOOST_NOEXCEPT { return !empty() && front() == x; } BOOST_CONSTEXPR bool starts_with( Ch const* x ) const BOOST_NOEXCEPT { return starts_with( basic_string_view( x ) ); } // ends_with BOOST_CONSTEXPR bool ends_with( basic_string_view x ) const BOOST_NOEXCEPT { return size() >= x.size() && traits_type::compare( data() + size() - x.size(), x.data(), x.size() ) == 0; } BOOST_CONSTEXPR bool ends_with( Ch x ) const BOOST_NOEXCEPT { return !empty() && back() == x; } BOOST_CONSTEXPR bool ends_with( Ch const* x ) const BOOST_NOEXCEPT { return ends_with( basic_string_view( x ) ); } // find BOOST_CONSTEXPR size_type find( basic_string_view str, size_type pos = 0 ) const BOOST_NOEXCEPT { return find( str.data(), pos, str.size() ); } BOOST_CXX14_CONSTEXPR size_type find( Ch c, size_type pos = 0 ) const BOOST_NOEXCEPT { if( pos >= size() ) return npos; Ch const* r = traits_type::find( data() + pos, size() - pos, c ); return r? r - data(): npos; } BOOST_CXX14_CONSTEXPR size_type find( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT { if( n == 1 ) return find( s[0], pos ); if( pos + n > size() ) return npos; if( n == 0 ) return pos; Ch const* p = data() + pos; Ch const* last = data() + size() - n + 1; for( ;; ) { p = traits_type::find( p, last - p, s[0] ); if( p == 0 ) break; if( traits_type::compare( p + 1, s + 1, n - 1 ) == 0 ) return p - data(); ++p; } return npos; } BOOST_CONSTEXPR size_type find( Ch const* s, size_type pos = 0 ) const BOOST_NOEXCEPT { return find( s, pos, traits_type::length( s ) ); } // rfind BOOST_CONSTEXPR size_type rfind( basic_string_view str, size_type pos = npos ) const BOOST_NOEXCEPT { return rfind( str.data(), pos, str.size() ); } BOOST_CXX14_CONSTEXPR size_type rfind( Ch c, size_type pos = npos ) const BOOST_NOEXCEPT { size_type n = size(); if( n == 0 ) { return npos; } if( pos > n - 1 ) { pos = n - 1; } do { if( p_[ pos ] == c ) return pos; --pos; } while( pos != npos ); return npos; } BOOST_CXX14_CONSTEXPR size_type rfind( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT { if( n > size() ) return npos; if( pos > size() - n ) { pos = size() - n; } if( n == 0 ) return pos; for( ;; ) { size_type xpos = rfind( s[0], pos ); if( xpos == npos ) return npos; if( traits_type::compare( data() + xpos, s, n ) == 0 ) return xpos; if( xpos == 0 ) return npos; pos = xpos - 1; } } BOOST_CONSTEXPR size_type rfind( Ch const* s, size_type pos = npos ) const BOOST_NOEXCEPT { return rfind( s, pos, traits_type::length( s ) ); } // find_first_of BOOST_CXX14_CONSTEXPR size_type find_first_of( basic_string_view str, size_type pos = 0 ) const BOOST_NOEXCEPT { return find_first_of( str.data(), pos, str.size() ); } BOOST_CONSTEXPR size_type find_first_of( Ch c, size_type pos = 0 ) const BOOST_NOEXCEPT { return find( c, pos ); } BOOST_CXX14_CONSTEXPR size_type find_first_of( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT { if( n == 0 || pos >= size() ) return npos; if( n == 1 ) return find( s[0], pos ); return detail::find_first_of( data(), size(), s, pos, n ); } BOOST_CXX14_CONSTEXPR size_type find_first_of( Ch const* s, size_type pos = 0 ) const BOOST_NOEXCEPT { return find_first_of( s, pos, traits_type::length( s ) ); } // find_last_of BOOST_CXX14_CONSTEXPR size_type find_last_of( basic_string_view str, size_type pos = npos ) const BOOST_NOEXCEPT { return find_last_of( str.data(), pos, str.size() ); } BOOST_CONSTEXPR size_type find_last_of( Ch c, size_type pos = npos ) const BOOST_NOEXCEPT { return rfind( c, pos ); } BOOST_CXX14_CONSTEXPR size_type find_last_of( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT { if( n == 1 ) { return rfind( s[0], pos ); } size_type m = size(); if( m == 0 ) { return npos; } if( pos > m - 1 ) { pos = m - 1; } return detail::find_last_of( data(), s, pos, n ); } BOOST_CXX14_CONSTEXPR size_type find_last_of( Ch const* s, size_type pos = npos ) const BOOST_NOEXCEPT { return find_last_of( s, pos, traits_type::length( s ) ); } // find_first_not_of BOOST_CXX14_CONSTEXPR size_type find_first_not_of( basic_string_view str, size_type pos = 0 ) const BOOST_NOEXCEPT { return find_first_not_of( str.data(), pos, str.size() ); } BOOST_CXX14_CONSTEXPR size_type find_first_not_of( Ch c, size_type pos = 0 ) const BOOST_NOEXCEPT { for( std::size_t i = pos; i < n_; ++i ) { if( p_[ i ] != c ) return i; } return npos; } BOOST_CXX14_CONSTEXPR size_type find_first_not_of( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT { if( pos >= size() ) return npos; if( n == 1 ) return find_first_not_of( s[0], pos ); return detail::find_first_not_of( data(), size(), s, pos, n ); } BOOST_CXX14_CONSTEXPR size_type find_first_not_of( Ch const* s, size_type pos = 0 ) const BOOST_NOEXCEPT { return find_first_not_of( s, pos, traits_type::length( s ) ); } // find_last_not_of BOOST_CXX14_CONSTEXPR size_type find_last_not_of( basic_string_view str, size_type pos = npos ) const BOOST_NOEXCEPT { return find_last_not_of( str.data(), pos, str.size() ); } BOOST_CXX14_CONSTEXPR size_type find_last_not_of( Ch c, size_type pos = npos ) const BOOST_NOEXCEPT { size_type m = size(); if( m == 0 ) { return npos; } if( pos > m - 1 ) { pos = m - 1; } do { if( p_[ pos ] != c ) return pos; --pos; } while( pos != npos ); return npos; } BOOST_CXX14_CONSTEXPR size_type find_last_not_of( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT { if( n == 1 ) { return find_last_not_of( s[0], pos ); } size_type m = size(); if( m == 0 ) { return npos; } if( pos > m - 1 ) { pos = m - 1; } return detail::find_last_not_of( data(), s, pos, n ); } BOOST_CXX14_CONSTEXPR size_type find_last_not_of( Ch const* s, size_type pos = npos ) const BOOST_NOEXCEPT { return find_last_not_of( s, pos, traits_type::length( s ) ); } // contains BOOST_CONSTEXPR bool contains( basic_string_view sv ) const BOOST_NOEXCEPT { return find( sv ) != npos; } BOOST_CXX14_CONSTEXPR bool contains( Ch c ) const BOOST_NOEXCEPT { Ch const* p = data(); size_type n = size(); if( n >= 16 ) { return traits_type::find( p, n, c ) != 0; } else { for( size_type i = 0; i < n; ++i ) { if( p[ i ] == c ) return true; } return false; } } BOOST_CONSTEXPR bool contains( Ch const* s ) const BOOST_NOEXCEPT { return find( s ) != npos; } // relational operators BOOST_CXX14_CONSTEXPR friend bool operator==( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0; } BOOST_CXX14_CONSTEXPR friend bool operator!=( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return !( sv1 == sv2 ); } BOOST_CXX14_CONSTEXPR friend bool operator<( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) < 0; } BOOST_CXX14_CONSTEXPR friend bool operator<=( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) <= 0; } BOOST_CXX14_CONSTEXPR friend bool operator>( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) > 0; } BOOST_CXX14_CONSTEXPR friend bool operator>=( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) >= 0; } #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) // "sufficient number of additional overloads" // against std::string_view BOOST_CXX14_CONSTEXPR friend bool operator==( basic_string_view sv1, std::basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0; } BOOST_CXX14_CONSTEXPR friend bool operator==( std::basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0; } BOOST_CXX14_CONSTEXPR friend bool operator!=( basic_string_view sv1, std::basic_string_view sv2 ) BOOST_NOEXCEPT { return !( sv1 == sv2 ); } BOOST_CXX14_CONSTEXPR friend bool operator!=( std::basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return !( sv1 == sv2 ); } BOOST_CXX14_CONSTEXPR friend bool operator<( basic_string_view sv1, std::basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) < 0; } BOOST_CXX14_CONSTEXPR friend bool operator<( std::basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) < 0; } BOOST_CXX14_CONSTEXPR friend bool operator<=( basic_string_view sv1, std::basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) <= 0; } BOOST_CXX14_CONSTEXPR friend bool operator<=( std::basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) <= 0; } BOOST_CXX14_CONSTEXPR friend bool operator>( basic_string_view sv1, std::basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) > 0; } BOOST_CXX14_CONSTEXPR friend bool operator>( std::basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) > 0; } BOOST_CXX14_CONSTEXPR friend bool operator>=( basic_string_view sv1, std::basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) >= 0; } BOOST_CXX14_CONSTEXPR friend bool operator>=( std::basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) >= 0; } // against Ch const* BOOST_CXX14_CONSTEXPR friend bool operator==( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT { return sv1 == basic_string_view( sv2 ); } BOOST_CXX14_CONSTEXPR friend bool operator==( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return basic_string_view( sv1 ) == sv2; } BOOST_CXX14_CONSTEXPR friend bool operator!=( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT { return !( sv1 == sv2 ); } BOOST_CXX14_CONSTEXPR friend bool operator!=( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return !( sv1 == sv2 ); } BOOST_CXX14_CONSTEXPR friend bool operator<( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) < 0; } BOOST_CXX14_CONSTEXPR friend bool operator<( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv2.compare( sv1 ) > 0; } BOOST_CXX14_CONSTEXPR friend bool operator<=( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) <= 0; } BOOST_CXX14_CONSTEXPR friend bool operator<=( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv2.compare( sv1 ) >= 0; } BOOST_CXX14_CONSTEXPR friend bool operator>( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) > 0; } BOOST_CXX14_CONSTEXPR friend bool operator>( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv2.compare( sv1 ) < 0; } BOOST_CXX14_CONSTEXPR friend bool operator>=( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) >= 0; } BOOST_CXX14_CONSTEXPR friend bool operator>=( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv2.compare( sv1 ) <= 0; } // against std::string template BOOST_CXX14_CONSTEXPR friend bool operator==( basic_string_view sv1, std::basic_string, A> const& sv2 ) BOOST_NOEXCEPT { return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0; } template BOOST_CXX14_CONSTEXPR friend bool operator==( std::basic_string, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0; } template BOOST_CXX14_CONSTEXPR friend bool operator!=( basic_string_view sv1, std::basic_string, A> const& sv2 ) BOOST_NOEXCEPT { return !( sv1 == sv2 ); } template BOOST_CXX14_CONSTEXPR friend bool operator!=( std::basic_string, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return !( sv1 == sv2 ); } template BOOST_CXX14_CONSTEXPR friend bool operator<( basic_string_view sv1, std::basic_string, A> const& sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) < 0; } template BOOST_CXX14_CONSTEXPR friend bool operator<( std::basic_string, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv2.compare( sv1 ) > 0; } template BOOST_CXX14_CONSTEXPR friend bool operator<=( basic_string_view sv1, std::basic_string, A> const& sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) <= 0; } template BOOST_CXX14_CONSTEXPR friend bool operator<=( std::basic_string, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv2.compare( sv1 ) >= 0; } template BOOST_CXX14_CONSTEXPR friend bool operator>( basic_string_view sv1, std::basic_string, A> const& sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) > 0; } template BOOST_CXX14_CONSTEXPR friend bool operator>( std::basic_string, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv2.compare( sv1 ) < 0; } template BOOST_CXX14_CONSTEXPR friend bool operator>=( basic_string_view sv1, std::basic_string, A> const& sv2 ) BOOST_NOEXCEPT { return sv1.compare( sv2 ) >= 0; } template BOOST_CXX14_CONSTEXPR friend bool operator>=( std::basic_string, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT { return sv2.compare( sv1 ) <= 0; } #endif inline friend std::size_t hash_value( basic_string_view const& sv ) { return boost::hash_range( sv.begin(), sv.end() ); } }; // stream inserter template std::basic_ostream& operator<<( std::basic_ostream& os, basic_string_view str ) { Ch const* p = str.data(); std::streamsize n = str.size(); std::streamsize m = os.width(); if( n >= m ) { os.write( p, n ); } else if( ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::left ) { os.write( p, n ); os.width( m - n ); os << ""; } else { os.width( m - n ); os << ""; os.write( p, n ); } os.width( 0 ); return os; } #if defined(BOOST_NO_CXX17_INLINE_VARIABLES) template BOOST_CONSTEXPR_OR_CONST std::size_t basic_string_view::npos; #endif // typedef names typedef basic_string_view string_view; typedef basic_string_view wstring_view; #if !defined(BOOST_NO_CXX11_CHAR16_T) typedef basic_string_view u16string_view; #endif #if !defined(BOOST_NO_CXX11_CHAR32_T) typedef basic_string_view u32string_view; #endif #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L typedef basic_string_view u8string_view; #endif } // namespace core } // namespace boost // std::common_reference support // needed for iterators that have reference=string_view and value_type=std::string #if !defined(BOOST_NO_CXX20_HDR_CONCEPTS) template class Q1, template class Q2> struct std::basic_common_reference< boost::core::basic_string_view, std::basic_string, A>, Q1, Q2> { using type = boost::core::basic_string_view; }; template class Q1, template class Q2> struct std::basic_common_reference< std::basic_string, A>, boost::core::basic_string_view, Q1, Q2> { using type = boost::core::basic_string_view; }; #endif #endif // #ifndef BOOST_CORE_STRING_VIEW_HPP_INCLUDED