forked from boostorg/algorithm
Initial check-in of transform_if()
[SVN r46785]
This commit is contained in:
@ -1,7 +1,3 @@
|
||||
/*** show that you have a forward iterator
|
||||
* more types
|
||||
* more containers*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2008 Jesse Williamson
|
||||
|
||||
|
95
include/boost/algorithm/transform_if.hpp
Normal file
95
include/boost/algorithm/transform_if.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright (C) 2008 Jesse Williamson
|
||||
|
||||
|
||||
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)
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_SEQUENCE_TRANSFORM_IF_HPP
|
||||
#define BOOST_ALGORITHM_SEQUENCE_TRANSFORM_IF_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
/// \file transform_if.hpp
|
||||
/// \brief Boost implementation of transform_if() algorithm.
|
||||
/// \author Jesse Williamson
|
||||
|
||||
namespace boost { namespace algorithm { namespace sequence {
|
||||
|
||||
/// \fn transform_if ( InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op, UnaryPredicate pred )
|
||||
/// \brief Applies op to all elements in [first, last] for which pred is true, storing each returned value in the range
|
||||
/// beginning at result.
|
||||
///
|
||||
/// \param first The start of the input sequence.
|
||||
/// \param last One past the end of the input sequence.
|
||||
/// \param result The start of the output sequence.
|
||||
/// \param op Unary operation to apply when pred is true.
|
||||
/// \param pred Unary condition predicate.
|
||||
///
|
||||
template <class InputIterator, class OutputIterator, class UnaryFunction, class UnaryPredicate>
|
||||
OutputIterator transform_if(InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op, UnaryPredicate pred)
|
||||
{
|
||||
for( ; first != last; ++first, ++result )
|
||||
if( pred( *first ) )
|
||||
*result = op( *first );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// \fn transform_if ( ForwardReadableRange& R, OutputIterator result, UnaryFunction op, UnaryPredicate pred )
|
||||
/// \brief Applies op to all elements in [first, last] for which pred is true, storing each returned value in the range
|
||||
/// beginning at result.
|
||||
///
|
||||
/// \param R A forward readable Boost range input sequence.
|
||||
/// \param result The start of the output sequence.
|
||||
/// \param op Unary operation to apply when pred is true.
|
||||
/// \param pred Unary condition predicate.
|
||||
///
|
||||
template <class ForwardReadableRange, class OutputIterator, class UnaryFunction, class UnaryPredicate>
|
||||
OutputIterator transform_if(ForwardReadableRange& R, OutputIterator result, UnaryFunction op, UnaryPredicate pred)
|
||||
{
|
||||
return transform_if( boost::begin(R), boost::end(R), result, op, pred );
|
||||
}
|
||||
|
||||
/// \fn transform_if ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryFunction op, BinaryPredicate pred )
|
||||
/// \brief Applies op to all elements in [first, last] for which pred is true, storing each returned value in the range
|
||||
/// beginning at result.
|
||||
///
|
||||
/// \param first1 The start of the first input sequence.
|
||||
/// \param last1 One past the end of the first input sequence.
|
||||
/// \param first2 The start of the second input sequence.
|
||||
/// \param result The start of the output sequence.
|
||||
/// \param op Binary operation to apply when pred is true.
|
||||
/// \param pred Binary condition predicate.
|
||||
///
|
||||
template <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryFunction, class BinaryPredicate>
|
||||
OutputIterator transform_if(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryFunction op, BinaryPredicate pred)
|
||||
{
|
||||
for ( ; first1 != last1; ++first1, ++first2, ++result )
|
||||
if ( pred( *first1, *first2 ) )
|
||||
*result = op( *first1, *first2 );
|
||||
}
|
||||
|
||||
/// \fn transform_if ( ForwardReadableRange& R, InputIterator2 first2, OutputIterator result, BinaryFunction op, BinaryPredicate pred )
|
||||
/// \brief Applies op to all elements in [first, last] for which pred is true, storing each returned value in the range
|
||||
/// beginning at result.
|
||||
///
|
||||
/// \param R A forward-readable Boost range input sequence.
|
||||
/// \param first2 The start of the second input sequence.
|
||||
/// \param result The start of the output sequence.
|
||||
/// \param op Binary operation to apply when pred is true.
|
||||
/// \param pred Binary condition predicate.
|
||||
///
|
||||
template <class ForwardReadableRange, class InputIterator2, class OutputIterator, class BinaryFunction, class BinaryPredicate>
|
||||
OutputIterator transform_if(ForwardReadableRange& R, InputIterator2 first2, OutputIterator result, BinaryFunction op, BinaryPredicate pred)
|
||||
{
|
||||
return transform_if( boost::begin(R), boost::end(R), first2, result, op, pred );
|
||||
}
|
||||
|
||||
}}} // namespace boost::algorithm::sequence
|
||||
|
||||
#endif
|
||||
|
||||
|
143
transform_if/test/transform_if_test.cpp
Normal file
143
transform_if/test/transform_if_test.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (C) 2008 Jesse Williamson
|
||||
|
||||
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 <list>
|
||||
#include <vector>
|
||||
#include <numeric>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#include <boost/algorithm/iota.hpp>
|
||||
#include <boost/assign/std/vector.hpp>
|
||||
|
||||
#include <boost/algorithm/transform_if.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
using namespace boost::algorithm::sequence;
|
||||
|
||||
int make_double(const int& i)
|
||||
{
|
||||
return i*2;
|
||||
}
|
||||
|
||||
int mult(const int& i, const int& i2)
|
||||
{
|
||||
return i*i2;
|
||||
}
|
||||
|
||||
bool is_even(const int& i)
|
||||
{
|
||||
return 0 == i % 2;
|
||||
}
|
||||
|
||||
bool is_odd(const int& i)
|
||||
{
|
||||
return !is_even(i);
|
||||
}
|
||||
|
||||
bool both_even(const int& i, const int& i2)
|
||||
{
|
||||
return is_even(i) && is_even(i2);
|
||||
}
|
||||
|
||||
int test_main(int, char **)
|
||||
{
|
||||
// transform_if(), unary op:
|
||||
{
|
||||
// ...on a vector:
|
||||
vector<int> v(3), v2;
|
||||
|
||||
v += 1, 2, 3;
|
||||
|
||||
transform_if(v.begin(), v.end(), back_inserter(v2), make_double, is_even);
|
||||
|
||||
BOOST_CHECK(4 == accumulate(v2.begin(), v2.end(), 0));
|
||||
|
||||
v2.clear();
|
||||
|
||||
transform_if(v.begin(), v.end(), back_inserter(v2), make_double, is_odd);
|
||||
|
||||
BOOST_CHECK(4 != accumulate(v2.begin(), v2.end(), 0));
|
||||
BOOST_CHECK(8 == accumulate(v2.begin(), v2.end(), 0));
|
||||
|
||||
// ...on an array:
|
||||
int x[3], y[3];
|
||||
|
||||
x[0] = 2;
|
||||
x[1] = 3;
|
||||
x[2] = 2;
|
||||
|
||||
memset(&y, 0, sizeof(y));
|
||||
|
||||
transform_if(x, x + 3, y, make_double, is_even);
|
||||
|
||||
BOOST_CHECK(8 == accumulate(y, y + 3, 0));
|
||||
}
|
||||
|
||||
// transform_if() unary op with a range:
|
||||
{
|
||||
vector<int> v(3), v2;
|
||||
|
||||
v += 1, 2, 3;
|
||||
|
||||
transform_if(v, back_inserter(v2), make_double, is_even);
|
||||
|
||||
BOOST_CHECK(4 == accumulate(v2.begin(), v2.end(), 0));
|
||||
}
|
||||
|
||||
// transform_if() binary op:
|
||||
{
|
||||
// ...on a vector:
|
||||
vector<int> v(3), v2(3), v3;
|
||||
|
||||
v += 1, 2, 3;
|
||||
v2 += 1, 2, 3;
|
||||
|
||||
transform_if(v.begin(), v.end(), v2.begin(), back_inserter(v3), mult, both_even);
|
||||
|
||||
BOOST_CHECK(4 == accumulate(v3.begin(), v3.end(), 0));
|
||||
|
||||
// ...on an array:
|
||||
int x[3], y[3], z[3];
|
||||
|
||||
x[0] = 2;
|
||||
x[1] = 3;
|
||||
x[2] = 2;
|
||||
|
||||
y[0] = 1;
|
||||
y[1] = 3;
|
||||
y[2] = 4;
|
||||
|
||||
memset(&z, 0, sizeof(z));
|
||||
|
||||
transform_if(x, x + 3, y, z, mult, both_even);
|
||||
|
||||
BOOST_CHECK(8 == accumulate(z, z + 3, 0));
|
||||
}
|
||||
|
||||
// transform_if() binary with a range:
|
||||
{
|
||||
vector<int> v(3), v2(3), v3;
|
||||
|
||||
v += 1, 2, 3;
|
||||
v2 += 1, 2, 3;
|
||||
|
||||
transform_if(v, v2.begin(), back_inserter(v3), mult, both_even);
|
||||
|
||||
BOOST_CHECK(4 == accumulate(v3.begin(), v3.end(), 0));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user