forked from boostorg/algorithm
Algorithms from BoostCon 'Library in a week'
[SVN r45440]
This commit is contained in:
18
copy/test/Jamfile.v2
Normal file
18
copy/test/Jamfile.v2
Normal file
@ -0,0 +1,18 @@
|
||||
# Boost.CopyIf Library test Jamfile
|
||||
#
|
||||
# Copyright (C) 2008 Marshall Clow
|
||||
#
|
||||
# Use, modification, and distribution is subject to 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)
|
||||
#
|
||||
|
||||
import testing ;
|
||||
|
||||
{
|
||||
test-suite algorithm/copy:
|
||||
: [ run copy_test.cpp
|
||||
: : : : copy ]
|
||||
;
|
||||
}
|
||||
|
250
copy/test/copy_test.cpp
Normal file
250
copy/test/copy_test.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
// (C) Copyright Marshall Clow 2008
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/copy.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
// #include <boost/algorithm/all.hpp>
|
||||
// #include <boost/algorithm/select.hpp>
|
||||
|
||||
template <int v> bool IsEqual ( int v2 ) { return v2 == v; }
|
||||
template <int v> bool IsNotEqual ( int v2 ) { return v2 != v; }
|
||||
template <int v> bool IsGreater ( int v2 ) { return v2 > v; }
|
||||
template <int v> bool IsLess ( int v2 ) { return v2 < v; }
|
||||
bool IsEven ( int v2 ) { return ( v2 & 1 ) == 0; }
|
||||
bool IsOdd ( int v2 ) { return ( v2 & 1 ) != 0; }
|
||||
|
||||
void test_copy_if ()
|
||||
{
|
||||
const int vals [] = { 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1 };
|
||||
const unsigned int valsSize = sizeof ( vals ) / sizeof ( vals [0] );
|
||||
|
||||
std::vector<int> cont;
|
||||
std::vector<int> res;
|
||||
|
||||
// Copy all but the last element
|
||||
std::copy ( vals, vals + valsSize - 1, std::back_inserter(cont));
|
||||
|
||||
// Copy_if from constant iterators
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if ( vals, vals + valsSize, std::back_inserter(res), IsEqual<0> );
|
||||
BOOST_CHECK_EQUAL ( res.size (), 5U );
|
||||
BOOST_CHECK ( std::find_if ( res.begin (), res.end (), IsNotEqual<0> ) == res.end ());
|
||||
|
||||
// Copy them all
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if ( vals, vals + valsSize, std::back_inserter(res), IsLess<100> );
|
||||
BOOST_CHECK_EQUAL ( valsSize, res.size ());
|
||||
BOOST_CHECK ( std::equal ( vals, vals + valsSize, res.begin ()));
|
||||
|
||||
// Copy none
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if ( vals, vals + valsSize, std::back_inserter(res), IsGreater<100> );
|
||||
BOOST_CHECK_EQUAL ( 0U, res.size ());
|
||||
|
||||
// Copy_if using ranges
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if ( cont, std::back_inserter(res), IsNotEqual<0> );
|
||||
BOOST_CHECK_EQUAL ( res.size (), 5U );
|
||||
BOOST_CHECK ( std::find_if ( res.begin (), res.end (), IsEqual<0> ) == res.end ());
|
||||
|
||||
// Copy them all
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if ( cont, std::back_inserter(res), IsNotEqual<2> );
|
||||
BOOST_CHECK_EQUAL ( cont.size (), res.size ());
|
||||
BOOST_CHECK ( std::equal ( cont.begin (), cont.end (), res.begin ()));
|
||||
|
||||
// Copy none
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if ( cont, std::back_inserter(res), IsEqual<2> );
|
||||
BOOST_CHECK_EQUAL ( 0U, res.size ());
|
||||
|
||||
// ---- Backwards tests ----
|
||||
const int vals2 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
const unsigned int vals2Size = sizeof ( vals2 ) / sizeof ( vals2 [0] );
|
||||
|
||||
// Copy all but the last element
|
||||
cont.clear ();
|
||||
std::copy ( vals2, vals2 + vals2Size - 1, std::back_inserter(cont));
|
||||
|
||||
// Copy_if_backward from constant iterators
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if_backward ( vals2, vals2 + vals2Size, std::back_inserter(res), IsEven );
|
||||
BOOST_CHECK_EQUAL ( res.size (), 5U );
|
||||
BOOST_CHECK_EQUAL ( res[0], 8 );
|
||||
BOOST_CHECK_EQUAL ( res[1], 6 );
|
||||
BOOST_CHECK_EQUAL ( res[2], 4 );
|
||||
BOOST_CHECK_EQUAL ( res[3], 2 );
|
||||
BOOST_CHECK_EQUAL ( res[4], 0 );
|
||||
|
||||
// Copy them all
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if_backward ( vals2, vals2 + vals2Size, std::back_inserter(res), IsLess<100> );
|
||||
BOOST_CHECK_EQUAL ( vals2Size, res.size ());
|
||||
BOOST_CHECK ( std::equal ( vals2, vals2 + vals2Size, res.rbegin ()));
|
||||
|
||||
// Copy none
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if_backward ( vals, vals + valsSize, std::back_inserter(res), IsGreater<100> );
|
||||
BOOST_CHECK_EQUAL ( 0U, res.size ());
|
||||
|
||||
|
||||
// Copy_if_backward using ranges
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if_backward ( cont, std::back_inserter(res), IsEven );
|
||||
BOOST_CHECK_EQUAL ( res.size (), 5U );
|
||||
BOOST_CHECK_EQUAL ( res[0], 8 );
|
||||
BOOST_CHECK_EQUAL ( res[1], 6 );
|
||||
BOOST_CHECK_EQUAL ( res[2], 4 );
|
||||
BOOST_CHECK_EQUAL ( res[3], 2 );
|
||||
BOOST_CHECK_EQUAL ( res[4], 0 );
|
||||
|
||||
// Copy them all
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if_backward ( cont, std::back_inserter(res), IsLess<100> );
|
||||
BOOST_CHECK_EQUAL ( cont.size (), res.size ());
|
||||
BOOST_CHECK ( std::equal ( cont.rbegin (), cont.rend (), res.begin ()));
|
||||
|
||||
// Copy none
|
||||
res.clear ();
|
||||
boost::algorithm::copy_if_backward ( vals, vals + valsSize, std::back_inserter(res), IsGreater<100> );
|
||||
BOOST_CHECK_EQUAL ( 0U, res.size ());
|
||||
}
|
||||
|
||||
void test_copy_while ()
|
||||
{
|
||||
const int vals [] = { 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1 };
|
||||
const unsigned int valsSize = sizeof ( vals ) / sizeof ( vals [0] );
|
||||
|
||||
std::vector<int> cont;
|
||||
std::vector<int> res;
|
||||
|
||||
// Copy all but the last element
|
||||
std::copy ( vals, vals + valsSize - 1, std::back_inserter(cont));
|
||||
|
||||
// Copy_while from constant iterators
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while ( vals, vals + valsSize, std::back_inserter(res), IsEqual<0> );
|
||||
BOOST_CHECK_EQUAL ( res.size (), 1U );
|
||||
BOOST_CHECK_EQUAL ( res[0], 0 );
|
||||
|
||||
// Copy them all
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while ( vals, vals + valsSize, std::back_inserter(res), IsLess<100> );
|
||||
BOOST_CHECK_EQUAL ( valsSize, res.size ());
|
||||
BOOST_CHECK ( std::equal ( vals, vals + valsSize, res.begin ()));
|
||||
|
||||
// Copy none
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while ( vals, vals + valsSize, std::back_inserter(res), IsGreater<100> );
|
||||
BOOST_CHECK_EQUAL ( 0U, res.size ());
|
||||
|
||||
// Copy_while using ranges
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while ( cont, std::back_inserter(res), IsNotEqual<1> );
|
||||
BOOST_CHECK_EQUAL ( res.size (), 1U );
|
||||
BOOST_CHECK_EQUAL ( res[0], 0 );
|
||||
|
||||
// Copy them all
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while ( cont, std::back_inserter(res), IsNotEqual<2> );
|
||||
BOOST_CHECK_EQUAL ( cont.size (), res.size ());
|
||||
BOOST_CHECK ( std::equal ( cont.begin (), cont.end (), res.begin ()));
|
||||
|
||||
// Copy none
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while ( cont, std::back_inserter(res), IsEqual<2> );
|
||||
BOOST_CHECK_EQUAL ( 0U, res.size ());
|
||||
|
||||
// ---- Backwards tests ----
|
||||
const int vals2 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
const unsigned int vals2Size = sizeof ( vals2 ) / sizeof ( vals2 [0] );
|
||||
|
||||
// Copy all but the last element
|
||||
cont.clear ();
|
||||
std::copy ( vals2, vals2 + vals2Size - 1, std::back_inserter(cont));
|
||||
|
||||
// Copy_if_backward from constant iterators
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while_backward ( vals2, vals2 + vals2Size, std::back_inserter(res), IsGreater<5> );
|
||||
BOOST_CHECK_EQUAL ( res.size (), 4U );
|
||||
BOOST_CHECK_EQUAL ( res[0], 9 );
|
||||
BOOST_CHECK_EQUAL ( res[1], 8 );
|
||||
BOOST_CHECK_EQUAL ( res[2], 7 );
|
||||
BOOST_CHECK_EQUAL ( res[3], 6 );
|
||||
|
||||
// Copy them all
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while_backward ( vals2, vals2 + vals2Size, std::back_inserter(res), IsLess<100> );
|
||||
BOOST_CHECK_EQUAL ( vals2Size, res.size ());
|
||||
BOOST_CHECK ( std::equal ( vals2, vals2 + vals2Size, res.rbegin ()));
|
||||
|
||||
// Copy none
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while_backward ( vals, vals + valsSize, std::back_inserter(res), IsGreater<100> );
|
||||
BOOST_CHECK_EQUAL ( 0U, res.size ());
|
||||
|
||||
|
||||
// Copy_while_backward using ranges
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while_backward ( cont, std::back_inserter(res), IsGreater<5> );
|
||||
BOOST_CHECK_EQUAL ( res.size (), 3U );
|
||||
BOOST_CHECK_EQUAL ( res[0], 8 );
|
||||
BOOST_CHECK_EQUAL ( res[1], 7 );
|
||||
BOOST_CHECK_EQUAL ( res[2], 6 );
|
||||
|
||||
// Copy them all
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while_backward ( cont, std::back_inserter(res), IsLess<100> );
|
||||
BOOST_CHECK_EQUAL ( cont.size (), res.size ());
|
||||
BOOST_CHECK ( std::equal ( cont.rbegin (), cont.rend (), res.begin ()));
|
||||
|
||||
// Copy none
|
||||
res.clear ();
|
||||
boost::algorithm::copy_while_backward ( vals, vals + valsSize, std::back_inserter(res), IsGreater<100> );
|
||||
BOOST_CHECK_EQUAL ( 0U, res.size ());
|
||||
}
|
||||
|
||||
void test_copy_n ()
|
||||
{
|
||||
const int vals [] = { 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1 };
|
||||
const unsigned int valsSize = sizeof ( vals ) / sizeof ( vals [0] );
|
||||
|
||||
std::vector<int> cont;
|
||||
std::vector<int> res;
|
||||
|
||||
// Copy all but the last element
|
||||
std::copy ( vals, vals + valsSize - 1, std::back_inserter(cont));
|
||||
|
||||
// copy_n from constant iterators
|
||||
res.clear ();
|
||||
boost::algorithm::copy_n ( vals, valsSize, std::back_inserter(res));
|
||||
BOOST_CHECK_EQUAL ( res.size (), valsSize );
|
||||
BOOST_CHECK ( std::equal ( vals, vals + valsSize, res.begin ()));
|
||||
|
||||
// Copy none
|
||||
res.clear ();
|
||||
boost::algorithm::copy_n ( vals, 0, std::back_inserter(res));
|
||||
BOOST_CHECK_EQUAL ( 0U, res.size ());
|
||||
|
||||
// Copy_while from container
|
||||
res.clear ();
|
||||
boost::algorithm::copy_n ( cont.begin (), cont.size (), std::back_inserter(res) );
|
||||
BOOST_CHECK_EQUAL ( res.size (), cont.size ());
|
||||
BOOST_CHECK ( std::equal ( cont.begin (), cont.end (), res.begin ()));
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
{
|
||||
test_copy_if ();
|
||||
test_copy_while ();
|
||||
test_copy_n ();
|
||||
return 0;
|
||||
}
|
260
include/boost/algorithm/all.hpp
Normal file
260
include/boost/algorithm/all.hpp
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2008.
|
||||
|
||||
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)
|
||||
|
||||
Revision history:
|
||||
05 May 2008 mtc First version - as part of BoostCon 2008
|
||||
*/
|
||||
|
||||
// Returns true iff all of the elements in [ first, last ) satisfy the predicate.
|
||||
|
||||
#ifndef BOOST_ALGORITHM_ALL_HPP
|
||||
#define BOOST_ALGORITHM_ALL_HPP
|
||||
|
||||
#include <boost/range.hpp> // For boost::begin and boost::end
|
||||
|
||||
/// \file all.hpp
|
||||
/// \brief Boost implementation of various STL-type logical algorithms
|
||||
/// \author Marshall Clow
|
||||
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn all ( I first, I last, V val )
|
||||
/// \brief Returns true if all elements in [first, last) are equal to 'val'
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename I, typename V>
|
||||
bool all ( I first, I last, const V &val )
|
||||
{
|
||||
while (first != last) {
|
||||
if ( *first++ != val )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn all ( Range range, V val )
|
||||
/// \brief Returns true if all elements in the range are equal to 'val'
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool all ( Range range, const V &val )
|
||||
{
|
||||
return all ( boost::begin ( range ), boost::end ( range ), val );
|
||||
}
|
||||
|
||||
|
||||
/// \fn all_if ( I first, I last, Pred p )
|
||||
/// \brief Returns true if all elements in [first, last) satisfy the predicate
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate
|
||||
///
|
||||
template<typename I, typename Pred>
|
||||
bool all_if ( I first, I last, Pred p )
|
||||
{
|
||||
while (first != last) {
|
||||
if ( !p(*first++))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn all_if ( Range range, Pred p )
|
||||
/// \brief Returns true if all elements in the range satisfy the predicate
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param p A predicate to test the elements
|
||||
///
|
||||
template<typename Range, typename Pred>
|
||||
bool all_if ( Range range, Pred p )
|
||||
{
|
||||
return all_if ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
/// \fn none ( I first, I last, V val )
|
||||
/// \brief Returns true if none of the elements in [first, last) are equal to 'val'
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename I, typename V>
|
||||
bool none ( I first, I last, const V &val )
|
||||
{
|
||||
while (first != last) {
|
||||
if ( *first++ == val )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \fn none ( Range range, V val )
|
||||
/// \brief Returns true if none of the elements in the range are equal to 'val'
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool none ( Range range, const V & val )
|
||||
{
|
||||
return none ( boost::begin ( range ), boost::end ( range ), val );
|
||||
}
|
||||
|
||||
|
||||
/// \fn none_if ( I first, I last, Pred p )
|
||||
/// \brief Returns true if none of the elements in [first, last) satisfy the predicate
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate
|
||||
///
|
||||
template<typename I, typename Pred>
|
||||
bool none_if ( I first, I last, Pred p )
|
||||
{
|
||||
while (first != last) {
|
||||
if ( p(*first++))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn none_if ( Range range, Pred p )
|
||||
/// \brief Returns true if none of the elements in the range satisfy the predicate
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param p A predicate to test the elements
|
||||
///
|
||||
template<typename Range, typename Pred>
|
||||
bool none_if ( Range range, Pred p )
|
||||
{
|
||||
return none_if ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
/// \fn any ( I first, I last, V val )
|
||||
/// \brief Returns true if any of the elements in [first, last) are equal to 'val'
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename I, typename V>
|
||||
bool any ( I first, I last, const V &val )
|
||||
{
|
||||
while (first != last) {
|
||||
if ( *first++ == val )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \fn any ( Range range, V val )
|
||||
/// \brief Returns true if any of the elements in the range are equal to 'val'
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool any ( Range range, const V &val )
|
||||
{
|
||||
return any ( boost::begin ( range ), boost::end ( range ), val );
|
||||
}
|
||||
|
||||
/// \fn any_if ( I first, I last, Pred p )
|
||||
/// \brief Returns true if any of the elements in [first, last) satisfy the predicate
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate
|
||||
///
|
||||
template<typename I, typename Pred>
|
||||
bool any_if ( I first, I last, Pred p)
|
||||
{
|
||||
while (first != last) {
|
||||
if ( p(*first++))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \fn any_if ( Range range, Pred p )
|
||||
/// \brief Returns true if any elements in the range satisfy the predicate
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param p A predicate to test the elements
|
||||
///
|
||||
template<typename Range, typename Pred>
|
||||
bool any_if ( Range range, Pred p )
|
||||
{
|
||||
return any_if ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
/// \fn exists_and_only ( I first, I last, V val )
|
||||
/// \brief Returns true if the value 'val' exists only once in [first, last).
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename I, typename V>
|
||||
bool exists_and_only ( I first, I last, const V &val )
|
||||
{
|
||||
I i = std::find (first, last, val);
|
||||
if (i == last) return false;
|
||||
if ( std::find (++i, last, val) != last) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn exists_and_only ( Range range, V val )
|
||||
/// \brief Returns true if the value 'val' exists only once in the range.
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool exists_and_only ( Range range, const V &val )
|
||||
{
|
||||
return exists_and_only ( boost::begin ( range ), boost::end ( range ), val );
|
||||
}
|
||||
|
||||
/// \fn exists_and_only_if ( I first, I last, Pred p )
|
||||
/// \brief Returns true if the predicate 'p' is true for exactly one item in [first, last).
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate to test the elements
|
||||
///
|
||||
template<typename I, typename Pred>
|
||||
bool exists_and_only_if ( I first, I last, Pred p )
|
||||
{
|
||||
I i = find_if (first, last, p);
|
||||
if (i == last) return false;
|
||||
if (find_if(++i, last, p) != last) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn exists_and_only_if ( Range range, Pred p )
|
||||
/// \brief Returns true if the predicate 'p' is true for exactly one item in the range.
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param p A predicate to test the elements
|
||||
///
|
||||
template<typename Range, typename Pred>
|
||||
bool exists_and_only_if ( Range range, Pred p )
|
||||
{
|
||||
return exists_and_only_if ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_ALL_HPP
|
244
include/boost/algorithm/copy.hpp
Normal file
244
include/boost/algorithm/copy.hpp
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2008.
|
||||
|
||||
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)
|
||||
|
||||
Revision history:
|
||||
05 May 2008 mtc First version - as part of BoostCon 2008
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_SEQUENCE_COPY_HPP
|
||||
#define BOOST_ALGORITHM_SEQUENCE_COPY_HPP
|
||||
|
||||
#include <boost/range.hpp> // For boost::begin and boost::end
|
||||
|
||||
/// \file copy.hpp
|
||||
/// \brief Boost implementation of various STL-type copying algorithms
|
||||
/// that were left out of the standard.
|
||||
/// \author Marshall Clow
|
||||
|
||||
namespace boost { namespace algorithm { namespace sequence {
|
||||
|
||||
/// \fn copy_if ( I first, I last, O res, Pred p )
|
||||
/// \brief Copies all the elements from [first, last) that satisfy the predicate into 'res'
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param res An output iterator to copy into
|
||||
/// \param p A predicate to determine which items to copy
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
/// \note Based on a suggested implementation by Bjorne Stoustrop.
|
||||
///
|
||||
template<typename I, typename O, typename Pred>
|
||||
O copy_if ( I first, I last, O res, Pred p)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
if (p(*first))
|
||||
*res++ = *first;
|
||||
++first;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// \fn copy_if ( Range range, O res, Pred p )
|
||||
/// \brief Copy all the elements from the range that satisfy the predicate into 'res'
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param res An output iterator to copy into
|
||||
/// \param p A predicate to determine which items to copy
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
template<typename Range, typename O, typename Pred>
|
||||
O copy_if ( Range range, O res, Pred p )
|
||||
{
|
||||
return copy_if ( boost::begin ( range ), boost::end ( range ), res, p );
|
||||
}
|
||||
|
||||
|
||||
/// \fn copy_backward_if ( I first, I last, O res, Pred p )
|
||||
/// \brief Copies all the elements from (last, first] that satisfy the predicate into 'res'
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param res An output iterator to copy into
|
||||
/// \param p A predicate to determine which items to copy
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
/// \note Based on a suggested implementation by Bjorne Stoustrop.
|
||||
///
|
||||
template<typename I, typename O, typename Pred>
|
||||
O copy_backward_if ( I first, I last, O res, Pred p)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
if (p(*--last))
|
||||
*res++ = *last;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// \fn copy_backward_if ( Range range, O res, Pred p )
|
||||
/// \brief Copy all the elements from the range that satisfy the predicate into 'res'
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param res An output iterator to copy into
|
||||
/// \param p A predicate to determine which items to copy
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
template<typename Range, typename O, typename Pred>
|
||||
O copy_backward_if ( Range range, O res, Pred p )
|
||||
{
|
||||
return copy_backward_if ( boost::begin ( range ), boost::end ( range ), res, p );
|
||||
}
|
||||
|
||||
|
||||
/* -- I'd like a value-based version, too; but I don't know of a good name....
|
||||
template<typename I,typename O>
|
||||
O copy_equal ( I first, I last, O res, I::value_type val )
|
||||
{
|
||||
while (first != last) {
|
||||
if (*first == val)
|
||||
*res++ = *first;
|
||||
++first;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/// \fn copy_while ( I first, I last, O res, Pred p )
|
||||
/// \brief Copies all the elements from [first, last) up to a point into 'res'.\n
|
||||
/// Will continue until the input range is exhausted, or the predicate 'p' fails.
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param res An output iterator to copy into
|
||||
/// \param p A predicate to determine when to stop copying
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
template<typename I, typename O, typename Pred>
|
||||
O copy_while ( I first, I last, O res, Pred p )
|
||||
{
|
||||
for (; first != last && p(*first); ++first)
|
||||
*res++ = *first;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// \fn copy_while ( Range range, O res, Pred p )
|
||||
/// \brief Copies all the elements from the range up to a point into 'res'.\n
|
||||
/// Will continue until the input range is exhausted, or the predicate 'p' fails.
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param res An output iterator to copy into
|
||||
/// \param p A predicate to determine when to stop copying
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
template<typename Range, typename O, typename Pred>
|
||||
O copy_while ( Range range, O res, Pred p )
|
||||
{
|
||||
return copy_while ( boost::begin ( range ), boost::end ( range ), res, p );
|
||||
}
|
||||
|
||||
|
||||
/// \fn copy_backward_while ( I first, I last, O res, Pred p )
|
||||
/// \brief Copies all the elements from (last, first] up to a point into 'res'.\n
|
||||
/// Will continue until the input range is exhausted, or the predicate 'p' fails.
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param res An output iterator to copy into
|
||||
/// \param p A predicate to determine when to stop copying
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
template<typename I, typename O, typename Pred>
|
||||
O copy_backward_while ( I first, I last, O res, Pred p )
|
||||
{
|
||||
while ( first != last && p ( *--last ))
|
||||
*res++ = *last;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// \fn copy_backward_while ( Range range, O res, Pred p )
|
||||
/// \brief Copies all the elements from the range up to a point into 'res'.\n
|
||||
/// Will continue until the input range is exhausted, or the predicate 'p' fails.
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param res An output iterator to copy into
|
||||
/// \param p A predicate to determine when to stop copying
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
template<typename Range, typename O, typename Pred>
|
||||
O copy_while_backward ( Range range, O res, Pred p )
|
||||
{
|
||||
return copy_backward_while ( boost::begin ( range ), boost::end ( range ), res, p );
|
||||
}
|
||||
|
||||
|
||||
// According to Werner Salomon, the challenge for copy_n is that the algorithm should work correctly
|
||||
// with an std::istream_iterator. Therefor the input iterator have to increment only N-1 times.
|
||||
// Marshall sez: Is that really true?
|
||||
// Long discussion starting
|
||||
// here <http://www.tech-archive.net/Archive/VC/microsoft.public.vc.stl/2004-05/0112.html>
|
||||
// Marshall sez: I'm going to increment N times.
|
||||
//
|
||||
// Marshall sez: What's the advantage of templatizing on count, rather than using std::size_t?
|
||||
//
|
||||
// No range-based version here
|
||||
|
||||
/// \fn copy_n ( I first, Size count, O res )
|
||||
/// \brief Copies n elements starting at 'first' into 'res'.
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param count The number of elements to copy
|
||||
/// \param res An output iterator to copy into
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
// template <typename I, typename Size, typename O>
|
||||
// O copy_n ( I first, Size count, O res )
|
||||
template <typename I, typename O>
|
||||
O copy_n ( I first, typename iterator_traits<I>::difference_type count, O res )
|
||||
{
|
||||
while ( count-- > 0 )
|
||||
*res++ = *first++;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Range-based versions of copy and copy_backwards.
|
||||
|
||||
/// \fn copy ( Range range, O res )
|
||||
/// \brief Copies elements from the range 'range' into 'res'.
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param res An output iterator to copy into
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
/// \note A range-based version of std::copy
|
||||
///
|
||||
template<typename Range, typename O>
|
||||
O copy ( Range range, O res )
|
||||
{
|
||||
return std::copy ( boost::begin ( range ), boost::end ( range ), res );
|
||||
}
|
||||
|
||||
|
||||
/// \fn copy_backward ( Range range, O res )
|
||||
/// \brief Copies elements from the range 'range' into 'res'.
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param res An output iterator to copy into
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
/// \note A range-based version of std::copy_backwards
|
||||
///
|
||||
template<typename Range, typename O>
|
||||
O copy_backward ( Range range, O res )
|
||||
{
|
||||
return std::copy_backward ( boost::begin ( range ), boost::end ( range ), res );
|
||||
}
|
||||
|
||||
}}} // namespace boost & algorithm & sequence
|
||||
|
||||
#endif // BOOST_ALGORITHM_SEQUENCE_COPY_HPP
|
47
include/boost/algorithm/for_each_if.hpp
Normal file
47
include/boost/algorithm/for_each_if.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2008.
|
||||
|
||||
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)
|
||||
|
||||
Revision history:
|
||||
06 May 2008 mtc First version - as part of BoostCon 2008
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_FOR_EACH_IF_HPP
|
||||
#define BOOST_ALGORITHM_FOR_EACH_IF_HPP
|
||||
|
||||
#include <boost/range.hpp> // For boost::begin and boost::end
|
||||
|
||||
/// \file for_each_if.hpp
|
||||
/// \brief Boost implementation for_each_if, which was left out of the standard.
|
||||
/// \author Marshall Clow
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn for_each_if ( InputIterator first, InputIterator last, Pred p, Func f )
|
||||
/// \brief Applies the function_object 'f' to each element in [first, last) that satisfies
|
||||
/// the predicate 'p'.
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate to determine which items to copy
|
||||
/// \param f A function object that takes a single argument
|
||||
/// \return the function object 'f'
|
||||
///
|
||||
///
|
||||
template<typename InputIterator, typename Pred, typename Func>
|
||||
UnaryFunction for_each_if ( InputIterator first, InputIterator last, Pred p, Func f )
|
||||
{
|
||||
while ( first != last )
|
||||
{
|
||||
if (p(*first))
|
||||
f(*first);
|
||||
++first;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
}} // namespace boost & algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_FOR_EACH_IF_HPP
|
54
include/boost/algorithm/select.hpp
Normal file
54
include/boost/algorithm/select.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2008.
|
||||
|
||||
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)
|
||||
|
||||
Implemented by SGI in their STL implementation
|
||||
This implemnetation is based on interprocess::detail::select1st by Ion Gaztanaga.
|
||||
|
||||
Revision history:
|
||||
06 May 2008 mtc First version - as part of BoostCon 2008
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_SELECT_HPP
|
||||
#define BOOST_ALGORITHM_SELECT_HPP
|
||||
|
||||
|
||||
/// \file select.hpp
|
||||
/// \brief Boost implementation select1st and select2nd.
|
||||
/// \author Marshall Clow
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn select1st
|
||||
/// \brief Unary function that returns the first element of a std::pair
|
||||
///
|
||||
/// \param p The pair.
|
||||
/// \return p.first
|
||||
///
|
||||
///
|
||||
template <class Pair>
|
||||
struct select1st : public std::unary_function<Pair, typename Pair::first_type>
|
||||
{
|
||||
const typename Pair::first_type& operator()(const Pair& p) const { return p.first; }
|
||||
typename Pair::first_type& operator()( Pair& p) const { return p.first; }
|
||||
};
|
||||
|
||||
/// \fn select2nd
|
||||
/// \brief Unary function that returns the first element of a std::pair
|
||||
///
|
||||
/// \param p The pair.
|
||||
/// \return p.first
|
||||
///
|
||||
///
|
||||
template <class Pair>
|
||||
struct select2nd : public std::unary_function<Pair, typename Pair::second_type>
|
||||
{
|
||||
const typename Pair::second_type& operator()(const Pair& p) const { return p.second; }
|
||||
typename Pair::second_type& operator()( Pair& p) const { return p.second; }
|
||||
};
|
||||
|
||||
}} // namespace boost & algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_SELECT_HPP
|
Reference in New Issue
Block a user