• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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