diff --git a/include/boost/algorithm/cxx11/copy_if.hpp b/include/boost/algorithm/cxx11/copy_if.hpp index 8591cb5..88b79b5 100644 --- a/include/boost/algorithm/cxx11/copy_if.hpp +++ b/include/boost/algorithm/cxx11/copy_if.hpp @@ -63,7 +63,7 @@ OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p ) /// \fn copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) /// \brief Copies all the elements at the start of the input range that /// satisfy the predicate to the output range. -/// \return The updated output iterator +/// \return The updated input and output iterators /// /// \param first The start of the input sequence /// \param last One past the end of the input sequence @@ -71,25 +71,26 @@ OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p ) /// \param p A predicate for testing the elements of the range /// template -OutputIterator copy_while ( InputIterator first, InputIterator last, - OutputIterator result, Predicate p ) +std::pair +copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) { for ( ; first != last && p(*first); ++first ) *result++ = *first; - return result; + return std::make_pair(first, result); } /// \fn copy_while ( const Range &r, OutputIterator result, Predicate p ) /// \brief Copies all the elements at the start of the input range that /// satisfy the predicate to the output range. -/// \return The updated output iterator +/// \return The updated input and output iterators /// /// \param r The input range /// \param result An output iterator to write the results into /// \param p A predicate for testing the elements of the range /// template -OutputIterator copy_while ( const Range &r, OutputIterator result, Predicate p ) +std::pair::type, OutputIterator> +copy_while ( const Range &r, OutputIterator result, Predicate p ) { return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p); } @@ -106,11 +107,12 @@ OutputIterator copy_while ( const Range &r, OutputIterator result, Predicate p ) /// \param p A predicate for testing the elements of the range /// template -OutputIterator copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) +std::pair +copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) { for ( ; first != last && !p(*first); ++first ) *result++ = *first; - return result; + return std::make_pair(first, result); } /// \fn copy_until ( const Range &r, OutputIterator result, Predicate p ) @@ -123,7 +125,8 @@ OutputIterator copy_until ( InputIterator first, InputIterator last, OutputItera /// \param p A predicate for testing the elements of the range /// template -OutputIterator copy_until ( const Range &r, OutputIterator result, Predicate p ) +std::pair::type, OutputIterator> +copy_until ( const Range &r, OutputIterator result, Predicate p ) { return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p); } diff --git a/test/copy_if_test1.cpp b/test/copy_if_test1.cpp index b237055..59944bc 100644 --- a/test/copy_if_test1.cpp +++ b/test/copy_if_test1.cpp @@ -20,6 +20,7 @@ #include #include +#include namespace ba = boost::algorithm; // namespace ba = boost; @@ -30,7 +31,7 @@ bool is_even ( int v ) { return v % 2 == 0; } bool is_odd ( int v ) { return v % 2 == 1; } template -void test_sequence ( Container const &c ) { +void test_copy_if ( Container const &c ) { typedef typename Container::value_type value_type; std::vector v; @@ -48,13 +49,13 @@ void test_sequence ( Container const &c ) { v.clear (); ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_true); BOOST_CHECK ( v.size () == c.size ()); - BOOST_CHECK ( std::equal ( c.begin (), c.end (), v.begin ())); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); v.clear (); ba::copy_if ( c, back_inserter ( v ), is_true); BOOST_CHECK ( v.size () == c.size ()); BOOST_CHECK ( v.size () == c.size ()); - BOOST_CHECK ( std::equal ( c.begin (), c.end (), v.begin ())); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); // Some of the elements v.clear (); @@ -69,16 +70,106 @@ void test_sequence ( Container const &c ) { } +template +void test_copy_while ( Container const &c ) { + + typedef typename Container::value_type value_type; + typename Container::const_iterator it; + std::vector v; + +// None of the elements + v.clear (); + ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_false); + BOOST_CHECK ( v.size () == 0 ); + + v.clear (); + ba::copy_while ( c, back_inserter ( v ), is_false); + BOOST_CHECK ( v.size () == 0 ); + +// All the elements + v.clear (); + ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_true); + BOOST_CHECK ( v.size () == c.size ()); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); + + v.clear (); + ba::copy_while ( c, back_inserter ( v ), is_true); + BOOST_CHECK ( v.size () == c.size ()); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); + +// Some of the elements + v.clear (); + it = ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_even ).first; + BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it )); + BOOST_CHECK ( it == c.end () || !is_even ( *it )); + BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even )); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); + + v.clear (); + it = ba::copy_while ( c, back_inserter ( v ), is_even ).first; + BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it )); + BOOST_CHECK ( it == c.end () || !is_even ( *it )); + BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even )); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); + } + +template +void test_copy_until ( Container const &c ) { + + typedef typename Container::value_type value_type; + typename Container::const_iterator it; + std::vector v; + +// None of the elements + v.clear (); + ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_true); + BOOST_CHECK ( v.size () == 0 ); + + v.clear (); + ba::copy_until ( c, back_inserter ( v ), is_true); + BOOST_CHECK ( v.size () == 0 ); + +// All the elements + v.clear (); + ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_false); + BOOST_CHECK ( v.size () == c.size ()); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); + + v.clear (); + ba::copy_until ( c, back_inserter ( v ), is_false); + BOOST_CHECK ( v.size () == c.size ()); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); + +// Some of the elements + v.clear (); + it = ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_even ).first; + BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it )); + BOOST_CHECK ( it == c.end () || is_even ( *it )); + BOOST_CHECK ( ba::none_of ( v.begin (), v.end (), is_even )); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); + + v.clear (); + it = ba::copy_until ( c, back_inserter ( v ), is_even ).first; + BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it )); + BOOST_CHECK ( it == c.end () || is_even ( *it )); + BOOST_CHECK ( ba::none_of ( v.begin (), v.end (), is_even )); + BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); + } + void test_sequence1 () { std::vector v; for ( int i = 5; i < 15; ++i ) v.push_back ( i ); - test_sequence ( v ); + test_copy_if ( v ); + test_copy_while ( v ); + test_copy_until ( v ); std::list l; for ( int i = 25; i > 15; --i ) l.push_back ( i ); - test_sequence ( l ); + test_copy_if ( l ); + test_copy_while ( l ); + test_copy_until ( l ); }