1 // Boost.Range library 2 // 3 // Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and 4 // distribution is subject to the Boost Software License, Version 5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // For more information, see http://www.boost.org/libs/range/ 9 // 10 11 #ifndef BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP 12 #define BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP 13 14 #include <boost/range/adaptor/argument_fwd.hpp> 15 #include <boost/range/detail/default_constructible_unary_fn.hpp> 16 #include <boost/range/iterator_range.hpp> 17 #include <boost/range/concepts.hpp> 18 #include <boost/iterator/transform_iterator.hpp> 19 #include <boost/utility/result_of.hpp> 20 21 namespace boost 22 { 23 namespace range_detail 24 { 25 // A type generator to produce the transform_iterator type conditionally 26 // including a wrapped predicate as appropriate. 27 template<typename P, typename It> 28 struct transform_iterator_gen 29 { 30 typedef transform_iterator< 31 typename default_constructible_unary_fn_gen< 32 P, 33 typename transform_iterator<P, It>::reference 34 >::type, 35 It 36 > type; 37 }; 38 39 template< class F, class R > 40 struct transformed_range : 41 public boost::iterator_range< 42 typename transform_iterator_gen< 43 F, typename range_iterator<R>::type>::type> 44 { 45 private: 46 typedef typename transform_iterator_gen< 47 F, typename range_iterator<R>::type>::type transform_iter_t; 48 49 typedef boost::iterator_range<transform_iter_t> base; 50 51 public: 52 typedef typename default_constructible_unary_fn_gen< 53 F, 54 typename transform_iterator< 55 F, 56 typename range_iterator<R>::type 57 >::reference 58 >::type transform_fn_type; 59 60 typedef R source_range_type; 61 transformed_rangeboost::range_detail::transformed_range62 transformed_range(transform_fn_type f, R& r) 63 : base(transform_iter_t(boost::begin(r), f), 64 transform_iter_t(boost::end(r), f)) 65 { 66 } 67 }; 68 69 template< class T > 70 struct transform_holder : holder<T> 71 { transform_holderboost::range_detail::transform_holder72 transform_holder( T r ) : holder<T>(r) 73 { 74 } 75 }; 76 77 template< class SinglePassRange, class UnaryFunction > 78 inline transformed_range<UnaryFunction,SinglePassRange> operator |(SinglePassRange & r,const transform_holder<UnaryFunction> & f)79 operator|( SinglePassRange& r, 80 const transform_holder<UnaryFunction>& f ) 81 { 82 BOOST_RANGE_CONCEPT_ASSERT(( 83 SinglePassRangeConcept<SinglePassRange>)); 84 85 return transformed_range<UnaryFunction,SinglePassRange>( f.val, r ); 86 } 87 88 template< class SinglePassRange, class UnaryFunction > 89 inline transformed_range<UnaryFunction, const SinglePassRange> operator |(const SinglePassRange & r,const transform_holder<UnaryFunction> & f)90 operator|( const SinglePassRange& r, 91 const transform_holder<UnaryFunction>& f ) 92 { 93 BOOST_RANGE_CONCEPT_ASSERT(( 94 SinglePassRangeConcept<const SinglePassRange>)); 95 96 return transformed_range<UnaryFunction, const SinglePassRange>( 97 f.val, r); 98 } 99 100 } // 'range_detail' 101 102 using range_detail::transformed_range; 103 104 namespace adaptors 105 { 106 namespace 107 { 108 const range_detail::forwarder<range_detail::transform_holder> 109 transformed = 110 range_detail::forwarder<range_detail::transform_holder>(); 111 } 112 113 template<class UnaryFunction, class SinglePassRange> 114 inline transformed_range<UnaryFunction, SinglePassRange> transform(SinglePassRange & rng,UnaryFunction fn)115 transform(SinglePassRange& rng, UnaryFunction fn) 116 { 117 BOOST_RANGE_CONCEPT_ASSERT(( 118 SinglePassRangeConcept<SinglePassRange>)); 119 120 return transformed_range<UnaryFunction, SinglePassRange>(fn, rng); 121 } 122 123 template<class UnaryFunction, class SinglePassRange> 124 inline transformed_range<UnaryFunction, const SinglePassRange> transform(const SinglePassRange & rng,UnaryFunction fn)125 transform(const SinglePassRange& rng, UnaryFunction fn) 126 { 127 BOOST_RANGE_CONCEPT_ASSERT(( 128 SinglePassRangeConcept<const SinglePassRange>)); 129 130 return transformed_range<UnaryFunction, const SinglePassRange>( 131 fn, rng); 132 } 133 } // 'adaptors' 134 135 } 136 137 #endif 138