From c6f784cb7034b0a8c3183086fcd7ed8389e50a03 Mon Sep 17 00:00:00 2001 From: Ben10do Date: Wed, 1 Aug 2018 20:54:17 +0100 Subject: [PATCH 1/3] Use forwarding references in string/split.hpp On compilers that support C++11, this allows both lvalues and rvalues to be used as inputs to the split(), find_all(), and ifind_all() functions. For example, given a function get_string() that returns a std::string, this allows you to write: boost::split(result, get_string(), boost::is_any_of(" ")) --- include/boost/algorithm/string/iter_find.hpp | 8 ++++++++ include/boost/algorithm/string/split.hpp | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/boost/algorithm/string/iter_find.hpp b/include/boost/algorithm/string/iter_find.hpp index 10424ab..d76a819 100644 --- a/include/boost/algorithm/string/iter_find.hpp +++ b/include/boost/algorithm/string/iter_find.hpp @@ -71,7 +71,11 @@ namespace boost { inline SequenceSequenceT& iter_find( SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + RangeT&& Input, +#else RangeT& Input, +#endif FinderT Finder ) { BOOST_CONCEPT_ASSERT(( @@ -142,7 +146,11 @@ namespace boost { inline SequenceSequenceT& iter_split( SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + RangeT&& Input, +#else RangeT& Input, +#endif FinderT Finder ) { BOOST_CONCEPT_ASSERT(( diff --git a/include/boost/algorithm/string/split.hpp b/include/boost/algorithm/string/split.hpp index cae712c..e0b30fb 100644 --- a/include/boost/algorithm/string/split.hpp +++ b/include/boost/algorithm/string/split.hpp @@ -61,7 +61,11 @@ namespace boost { template< typename SequenceSequenceT, typename Range1T, typename Range2T > inline SequenceSequenceT& find_all( SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + Range1T&& Input, +#else Range1T& Input, +#endif const Range2T& Search) { return ::boost::algorithm::iter_find( @@ -96,7 +100,11 @@ namespace boost { template< typename SequenceSequenceT, typename Range1T, typename Range2T > inline SequenceSequenceT& ifind_all( SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + Range1T&& Input, +#else Range1T& Input, +#endif const Range2T& Search, const std::locale& Loc=std::locale() ) { @@ -139,7 +147,11 @@ namespace boost { template< typename SequenceSequenceT, typename RangeT, typename PredicateT > inline SequenceSequenceT& split( SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + RangeT&& Input, +#else RangeT& Input, +#endif PredicateT Pred, token_compress_mode_type eCompress=token_compress_off ) { From 5408a17020ba7d7467288ce59f820a07ae890142 Mon Sep 17 00:00:00 2001 From: Ben10do Date: Wed, 1 Aug 2018 22:42:18 +0100 Subject: [PATCH 2/3] Add tests with lvalue inputs If the compiler supports forwarding references, we now test if lvalues can be used as input strings for split(), find_all(), and ifind_all(). Note that MSVC (without its recent /permissive- flag) may pass these tests without the forwarding references changes that I made, due to its non-standard binding of lvalues to rvalues. --- string/test/split_test.cpp | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/string/test/split_test.cpp b/string/test/split_test.cpp index 582472b..d7e9186 100644 --- a/string/test/split_test.cpp +++ b/string/test/split_test.cpp @@ -7,6 +7,8 @@ // See http://www.boost.org for updates, documentation, and revision history. +#include + #include #include // equals predicate is used for result comparison @@ -82,6 +84,28 @@ void iterator_test() string("xx") ); deep_compare( tokens, vtokens ); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + // If using a compiler that supports forwarding references, we should be able to use lvalues, too + find_all( + tokens, + string("xx-abc--xx-abb"), + "xx" ); + + BOOST_REQUIRE( tokens.size()==2 ); + BOOST_CHECK( tokens[0]==string("xx") ); + BOOST_CHECK( tokens[1]==string("xx") ); + + ifind_all( + tokens, + string("Xx-abc--xX-abb-xx"), + "xx" ); + + BOOST_REQUIRE( tokens.size()==3 ); + BOOST_CHECK( tokens[0]==string("Xx") ); + BOOST_CHECK( tokens[1]==string("xX") ); + BOOST_CHECK( tokens[2]==string("xx") ); +#endif + // split tests split( tokens, @@ -144,6 +168,21 @@ void iterator_test() BOOST_REQUIRE( tokens.size()==1 ); BOOST_CHECK( tokens[0]==string("") ); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + // If using a compiler that supports forwarding references, we should be able to use lvalues, too + split( + tokens, + string("Xx-abc--xX-abb-xx"), + is_any_of("xX"), + token_compress_on ); + + BOOST_REQUIRE( tokens.size()==4 ); + BOOST_CHECK( tokens[0]==string("") ); + BOOST_CHECK( tokens[1]==string("-abc--") ); + BOOST_CHECK( tokens[2]==string("-abb-") ); + BOOST_CHECK( tokens[3]==string("") ); +#endif + find_iterator fiter=make_find_iterator(str1, first_finder("xx")); find_iterator fiter2; From 45baad2431913db14ff0d2d014226985bf3602ae Mon Sep 17 00:00:00 2001 From: Ben10do Date: Thu, 2 Aug 2018 22:18:54 +0100 Subject: [PATCH 3/3] Correct lvalue/rvalue nomenclature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I accidentally referred to the additional tests as using lvalues as inputs, when they’re actually using rvalues. This commit corrects the relevant comments. --- string/test/split_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/string/test/split_test.cpp b/string/test/split_test.cpp index d7e9186..3dbcfac 100644 --- a/string/test/split_test.cpp +++ b/string/test/split_test.cpp @@ -85,7 +85,7 @@ void iterator_test() deep_compare( tokens, vtokens ); #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - // If using a compiler that supports forwarding references, we should be able to use lvalues, too + // If using a compiler that supports forwarding references, we should be able to use rvalues, too find_all( tokens, string("xx-abc--xx-abb"), @@ -169,7 +169,7 @@ void iterator_test() BOOST_CHECK( tokens[0]==string("") ); #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - // If using a compiler that supports forwarding references, we should be able to use lvalues, too + // If using a compiler that supports forwarding references, we should be able to use rvalues, too split( tokens, string("Xx-abc--xX-abb-xx"),