diff --git a/apply/test/apply_test.cpp b/apply/test/apply_test.cpp index 01bca88..d3cef71 100644 --- a/apply/test/apply_test.cpp +++ b/apply/test/apply_test.cpp @@ -1,7 +1,3 @@ -/*** show that you have a forward iterator -* more types -* more containers*/ - /* Copyright (C) 2008 Jesse Williamson diff --git a/include/boost/algorithm/transform_if.hpp b/include/boost/algorithm/transform_if.hpp new file mode 100644 index 0000000..be67881 --- /dev/null +++ b/include/boost/algorithm/transform_if.hpp @@ -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 + +/// \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 + 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 + 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 + 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 + 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 + + diff --git a/transform_if/test/transform_if_test.cpp b/transform_if/test/transform_if_test.cpp new file mode 100644 index 0000000..4f9ab4f --- /dev/null +++ b/transform_if/test/transform_if_test.cpp @@ -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 +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +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 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 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 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 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; +}