Ticket #7748: range.diff
File range.diff, 6.4 KB (added by , 10 years ago) |
---|
-
boost/range/adaptor/transformed.hpp
13 13 14 14 #include <boost/range/adaptor/argument_fwd.hpp> 15 15 #include <boost/range/iterator_range.hpp> 16 #include <boost/range/reference.hpp> 16 17 #include <boost/iterator/transform_iterator.hpp> 17 18 #include <boost/utility/result_of.hpp> 18 19 … … 48 49 { } 49 50 }; 50 51 52 template< class R, class T, class U > 53 struct ret_wrapper 54 { 55 T val; 56 explicit ret_wrapper(T v) : val(v) {} 57 58 typedef R result_type; 59 60 R operator()(U u) const 61 { return val(u); } 62 }; 63 51 64 template< class T > 52 65 struct transform_holder : holder<T> 53 66 { … … 55 68 { } 56 69 }; 57 70 71 template< class R, class T > 72 struct ret_transform_holder : transform_holder<T> 73 { 74 ret_transform_holder( T r ) : transform_holder<T>(r) 75 { } 76 }; 77 78 79 template< class InputRng, class R, class UnaryFunction > 80 inline transformed_range<ret_wrapper<R,UnaryFunction, 81 BOOST_DEDUCED_TYPENAME range_reference<InputRng>::type>, InputRng> 82 operator|( InputRng& r, 83 const ret_transform_holder<R, UnaryFunction>& f ) 84 { 85 typedef BOOST_DEDUCED_TYPENAME range_reference<InputRng>::type InRef; 86 return transformed_range<ret_wrapper<R, UnaryFunction, InRef>, 87 InputRng>( ret_wrapper<R, UnaryFunction, InRef>(f.val), r ); 88 } 89 90 template< class InputRng, class R, class UnaryFunction > 91 inline transformed_range<ret_wrapper<R,UnaryFunction, 92 BOOST_DEDUCED_TYPENAME range_reference<const InputRng>::type>, const InputRng> 93 operator|( const InputRng& r, 94 const ret_transform_holder<R, UnaryFunction>& f ) 95 { 96 typedef BOOST_DEDUCED_TYPENAME range_reference<const InputRng>::type InRef; 97 return transformed_range<ret_wrapper<R, UnaryFunction, InRef>, 98 const InputRng>( ret_wrapper<R, UnaryFunction, InRef>(f.val), r ); 99 } 100 58 101 template< class InputRng, class UnaryFunction > 59 102 inline transformed_range<UnaryFunction,InputRng> 60 103 operator|( InputRng& r, … … 77 120 78 121 namespace adaptors 79 122 { 80 namespace 123 template< class R, class T > 124 range_detail::ret_transform_holder<R,T> transformed( T t ) 81 125 { 82 const range_detail::forwarder<range_detail::transform_holder> 83 transformed = 84 range_detail::forwarder<range_detail::transform_holder>(); 126 return range_detail::ret_transform_holder<R,T>(t); 85 127 } 128 template< class T > 129 range_detail::transform_holder<T> transformed( T t ) 130 { 131 return range_detail::transform_holder<T>(t); 132 } 86 133 134 template< class R, class InputRng, class UnaryFunction > 135 inline transformed_range<range_detail::ret_wrapper<R, UnaryFunction, 136 BOOST_DEDUCED_TYPENAME range_reference<InputRng>::type>,InputRng> 137 transform(InputRng& r, UnaryFunction fn) 138 { 139 typedef BOOST_DEDUCED_TYPENAME range_reference<InputRng>::type InRef; 140 return transformed_range<range_detail::ret_wrapper<R, UnaryFunction, InRef>, 141 InputRng>(range_detail::ret_wrapper<R, UnaryFunction, InRef>(fn), r ); 142 } 143 template< class R, class InputRng, class UnaryFunction > 144 inline transformed_range<range_detail::ret_wrapper<R, UnaryFunction, 145 BOOST_DEDUCED_TYPENAME range_reference<const InputRng>::type>, const InputRng> 146 transform(const InputRng& r, UnaryFunction fn) 147 { 148 typedef BOOST_DEDUCED_TYPENAME range_reference<const InputRng>::type InRef; 149 return transformed_range<range_detail::ret_wrapper<R, UnaryFunction, InRef>, 150 const InputRng>(range_detail::ret_wrapper<R, UnaryFunction, InRef>(fn), r ); 151 } 152 87 153 template<class UnaryFunction, class InputRange> 88 154 inline transformed_range<UnaryFunction, InputRange> 89 155 transform(InputRange& rng, UnaryFunction fn) -
libs/range/test/adaptor_test/transformed.cpp
92 92 transformed_test_impl< std::set< int > >(); 93 93 transformed_test_impl< std::multiset< int > >(); 94 94 } 95 96 //Unmodifiable struct which doesn't follow result_of. 97 struct hands_off 98 { 99 int operator()(double d) const 100 { return static_cast<int>(d); } 101 }; 102 103 //Previous tests verify that transform/transformed which followed 104 // result_type worked. This checks only cases which don't (and thus 105 // require an explicit result) (assuming no decltype support) 106 void transformed_result_test() 107 { 108 using namespace boost::assign; 109 110 hands_off fn; 111 std::vector< double > c; 112 c += 1,2,3,4,5,6,7,8,9; 113 std::vector< int > result1, result2, result3, result4; 114 boost::push_back(result1, c | adaptors::transformed<int>(fn)); 115 boost::push_back(result2, adaptors::transform<int>(c, fn)); 116 117 BOOST_CHECK_EQUAL_COLLECTIONS( result1.begin(), result1.end(), 118 result2.begin(), result2.end() ); 119 120 const std::vector< double >& c2 = c; 121 boost::push_back(result3, c2 | adaptors::transformed<int>(fn)); 122 boost::push_back(result4, adaptors::transform<int>(c2, fn)); 123 124 BOOST_CHECK_EQUAL_COLLECTIONS( result3.begin(), result3.end(), 125 result4.begin(), result4.end() ); 126 127 BOOST_CHECK_EQUAL_COLLECTIONS( result1.begin(), result1.end(), 128 result3.begin(), result3.end() ); 129 } 95 130 } 96 131 } 97 132 … … 102 137 = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed" ); 103 138 104 139 test->add( BOOST_TEST_CASE( &boost::transformed_test ) ); 140 test->add( BOOST_TEST_CASE( &boost::transformed_result_test ) ); 105 141 106 142 return test; 107 143 }