diff --git a/include/boost/iterator/transform_iterator.hpp b/include/boost/iterator/transform_iterator.hpp index 34e2fa6..77fa9bc 100644 --- a/include/boost/iterator/transform_iterator.hpp +++ b/include/boost/iterator/transform_iterator.hpp @@ -9,10 +9,16 @@ #ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP #define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP +#include #include +#include #include #include +#include +#include +#include #include +#include #include #include #include @@ -106,10 +112,43 @@ namespace boost UnaryFunction m_f; }; - template - transform_iterator make_transform_iterator(Iterator it, UnaryFunction fun) + template + transform_iterator make_transform_iterator(Iterator it, UnaryFunctionObject fun) { - return transform_iterator(it, fun); + return transform_iterator(it, fun); + } + + namespace detail { + + template + struct is_unary : + mpl::bool_<(function_traits::arity == 1)> + {}; + + template + struct is_unary_function : + mpl::apply_if< is_function + , is_unary + , mpl::bool_ + >::type + {}; + + } + + // + // ToDo: Think twice wether enable_if is better than an + // static assert. Currently we get convoluted error messages + // from the above overload for any pointer that is not a + // pointer to a unary function. + // + template + typename detail::enable_if< + detail::is_unary_function + , transform_iterator< function, Iterator> + >::type + make_transform_iterator(Iterator it, UnaryFunction* fun) + { + return make_transform_iterator(it, function(fun)); } } // namespace boost diff --git a/test/transform_iterator_test.cpp b/test/transform_iterator_test.cpp index 5d5f388..8d6a55e 100644 --- a/test/transform_iterator_test.cpp +++ b/test/transform_iterator_test.cpp @@ -96,6 +96,10 @@ struct value_select_first } }; +int mult_2(int arg) +{ + return arg*2; +} int main() @@ -128,6 +132,30 @@ main() boost::random_access_readable_iterator_test(i, N, x); } + // Test transform_iterator with function pointers + { + int x[N], y[N]; + for (int k = 0; k < N; ++k) + x[k] = k; + std::copy(x, x + N, y); + + for (int k2 = 0; k2 < N; ++k2) + x[k2] = x[k2] * 2; + + boost::input_iterator_test(boost::make_transform_iterator(y, mult_2) + , x[0] + , x[1]); + + boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_2) + , x[0] + , x[1]); + + boost::random_access_readable_iterator_test(boost::make_transform_iterator(y, mult_2) + , N + , x); + + } + // Test transform_iterator as projection iterator { typedef std::pair pair_t;