]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
62 | 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 | { | |
72 | transform_holder( T r ) : holder<T>(r) | |
73 | { | |
74 | } | |
75 | }; | |
76 | ||
77 | template< class SinglePassRange, class UnaryFunction > | |
78 | inline transformed_range<UnaryFunction,SinglePassRange> | |
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> | |
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> | |
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> | |
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 |