diff --git a/include/boost/range/adaptor/transformed.hpp b/include/boost/range/adaptor/transformed.hpp index 96d2dab..98c655e 100755 --- a/include/boost/range/adaptor/transformed.hpp +++ b/include/boost/range/adaptor/transformed.hpp @@ -41,20 +41,32 @@ namespace boost typedef F transform_fn_type; typedef R source_range_type; +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES transformed_range( F f, R& r ) : base( boost::make_transform_iterator( boost::begin(r), f ), boost::make_transform_iterator( boost::end(r), f ) ) - { } + { + } +#else + transformed_range(F&& f, R&& r) + : base(typename base::iterator(boost::begin(r), std::forward(f), + typename base::iterator(boost::end(r), std::forward(f)))) + { + } + +#endif }; template< class T > struct transform_holder : holder { transform_holder( T r ) : holder(r) - { } + { + } }; +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES template< class InputRng, class UnaryFunction > inline transformed_range operator|( InputRng& r, @@ -70,6 +82,16 @@ namespace boost { return transformed_range( f.val, r ); } +#else + template + inline transformed_range + operator|(InputRng&& r, + transform_holder&& f) + { + return transformed_range( + f.val, std::forward(r)); + } +#endif } // 'range_detail' @@ -84,6 +106,7 @@ namespace boost range_detail::forwarder(); } +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES template inline transformed_range transform(InputRange& rng, UnaryFunction fn) @@ -97,6 +120,16 @@ namespace boost { return transformed_range(fn, rng); } +#else + template + inline transformed_range + transform(InputRange&& rng, UnaryFunction&& fn) + { + return transformed_range( + std::forward(fn), std::forward(rng)); + } + +#endif } // 'adaptors' } diff --git a/test/adaptor_test/transformed.cpp b/test/adaptor_test/transformed.cpp index 6b6121e..adadafc 100644 --- a/test/adaptor_test/transformed.cpp +++ b/test/adaptor_test/transformed.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -92,6 +93,29 @@ namespace boost transformed_test_impl< std::set< int > >(); transformed_test_impl< std::multiset< int > >(); } + + struct foo_bind + { + int foo() const { return 7; } + }; + + void transformed_bind() + { + using namespace boost::adaptors; + + std::vector input(5); + std::vector output; + boost::range::push_back( + output, + input | transformed(boost::bind(&foo_bind::foo, _1))); + + BOOST_CHECK_EQUAL(output.size(), input.size()); + + std::vector reference_output(5, 7); + BOOST_CHECK_EQUAL_COLLECTIONS( + output.begin(), output.end(), + reference_output.begin(), reference_output.end()); + } } } @@ -101,7 +125,8 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed" ); - test->add( BOOST_TEST_CASE( &boost::transformed_test ) ); + test->add(BOOST_TEST_CASE(&boost::transformed_test)); + test->add(BOOST_TEST_CASE(&boost::transformed_bind)); return test; }