diff --git a/include/boost/utility/string_view.hpp b/include/boost/utility/string_view.hpp index e3cb0ae..aae7f25 100644 --- a/include/boost/utility/string_view.hpp +++ b/include/boost/utility/string_view.hpp @@ -157,13 +157,18 @@ namespace boost { #ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS template > - std::basic_string to_string(const Allocator& a = Allocator()) const { + std::basic_string to_string(const Allocator& a = Allocator()) const { return std::basic_string(begin(), end(), a); } #else std::basic_string to_string() const { return std::basic_string(begin(), end()); } + + template + std::basic_string to_string(const Allocator& a) const { + return std::basic_string(begin(), end(), a); + } #endif size_type copy(charT* s, size_type n, size_type pos=0) const { @@ -215,7 +220,7 @@ namespace boost { // Searches BOOST_CONSTEXPR bool starts_with(charT c) const BOOST_NOEXCEPT { // Boost extension return !empty() && traits::eq(c, front()); - } + } BOOST_CONSTEXPR bool starts_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension return len_ >= x.len_ && traits::compare(ptr_, x.ptr_, x.len_) == 0; @@ -226,7 +231,7 @@ namespace boost { } BOOST_CONSTEXPR bool ends_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension - return len_ >= x.len_ && + return len_ >= x.len_ && traits::compare(ptr_ + len_ - x.len_, x.ptr_, x.len_) == 0; } @@ -251,7 +256,7 @@ namespace boost { BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT { if (len_ < s.len_) return npos; - if (pos > len_ - s.len_) + if (pos > len_ - s.len_) pos = len_ - s.len_; if (s.len_ == 0u) // an empty string is always found return pos; @@ -368,7 +373,7 @@ namespace boost { // Inequality template inline bool operator!=(basic_string_view x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { if ( x.size () != y.size ()) return true; return x.compare(y) != 0; } @@ -376,173 +381,173 @@ namespace boost { // Less than template inline bool operator<(basic_string_view x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return x.compare(y) < 0; } // Greater than template inline bool operator>(basic_string_view x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return x.compare(y) > 0; } // Less than or equal to template inline bool operator<=(basic_string_view x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return x.compare(y) <= 0; } // Greater than or equal to template inline bool operator>=(basic_string_view x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return x.compare(y) >= 0; } // "sufficient additional overloads of comparison functions" template inline bool operator==(basic_string_view x, - const std::basic_string & y) BOOST_NOEXCEPT { + const std::basic_string & y) BOOST_NOEXCEPT { return x == basic_string_view(y); } template inline bool operator==(const std::basic_string & x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) == y; } template inline bool operator==(basic_string_view x, - const charT * y) BOOST_NOEXCEPT { + const charT * y) BOOST_NOEXCEPT { return x == basic_string_view(y); } template inline bool operator==(const charT * x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) == y; } template inline bool operator!=(basic_string_view x, - const std::basic_string & y) BOOST_NOEXCEPT { + const std::basic_string & y) BOOST_NOEXCEPT { return x != basic_string_view(y); } template inline bool operator!=(const std::basic_string & x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) != y; } template inline bool operator!=(basic_string_view x, - const charT * y) BOOST_NOEXCEPT { + const charT * y) BOOST_NOEXCEPT { return x != basic_string_view(y); } template inline bool operator!=(const charT * x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) != y; } template inline bool operator<(basic_string_view x, - const std::basic_string & y) BOOST_NOEXCEPT { + const std::basic_string & y) BOOST_NOEXCEPT { return x < basic_string_view(y); } template inline bool operator<(const std::basic_string & x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) < y; } template inline bool operator<(basic_string_view x, - const charT * y) BOOST_NOEXCEPT { + const charT * y) BOOST_NOEXCEPT { return x < basic_string_view(y); } template inline bool operator<(const charT * x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) < y; } template inline bool operator>(basic_string_view x, - const std::basic_string & y) BOOST_NOEXCEPT { + const std::basic_string & y) BOOST_NOEXCEPT { return x > basic_string_view(y); } template inline bool operator>(const std::basic_string & x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) > y; } template inline bool operator>(basic_string_view x, - const charT * y) BOOST_NOEXCEPT { + const charT * y) BOOST_NOEXCEPT { return x > basic_string_view(y); } template inline bool operator>(const charT * x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) > y; } template inline bool operator<=(basic_string_view x, - const std::basic_string & y) BOOST_NOEXCEPT { + const std::basic_string & y) BOOST_NOEXCEPT { return x <= basic_string_view(y); } template inline bool operator<=(const std::basic_string & x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) <= y; } template inline bool operator<=(basic_string_view x, - const charT * y) BOOST_NOEXCEPT { + const charT * y) BOOST_NOEXCEPT { return x <= basic_string_view(y); } template inline bool operator<=(const charT * x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) <= y; } template inline bool operator>=(basic_string_view x, - const std::basic_string & y) BOOST_NOEXCEPT { + const std::basic_string & y) BOOST_NOEXCEPT { return x >= basic_string_view(y); } template inline bool operator>=(const std::basic_string & x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) >= y; } template inline bool operator>=(basic_string_view x, - const charT * y) BOOST_NOEXCEPT { + const charT * y) BOOST_NOEXCEPT { return x >= basic_string_view(y); } template inline bool operator>=(const charT * x, - basic_string_view y) BOOST_NOEXCEPT { + basic_string_view y) BOOST_NOEXCEPT { return basic_string_view(x) >= y; } diff --git a/test/string_view_test2.cpp b/test/string_view_test2.cpp index be04231..b9675d2 100644 --- a/test/string_view_test2.cpp +++ b/test/string_view_test2.cpp @@ -7,10 +7,14 @@ For more information, see http://www.boost.org */ +#include // for placement new #include -#include // for std::strchr +#include // for NULL, std::size_t, std::ptrdiff_t +#include // for std::strchr and std::strcmp +#include // for std::malloc and std::free #include +#include #define BOOST_TEST_MAIN #include @@ -83,7 +87,7 @@ void reverse ( const char *arg ) { BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ())); } -// This helper function eliminates signed vs. unsigned warnings +// This helper function eliminates signed vs. unsigned warnings string_view::size_type ptr_diff ( const char *res, const char *base ) { BOOST_CHECK ( res >= base ); return static_cast ( res - base ); @@ -112,7 +116,7 @@ void find ( const char *arg ) { ++p; } -// Look for pairs on characters (searching from the start) +// Look for pairs on characters (searching from the start) sr1 = arg; p = arg; while ( *p && *(p+1)) { @@ -241,6 +245,86 @@ void find ( const char *arg ) { } +template +class custom_allocator { +public: + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef void* void_pointer; + typedef const void* const_void_pointer; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T& reference; + typedef const T& const_reference; + + template + struct rebind { + typedef custom_allocator other; + }; + + custom_allocator() BOOST_NOEXCEPT {} + template + custom_allocator(custom_allocator const&) BOOST_NOEXCEPT {} + + pointer allocate(size_type n) const { + return static_cast(std::malloc(sizeof(value_type) * n)); + } + void deallocate(pointer p, size_type) const BOOST_NOEXCEPT { + std::free(p); + } + + pointer address(reference value) const BOOST_NOEXCEPT { + return &value; + } + + const_pointer address(const_reference value) const BOOST_NOEXCEPT { + return &value; + } + + BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { + return (~(size_type)0u) / sizeof(value_type); + } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + void construct(U* ptr, Args&&... args) const { + ::new((void*)ptr) U(static_cast(args)...); + } +#else + template + void construct(U* ptr, V&& value) const { + ::new((void*)ptr) U(static_cast(value)); + } +#endif +#else + template + void construct(U* ptr, const V& value) const { + ::new((void*)ptr) U(value); + } +#endif + + template + void construct(U* ptr) const { + ::new((void*)ptr) U(); + } + + template + void destroy(U* ptr) const { + (void)ptr; + ptr->~U(); + } + }; + +template +BOOST_CONSTEXPR bool operator==(const custom_allocator &, const custom_allocator &) BOOST_NOEXCEPT { + return true; + } +template +BOOST_CONSTEXPR bool operator!=(const custom_allocator &, const custom_allocator &) BOOST_NOEXCEPT { + return false; + } void to_string ( const char *arg ) { string_view sr1; @@ -249,13 +333,16 @@ void to_string ( const char *arg ) { str1.assign ( arg ); sr1 = arg; -// str2 = sr1.to_string > (); +// str2 = sr1.to_string > (); str2 = sr1.to_string (); BOOST_CHECK ( str1 == str2 ); + std::basic_string, custom_allocator > str3 = sr1.to_string(custom_allocator()); + BOOST_CHECK ( std::strcmp(str1.c_str(), str3.c_str()) == 0 ); + #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS - std::string str3 = static_cast ( sr1 ); - BOOST_CHECK ( str1 == str3 ); + std::string str4 = static_cast ( sr1 ); + BOOST_CHECK ( str1 == str4 ); #endif } @@ -266,11 +353,11 @@ void compare ( const char *arg ) { str1.assign ( arg ); sr1 = arg; - BOOST_CHECK ( sr1 == sr1); // compare string_view and string_view - BOOST_CHECK ( sr1 == str1); // compare string and string_view - BOOST_CHECK ( str1 == sr1 ); // compare string_view and string - BOOST_CHECK ( sr1 == arg ); // compare string_view and pointer - BOOST_CHECK ( arg == sr1 ); // compare pointer and string_view + BOOST_CHECK ( sr1 == sr1); // compare string_view and string_view + BOOST_CHECK ( sr1 == str1); // compare string and string_view + BOOST_CHECK ( str1 == sr1 ); // compare string_view and string + BOOST_CHECK ( sr1 == arg ); // compare string_view and pointer + BOOST_CHECK ( arg == sr1 ); // compare pointer and string_view if ( sr1.size () > 0 ) { (*str1.rbegin())++;