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_MAP_HPP |
12 | #define BOOST_RANGE_ADAPTOR_MAP_HPP |
13 | |
14 | #include <boost/range/adaptor/transformed.hpp> |
15 | #include <boost/range/iterator_range.hpp> |
16 | #include <boost/range/value_type.hpp> |
17 | #include <boost/range/reference.hpp> |
18 | #include <boost/range/concepts.hpp> |
19 | |
20 | namespace boost |
21 | { |
22 | namespace range_detail |
23 | { |
24 | struct map_keys_forwarder {}; |
25 | struct map_values_forwarder {}; |
26 | |
27 | template< class Map > |
28 | struct select_first |
29 | { |
30 | typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type; |
31 | typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::first_type& result_type; |
32 | |
33 | result_type operator()( argument_type r ) const |
34 | { |
35 | return r.first; |
36 | } |
37 | }; |
38 | |
39 | template< class Map > |
40 | struct select_second_mutable |
41 | { |
42 | typedef BOOST_DEDUCED_TYPENAME range_reference<Map>::type argument_type; |
43 | typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type::second_type& result_type; |
44 | |
45 | result_type operator()( argument_type r ) const |
46 | { |
47 | return r.second; |
48 | } |
49 | }; |
50 | |
51 | template< class Map > |
52 | struct select_second_const |
53 | { |
54 | typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type; |
55 | typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::second_type& result_type; |
56 | |
57 | result_type operator()( argument_type r ) const |
58 | { |
59 | return r.second; |
60 | } |
61 | }; |
62 | |
63 | template<class StdPairRng> |
64 | class select_first_range |
65 | : public transformed_range< |
66 | select_first<StdPairRng>, |
67 | const StdPairRng> |
68 | { |
69 | typedef transformed_range<select_first<StdPairRng>, const StdPairRng> base; |
70 | public: |
71 | typedef select_first<StdPairRng> transform_fn_type; |
72 | typedef const StdPairRng source_range_type; |
73 | |
74 | select_first_range(transform_fn_type fn, source_range_type& rng) |
75 | : base(fn, rng) |
76 | { |
77 | } |
78 | |
79 | select_first_range(const base& other) : base(other) {} |
80 | }; |
81 | |
82 | template<class StdPairRng> |
83 | class select_second_mutable_range |
84 | : public transformed_range< |
85 | select_second_mutable<StdPairRng>, |
86 | StdPairRng> |
87 | { |
88 | typedef transformed_range<select_second_mutable<StdPairRng>, StdPairRng> base; |
89 | public: |
90 | typedef select_second_mutable<StdPairRng> transform_fn_type; |
91 | typedef StdPairRng source_range_type; |
92 | |
93 | select_second_mutable_range(transform_fn_type fn, source_range_type& rng) |
94 | : base(fn, rng) |
95 | { |
96 | } |
97 | |
98 | select_second_mutable_range(const base& other) : base(other) {} |
99 | }; |
100 | |
101 | template<class StdPairRng> |
102 | class select_second_const_range |
103 | : public transformed_range< |
104 | select_second_const<StdPairRng>, |
105 | const StdPairRng> |
106 | { |
107 | typedef transformed_range<select_second_const<StdPairRng>, const StdPairRng> base; |
108 | public: |
109 | typedef select_second_const<StdPairRng> transform_fn_type; |
110 | typedef const StdPairRng source_range_type; |
111 | |
112 | select_second_const_range(transform_fn_type fn, source_range_type& rng) |
113 | : base(fn, rng) |
114 | { |
115 | } |
116 | |
117 | select_second_const_range(const base& other) : base(other) {} |
118 | }; |
119 | |
120 | template< class StdPairRng > |
121 | inline select_first_range<StdPairRng> |
122 | operator|( const StdPairRng& r, map_keys_forwarder ) |
123 | { |
124 | BOOST_RANGE_CONCEPT_ASSERT(( |
125 | SinglePassRangeConcept<const StdPairRng>)); |
126 | |
127 | return operator|( r, |
128 | boost::adaptors::transformed( select_first<StdPairRng>() ) ); |
129 | } |
130 | |
131 | template< class StdPairRng > |
132 | inline select_second_mutable_range<StdPairRng> |
133 | operator|( StdPairRng& r, map_values_forwarder ) |
134 | { |
135 | BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<StdPairRng>)); |
136 | |
137 | return operator|( r, |
138 | boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) ); |
139 | } |
140 | |
141 | template< class StdPairRng > |
142 | inline select_second_const_range<StdPairRng> |
143 | operator|( const StdPairRng& r, map_values_forwarder ) |
144 | { |
145 | BOOST_RANGE_CONCEPT_ASSERT(( |
146 | SinglePassRangeConcept<const StdPairRng>)); |
147 | |
148 | return operator|( r, |
149 | boost::adaptors::transformed( select_second_const<StdPairRng>() ) ); |
150 | } |
151 | |
152 | } // 'range_detail' |
153 | |
154 | using range_detail::select_first_range; |
155 | using range_detail::select_second_mutable_range; |
156 | using range_detail::select_second_const_range; |
157 | |
158 | namespace adaptors |
159 | { |
160 | namespace |
161 | { |
162 | const range_detail::map_keys_forwarder map_keys = |
163 | range_detail::map_keys_forwarder(); |
164 | |
165 | const range_detail::map_values_forwarder map_values = |
166 | range_detail::map_values_forwarder(); |
167 | } |
168 | |
169 | template<class StdPairRange> |
170 | inline select_first_range<StdPairRange> |
171 | keys(const StdPairRange& rng) |
172 | { |
173 | BOOST_RANGE_CONCEPT_ASSERT(( |
174 | SinglePassRangeConcept<const StdPairRange>)); |
175 | |
176 | return select_first_range<StdPairRange>( |
177 | range_detail::select_first<StdPairRange>(), rng ); |
178 | } |
179 | |
180 | template<class StdPairRange> |
181 | inline select_second_const_range<StdPairRange> |
182 | values(const StdPairRange& rng) |
183 | { |
184 | BOOST_RANGE_CONCEPT_ASSERT(( |
185 | SinglePassRangeConcept<const StdPairRange>)); |
186 | |
187 | return select_second_const_range<StdPairRange>( |
188 | range_detail::select_second_const<StdPairRange>(), rng ); |
189 | } |
190 | |
191 | template<class StdPairRange> |
192 | inline select_second_mutable_range<StdPairRange> |
193 | values(StdPairRange& rng) |
194 | { |
195 | BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<StdPairRange>)); |
196 | |
197 | return select_second_mutable_range<StdPairRange>( |
198 | range_detail::select_second_mutable<StdPairRange>(), rng ); |
199 | } |
200 | } // 'adaptors' |
201 | |
202 | } |
203 | |
204 | #endif |
205 | |