]>
Commit | Line | Data |
---|---|---|
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 |