From fde7e1fbdd7a830e46b80cbe55d382a760892aea Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 13 Feb 2017 11:35:27 -0800 Subject: [PATCH 1/4] Add support for `boost::string_view` into `container::basic_string` Conversion from a `basic_string` to a `string_view`, and make all the comparisons work. Ion - if you like this, I'll work up some tests, too. --- include/boost/container/string.hpp | 100 +++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index 1e47aba..db65bf3 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -58,6 +58,7 @@ #include #include #include +#include namespace boost { namespace container { @@ -2059,6 +2060,12 @@ class basic_string const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW { return container_detail::to_raw_pointer(this->priv_addr()); } + //! Returns: a string_view to the characters in the string. + //! + //! Complexity: constant time. + operator boost::basic_string_view() const BOOST_NOEXCEPT_OR_NOTHROW + { return boost::basic_string_view(data(), size()); } + ////////////////////////////////////////////// // // string operations @@ -2463,6 +2470,16 @@ class basic_string } + //! Throws: Nothing + //! + //! Returns: compare(basic_string(sv)). + int compare(boost::basic_string_view sv) const + { + const pointer addr = this->priv_addr(); + return s_compare(addr, addr + this->priv_size(), + sv.data(), sv.data() + sv.size()); + } + //! Requires: pos1 > size() and s points to an array of at least n2 elements of CharT. //! //! Throws: out_of_range if pos1 > size() @@ -2776,6 +2793,25 @@ operator==(const basic_string& x, const CharT* s) return x.size() == n && Traits::compare(x.data(), s, n) == 0; } +template +inline bool +operator==( boost::basic_string_view x, + const basic_string& y) +{ + return x.size() == y.size() && + Traits::compare(x.data(), y.data(), x.size()) == 0; +} + +template +inline bool +operator==( const basic_string& x, + boost::basic_string_view y) +{ + return x.size() == y.size() && + Traits::compare(x.data(), y.data(), x.size()) == 0; +} + + template inline bool operator!=(const basic_string& x, @@ -2793,6 +2829,19 @@ operator!=(const basic_string& x, const CharT* s) { return !(x == s); } +template +inline bool +operator!=( boost::basic_string_view x, + const basic_string& y) + { return !(x == y); } + +template +inline bool +operator!=( const basic_string& x, + boost::basic_string_view y) + { return !(x == y); } + + // Operator< (and also >, <=, and >=). template @@ -2825,6 +2874,18 @@ operator<(const basic_string& x, // ::s_compare(x.begin(), x.end(), s, s + n) < 0; } +template +inline bool +operator<( boost::basic_string_view x, + const basic_string& y) + { return x.compare(y) < 0; } + +template +inline bool +operator<( const basic_string& x, + boost::basic_string_view y) + { return y.compare(x) > 0; } + template inline bool operator>(const basic_string& x, @@ -2845,6 +2906,19 @@ operator>(const basic_string& x, const CharT* s) return s < x; } +template +inline bool +operator>( boost::basic_string_view x, + const basic_string& y) + { return y < x; } + +template +inline bool +operator>( const basic_string& x, + boost::basic_string_view y) + { return y < x; } + + template inline bool operator<=(const basic_string& x, @@ -2863,6 +2937,19 @@ inline bool operator<=(const basic_string& x, const CharT* s) { return !(s < x); } + +template +inline bool +operator<=( boost::basic_string_view x, + const basic_string& y) + { return !(y < x); } + +template +inline bool +operator<=( const basic_string& x, + boost::basic_string_view y) + { return !(y < x); } + template inline bool operator>=(const basic_string& x, @@ -2879,6 +2966,19 @@ inline bool operator>=(const basic_string& x, const CharT* s) { return !(x < s); } +template +inline bool +operator>=( boost::basic_string_view x, + const basic_string& y) + { return !(x < y); } + +template +inline bool +operator>=( const basic_string& x, + boost::basic_string_view y) + { return !(x < y); } + + // Swap. template inline void swap(basic_string& x, basic_string& y) From 865c69bab72e760f97c4bd073bf59bdeb5623d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 21 Feb 2017 14:27:18 +0100 Subject: [PATCH 2/4] Changed string_view interoperability to a templated solution in order to support also std::string_view. Added missing members and testcases. --- doc/container.qbk | 7 +- include/boost/container/detail/workaround.hpp | 4 + include/boost/container/string.hpp | 404 ++++++++++++------ proj/vc7ide/container.sln | 8 + proj/vc7ide/container.vcproj | 3 - proj/vc7ide/string_view_compat_test.vcproj | 136 ++++++ test/string_test.cpp | 9 +- test/string_view_compat_test.cpp | 275 ++++++++++++ 8 files changed, 707 insertions(+), 139 deletions(-) create mode 100644 proj/vc7ide/string_view_compat_test.vcproj create mode 100644 test/string_view_compat_test.cpp diff --git a/doc/container.qbk b/doc/container.qbk index aa43fe7..aa31f0a 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1217,15 +1217,16 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes_boost_1_64_00 Boost 1.64 Release] * Fixed bugs: - * [@https://svn.boost.org/trac/boost/ticket/12749 Trac #12749 : ['"container::pmr::polymorphic_allocator compilation error"]]. + * [@https://svn.boost.org/trac/boost/ticket/12749 Trac #12749: ['"container::pmr::polymorphic_allocator compilation error"]]. + * [@https://svn.boost.org/trac/boost/ticket/11333 Trac #11333: ['"boost::basic_string_ref should interop with boost::container::basic_string"]]. [endsect] [section:release_notes_boost_1_63_00 Boost 1.63 Release] * Fixed bugs: - * [@https://svn.boost.org/trac/boost/ticket/12534 Trac #12534: ['"flat_map fails to compile if included after type_traits is instantiated under gcc"]]. - * [@https://svn.boost.org/trac/boost/ticket/12577 Trac #12577: ['"Null reference in pair.hpp triggers runtime warning with -fsanitize=undefined"]]. + * [@https://svn.boost.org/trac/boost/ticket/12534 Trac #12534: ['"flat_map fails to compile if included after type_traits is instantiated under gcc"]]. + * [@https://svn.boost.org/trac/boost/ticket/12577 Trac #12577: ['"Null reference in pair.hpp triggers runtime warning with -fsanitize=undefined"]]. * [@https://github.com/boostorg/container/pull/41 GitHub #40: ['Fix parameter types in copy_move_algo.hpp: iterator_traits::difference_type -> allocator_traits::size_type]]. * [@https://github.com/boostorg/container/pull/41 GitHub #41: ['Avoid -Wunreachable-code in do_allocate()]]. diff --git a/include/boost/container/detail/workaround.hpp b/include/boost/container/detail/workaround.hpp index ed57718..816d3cc 100644 --- a/include/boost/container/detail/workaround.hpp +++ b/include/boost/container/detail/workaround.hpp @@ -49,6 +49,10 @@ #define BOOST_CONTAINER_FALLTHOUGH BOOST_FALLTHOUGH; #endif +#if defined(BOOST_MSVC) && (_MSC_VER < 1400) + #define BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN +#endif + #if !defined(BOOST_NO_CXX11_HDR_TUPLE) || (defined(BOOST_MSVC) && (BOOST_MSVC == 1700 || BOOST_MSVC == 1600)) #define BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE #endif diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index db65bf3..cb219c5 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -58,7 +58,6 @@ #include #include #include -#include namespace boost { namespace container { @@ -616,6 +615,17 @@ class basic_string this->assign(s.begin(), s.end()); } + //! Effects: Same as basic_string(sv.data(), sv.size(), a). + //! + //! Throws: If allocator_type's default constructor or allocation throws. + template