Ticket #7748: range.diff

File range.diff, 6.4 KB (added by nathan.crookston+boost@…, 10 years ago)

patch for proposed syntax

  • boost/range/adaptor/transformed.hpp

     
    1313
    1414#include <boost/range/adaptor/argument_fwd.hpp>
    1515#include <boost/range/iterator_range.hpp>
     16#include <boost/range/reference.hpp>
    1617#include <boost/iterator/transform_iterator.hpp>
    1718#include <boost/utility/result_of.hpp>
    1819
     
    4849            { }
    4950        };
    5051
     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
    5164        template< class T >
    5265        struct transform_holder : holder<T>
    5366        {
     
    5568            { }
    5669        };
    5770
     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
    58101        template< class InputRng, class UnaryFunction >
    59102        inline transformed_range<UnaryFunction,InputRng>
    60103        operator|( InputRng& r,
     
    77120
    78121    namespace adaptors
    79122    {
    80         namespace
     123        template< class R, class T >
     124        range_detail::ret_transform_holder<R,T> transformed( T t )
    81125        {
    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);
    85127        }
     128        template< class T >
     129        range_detail::transform_holder<T> transformed( T t )
     130        {
     131            return range_detail::transform_holder<T>(t);
     132        }
    86133
     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
    87153        template<class UnaryFunction, class InputRange>
    88154        inline transformed_range<UnaryFunction, InputRange>
    89155        transform(InputRange& rng, UnaryFunction fn)
  • libs/range/test/adaptor_test/transformed.cpp

     
    9292            transformed_test_impl< std::set< int > >();
    9393            transformed_test_impl< std::multiset< int > >();
    9494        }
     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        }
    95130    }
    96131}
    97132
     
    102137        = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed" );
    103138
    104139    test->add( BOOST_TEST_CASE( &boost::transformed_test ) );
     140    test->add( BOOST_TEST_CASE( &boost::transformed_result_test ) );
    105141
    106142    return test;
    107143}