From 199a89a1e9e1ae3761c4cbefd1a7d3f99ee4493d Mon Sep 17 00:00:00 2001 From: Pavol Droba Date: Fri, 3 Jun 2011 21:13:37 +0000 Subject: [PATCH] merged from trunk [SVN r72380] --- .../algorithm/string/detail/formatter.hpp | 25 ++ include/boost/algorithm/string/formatter.hpp | 23 +- include/boost/algorithm/string/trim_all.hpp | 217 ++++++++++++++++++ string/test/replace_test.cpp | 21 ++ string/test/trim_test.cpp | 88 ++++++- 5 files changed, 370 insertions(+), 4 deletions(-) create mode 100644 include/boost/algorithm/string/trim_all.hpp diff --git a/include/boost/algorithm/string/detail/formatter.hpp b/include/boost/algorithm/string/detail/formatter.hpp index bd6a780..8e7b727 100644 --- a/include/boost/algorithm/string/detail/formatter.hpp +++ b/include/boost/algorithm/string/detail/formatter.hpp @@ -87,6 +87,31 @@ namespace boost { } }; +// dissect format functor ----------------------------------------------------// + + // dissect format functor + template + struct dissect_formatF + { + public: + // Construction + dissect_formatF(FinderT Finder) : + m_Finder(Finder) {} + + // Operation + template + inline iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> + operator()(const RangeT& Replace) const + { + return m_Finder(::boost::begin(Replace), ::boost::end(Replace)); + } + + private: + FinderT m_Finder; + }; + + } // namespace detail } // namespace algorithm } // namespace boost diff --git a/include/boost/algorithm/string/formatter.hpp b/include/boost/algorithm/string/formatter.hpp index 50006df..ab5921e 100644 --- a/include/boost/algorithm/string/formatter.hpp +++ b/include/boost/algorithm/string/formatter.hpp @@ -36,7 +36,7 @@ namespace boost { //! Constant formatter /*! - Construct the \c const_formatter. Const formatter always returns + Constructs a \c const_formatter. Const formatter always returns the same value, regardless of the parameter. \param Format A predefined value used as a result for formating @@ -55,7 +55,7 @@ namespace boost { //! Identity formatter /*! - Construct the \c identity_formatter. Identity formatter always returns + Constructs an \c identity_formatter. Identity formatter always returns the parameter. \return An instance of the \c identity_formatter object. @@ -73,7 +73,7 @@ namespace boost { //! Empty formatter /*! - Construct the \c empty_formatter. Empty formatter always returns an empty + Constructs an \c empty_formatter. Empty formatter always returns an empty sequence. \param Input container used to select a correct value_type for the @@ -89,6 +89,22 @@ namespace boost { BOOST_STRING_TYPENAME range_value::type>(); } + //! Empty formatter + /*! + Constructs a \c dissect_formatter. Dissect formatter uses a specified finder + to extract a portion of the formatted sequence. The first finder's match is returned + as a result + + \param Finder a finder used to select a portion of the formated sequence + \return An instance of the \c dissect_formatter object. + */ + template + inline detail::dissect_formatF< FinderT > + dissect_formatter(const FinderT& Finder) + { + return detail::dissect_formatF(Finder); + } + } // namespace algorithm @@ -96,6 +112,7 @@ namespace boost { using algorithm::const_formatter; using algorithm::identity_formatter; using algorithm::empty_formatter; + using algorithm::dissect_formatter; } // namespace boost diff --git a/include/boost/algorithm/string/trim_all.hpp b/include/boost/algorithm/string/trim_all.hpp new file mode 100644 index 0000000..70fd041 --- /dev/null +++ b/include/boost/algorithm/string/trim_all.hpp @@ -0,0 +1,217 @@ +// Boost string_algo library trim.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_TRIM_ALL_HPP +#define BOOST_STRING_TRIM_ALL_HPP + +#include + +#include +#include +#include +#include +#include +#include + +/*! \file + Defines trim_all algorithms. + + Just like \c trim, \c trim_all removes all trailing and leading spaces from a + sequence (string). In addition, spaces in the middle of the sequence are truncated + to just one character. Space is recognized using given locales. + + \c trim_fill acts as trim_all, but the spaces in the middle are replaces with + a user-define sequence of character. + + Parametric (\c _if) variants use a predicate (functor) to select which characters + are to be trimmed.. + Functions take a selection predicate as a parameter, which is used to determine + whether a character is a space. Common predicates are provided in classification.hpp header. + +*/ + +namespace boost { + namespace algorithm { + + // multi line trim ----------------------------------------------- // + + //! Trim All - parametric + /*! + Remove all leading and trailing spaces from the input and + compress all other spaces to a single character. + The result is a trimmed copy of the input + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + \return A trimmed copy of the input + */ + template + inline SequenceT trim_all_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + return + ::boost::find_format_all_copy( + ::boost::trim_copy_if(Input, IsSpace), + ::boost::token_finder(IsSpace, ::boost::token_compress_on), + ::boost::dissect_formatter(::boost::head_finder(1))); + } + + + //! Trim All + /*! + Remove all leading and trailing spaces from the input and + compress all other spaces to a single character. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + */ + template + inline void trim_all_if(SequenceT& Input, PredicateT IsSpace) + { + ::boost::trim_if(Input, IsSpace); + ::boost::find_format_all( + Input, + ::boost::token_finder(IsSpace, ::boost::token_compress_on), + ::boost::dissect_formatter(::boost::head_finder(1))); + } + + + //! Trim All + /*! + Remove all leading and trailing spaces from the input and + compress all other spaces to a single character. + The result is a trimmed copy of the input + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + */ + template + inline SequenceT trim_all_copy(const SequenceT& Input, const std::locale& Loc =std::locale()) + { + return trim_all_copy_if(Input, ::boost::is_space(Loc)); + } + + + //! Trim All + /*! + Remove all leading and trailing spaces from the input and + compress all other spaces to a single character. + The input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + */ + template + inline void trim_all(SequenceT& Input, const std::locale& Loc =std::locale()) + { + trim_all_if(Input, ::boost::is_space(Loc)); + } + + + //! Trim Fill - parametric + /*! + Remove all leading and trailing spaces from the input and + replace all every block of consecutive spaces with a fill string + defined by user. + The result is a trimmed copy of the input + + \param Input An input sequence + \param Fill A string used to fill the inner spaces + \param IsSpace An unary predicate identifying spaces + \return A trimmed copy of the input + */ + template + inline SequenceT trim_fill_copy_if(const SequenceT& Input, const RangeT& Fill, PredicateT IsSpace) + { + return + ::boost::find_format_all_copy( + ::boost::trim_copy_if(Input, IsSpace), + ::boost::token_finder(IsSpace, ::boost::token_compress_on), + ::boost::const_formatter(::boost::as_literal(Fill))); + } + + + //! Trim Fill + /*! + Remove all leading and trailing spaces from the input and + replace all every block of consecutive spaces with a fill string + defined by user. + The input sequence is modified in-place. + + \param Input An input sequence + \param Fill A string used to fill the inner spaces + \param IsSpace An unary predicate identifying spaces + */ + template + inline void trim_fill_if(SequenceT& Input, const RangeT& Fill, PredicateT IsSpace) + { + ::boost::trim_if(Input, IsSpace); + ::boost::find_format_all( + Input, + ::boost::token_finder(IsSpace, ::boost::token_compress_on), + ::boost::const_formatter(::boost::as_literal(Fill))); + } + + + //! Trim Fill + /*! + Remove all leading and trailing spaces from the input and + replace all every block of consecutive spaces with a fill string + defined by user. + The result is a trimmed copy of the input + + \param Input An input sequence + \param Fill A string used to fill the inner spaces + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + */ + template + inline SequenceT trim_fill_copy(const SequenceT& Input, const RangeT& Fill, const std::locale& Loc =std::locale()) + { + return trim_fill_copy_if(Input, Fill, ::boost::is_space(Loc)); + } + + + //! Trim Fill + /*! + Remove all leading and trailing spaces from the input and + replace all every block of consecutive spaces with a fill string + defined by user. + The input sequence is modified in-place. + + \param Input An input sequence + \param Fill A string used to fill the inner spaces + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + */ + template + inline void trim_fill(SequenceT& Input, const RangeT& Fill, const std::locale& Loc =std::locale()) + { + trim_fill_if(Input, Fill, ::boost::is_space(Loc)); + } + + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::trim_all; + using algorithm::trim_all_if; + using algorithm::trim_all_copy; + using algorithm::trim_all_copy_if; + using algorithm::trim_fill; + using algorithm::trim_fill_if; + using algorithm::trim_fill_copy; + using algorithm::trim_fill_copy_if; + +} // namespace boost + +#endif // BOOST_STRING_TRIM_ALL_HPP diff --git a/string/test/replace_test.cpp b/string/test/replace_test.cpp index f9239f6..7264ea9 100644 --- a/string/test/replace_test.cpp +++ b/string/test/replace_test.cpp @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include // Include unit test framework #include @@ -285,6 +288,23 @@ void collection_comp_test() } } +void dissect_format_test() +{ + BOOST_CHECK( + find_format_all_copy( + string("aBc123Abc"), + first_finder("abc", is_iequal()), + dissect_formatter(token_finder(is_upper())))=="B123A"); + + + BOOST_CHECK( + find_format_all_copy( + string("abc 123 abc"), + token_finder(is_space(), token_compress_on), + dissect_formatter(head_finder(1)))=="abc 123 abc"); + +} + // test main int test_main( int, char*[] ) { @@ -297,6 +317,7 @@ int test_main( int, char*[] ) replace_tail_test(); replace_range_test(); collection_comp_test(); + dissect_format_test(); return 0; } diff --git a/string/test/trim_test.cpp b/string/test/trim_test.cpp index ed80c28..8dcce28 100644 --- a/string/test/trim_test.cpp +++ b/string/test/trim_test.cpp @@ -8,6 +8,7 @@ // See http://www.boost.org for updates, documentation, and revision history. #include +#include // Include unit test framework #include @@ -109,10 +110,95 @@ void trim_test() BOOST_CHECK( trim_copy_if( string("<>abc<>"), is_any_of( "<<>>" ) )=="abc" ); } +void trim_all_test() +{ + string str1(" 1x x x x1 "); + string str2("+---...2x+--x--+x-+-x2...---+"); + string str3(" "); + + // *** value passing tests *** // + + // general string test + BOOST_CHECK( trim_all_copy( str1 )=="1x x x x1" ) ; + BOOST_CHECK( trim_all_copy_if( str2, is_punct() )=="2x+x-x-x2" ) ; + + // spaces-only string test + BOOST_CHECK( trim_all_copy( str3 )=="" ); + + // empty string check + BOOST_CHECK( trim_all_copy( string("") )=="" ); + + // general string test + trim_all( str1 ); + BOOST_CHECK( str1=="1x x x x1" ) ; + trim_all_if( str2, is_punct() ); + BOOST_CHECK( str2=="2x+x-x-x2" ) ; + + // spaces-only string test + str3 = " "; trim_all( str3 ); + BOOST_CHECK( str3=="" ); + + // empty string check + str3 = ""; trim_all( str3 ); + BOOST_CHECK( str3=="" ); + BOOST_CHECK( str3=="" ); + + // *** non-standard predicate tests *** // + BOOST_CHECK( + trim_all_copy_if( + string("123abc127deb456"), + is_classified(std::ctype_base::digit) )=="abc1deb" ); + BOOST_CHECK( trim_all_copy_if( string("<>abc<>def<>"), is_any_of( "<<>>" ) )=="abcabc<>def<>"), "-", is_any_of( "<<>>" ) )=="abc-def" ); +} + // test main int test_main( int, char*[] ) { trim_test(); - + trim_all_test(); + trim_fill_test(); + return 0; }