Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/range/combine.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Copyright Neil Groves 2010. Use, modification and | |
2 // distribution is subject to the Boost Software License, Version | |
3 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
4 // http://www.boost.org/LICENSE_1_0.txt) | |
5 // | |
6 // | |
7 // For more information, see http://www.boost.org/libs/range/ | |
8 // | |
9 #ifndef BOOST_RANGE_COMBINE_HPP | |
10 #define BOOST_RANGE_COMBINE_HPP | |
11 | |
12 #include <boost/iterator/zip_iterator.hpp> | |
13 #include <boost/tuple/tuple.hpp> | |
14 #include <boost/range/iterator.hpp> | |
15 #include <boost/range/iterator_range.hpp> | |
16 #include <boost/type_traits/is_void.hpp> | |
17 #include <boost/type_traits/is_same.hpp> | |
18 #include <boost/mpl/eval_if.hpp> | |
19 #include <boost/mpl/int.hpp> | |
20 #include <boost/mpl/plus.hpp> | |
21 #include <boost/mpl/arithmetic.hpp> | |
22 #include <boost/config.hpp> | |
23 | |
24 namespace boost | |
25 { | |
26 namespace range_detail | |
27 { | |
28 struct void_ { typedef void_ type; }; | |
29 } | |
30 | |
31 template<> struct range_iterator< ::boost::range_detail::void_ > | |
32 { | |
33 typedef ::boost::tuples::null_type type; | |
34 }; | |
35 | |
36 namespace range_detail | |
37 { | |
38 inline ::boost::tuples::null_type range_begin( ::boost::range_detail::void_& ) | |
39 { return ::boost::tuples::null_type(); } | |
40 | |
41 inline ::boost::tuples::null_type range_begin( const ::boost::range_detail::void_& ) | |
42 { return ::boost::tuples::null_type(); } | |
43 | |
44 inline ::boost::tuples::null_type range_end( ::boost::range_detail::void_& ) | |
45 { return ::boost::tuples::null_type(); } | |
46 | |
47 inline ::boost::tuples::null_type range_end( const ::boost::range_detail::void_& ) | |
48 { return ::boost::tuples::null_type(); } | |
49 | |
50 template< class T > | |
51 struct tuple_iter | |
52 { | |
53 typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c< | |
54 ::boost::is_same<T, ::boost::range_detail::void_ >::value, | |
55 ::boost::mpl::identity< ::boost::tuples::null_type >, | |
56 ::boost::range_iterator<T> | |
57 >::type type; | |
58 }; | |
59 | |
60 template< class Rng1, class Rng2 > | |
61 struct tuple_range | |
62 { | |
63 typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c< | |
64 ::boost::is_same<Rng1, ::boost::range_detail::void_ >::value, | |
65 ::boost::range_detail::void_, | |
66 ::boost::mpl::identity<Rng1> | |
67 >::type type; | |
68 }; | |
69 | |
70 template | |
71 < | |
72 class R1, | |
73 class R2, | |
74 class R3, | |
75 class R4, | |
76 class R5, | |
77 class R6 | |
78 > | |
79 struct generate_tuple | |
80 { | |
81 typedef ::boost::tuples::tuple< | |
82 BOOST_DEDUCED_TYPENAME tuple_iter<R1>::type, | |
83 BOOST_DEDUCED_TYPENAME tuple_iter<R2>::type, | |
84 BOOST_DEDUCED_TYPENAME tuple_iter<R3>::type, | |
85 BOOST_DEDUCED_TYPENAME tuple_iter<R4>::type, | |
86 BOOST_DEDUCED_TYPENAME tuple_iter<R5>::type, | |
87 BOOST_DEDUCED_TYPENAME tuple_iter<R6>::type | |
88 > type; | |
89 | |
90 static type begin( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 ) | |
91 { | |
92 return ::boost::tuples::make_tuple( ::boost::begin(r1), | |
93 ::boost::begin(r2), | |
94 ::boost::begin(r3), | |
95 ::boost::begin(r4), | |
96 ::boost::begin(r5), | |
97 ::boost::begin(r6) ); | |
98 } | |
99 | |
100 static type end( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 ) | |
101 { | |
102 return ::boost::tuples::make_tuple( ::boost::end(r1), | |
103 ::boost::end(r2), | |
104 ::boost::end(r3), | |
105 ::boost::end(r4), | |
106 ::boost::end(r5), | |
107 ::boost::end(r6) ); | |
108 } | |
109 }; | |
110 | |
111 template | |
112 < | |
113 class R1, | |
114 class R2 = void_, | |
115 class R3 = void_, | |
116 class R4 = void_, | |
117 class R5 = void_, | |
118 class R6 = void_ | |
119 > | |
120 struct zip_rng | |
121 : iterator_range< | |
122 zip_iterator< | |
123 BOOST_DEDUCED_TYPENAME generate_tuple<R1,R2,R3,R4,R5,R6>::type | |
124 > | |
125 > | |
126 { | |
127 private: | |
128 typedef generate_tuple<R1,R2,R3,R4,R5,R6> generator_t; | |
129 typedef BOOST_DEDUCED_TYPENAME generator_t::type tuple_t; | |
130 typedef zip_iterator<tuple_t> zip_iter_t; | |
131 typedef iterator_range<zip_iter_t> base_t; | |
132 | |
133 public: | |
134 zip_rng( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 ) | |
135 : base_t( zip_iter_t( generator_t::begin(r1,r2,r3,r4,r5,r6) ), | |
136 zip_iter_t( generator_t::end(r1,r2,r3,r4,r5,r6) ) ) | |
137 { | |
138 BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2)); | |
139 BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3)); | |
140 BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r4)); | |
141 BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r5)); | |
142 BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r6)); | |
143 } | |
144 | |
145 template< class Zip, class Rng > | |
146 zip_rng( Zip& z, Rng& r ) | |
147 : base_t( zip_iter_t( generator_t::begin( z, r ) ), | |
148 zip_iter_t( generator_t::end( z, r ) ) ) | |
149 { | |
150 | |
151 // @todo: tuple::begin( should be overloaded for this situation | |
152 } | |
153 | |
154 struct tuple_length : ::boost::tuples::length<tuple_t> | |
155 { }; | |
156 | |
157 template< unsigned N > | |
158 struct get | |
159 { | |
160 template< class Z, class R > | |
161 static BOOST_DEDUCED_TYPENAME ::boost::tuples::element<N,tuple_t>::type begin( Z& z, R& ) | |
162 { | |
163 return get<N>( z.begin().get_iterator_tuple() ); | |
164 } | |
165 | |
166 template< class Z, class R > | |
167 static BOOST_DEDUCED_TYPENAME ::boost::tuples::element<N,tuple_t>::type end( Z& z, R& r ) | |
168 { | |
169 return get<N>( z.end().get_iterator_tuple() ); | |
170 } | |
171 }; | |
172 | |
173 }; | |
174 | |
175 template< class Rng1, class Rng2 > | |
176 struct zip_range | |
177 : iterator_range< | |
178 zip_iterator< | |
179 ::boost::tuples::tuple< | |
180 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type, | |
181 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type | |
182 > | |
183 > | |
184 > | |
185 { | |
186 private: | |
187 typedef zip_iterator< | |
188 ::boost::tuples::tuple< | |
189 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type, | |
190 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type | |
191 > | |
192 > zip_iter_t; | |
193 typedef iterator_range<zip_iter_t> base_t; | |
194 | |
195 public: | |
196 zip_range( Rng1& r1, Rng2& r2 ) | |
197 : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1), | |
198 ::boost::begin(r2)) ), | |
199 zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1), | |
200 ::boost::end(r2)) ) ) | |
201 { | |
202 BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2)); | |
203 } | |
204 }; | |
205 | |
206 template< class Rng1, class Rng2, class Rng3 > | |
207 struct zip_range3 | |
208 : iterator_range< | |
209 zip_iterator< | |
210 ::boost::tuples::tuple< | |
211 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type, | |
212 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type, | |
213 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng3>::type | |
214 > | |
215 > | |
216 > | |
217 { | |
218 private: | |
219 typedef zip_iterator< | |
220 ::boost::tuples::tuple< | |
221 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type, | |
222 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type, | |
223 BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng3>::type | |
224 > | |
225 > zip_iter_t; | |
226 typedef iterator_range<zip_iter_t> base_t; | |
227 | |
228 public: | |
229 zip_range3( Rng1& r1, Rng2& r2, Rng3& r3 ) | |
230 : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1), | |
231 ::boost::begin(r2), | |
232 ::boost::begin(r3)) ), | |
233 zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1), | |
234 ::boost::end(r2), | |
235 ::boost::end(r3)) ) | |
236 ) | |
237 { | |
238 BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2)); | |
239 BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3)); | |
240 } | |
241 }; | |
242 | |
243 | |
244 struct combine_tag {}; | |
245 | |
246 template< class Rng > | |
247 inline zip_rng<Rng> | |
248 operator&( combine_tag, Rng& r ) | |
249 { | |
250 return zip_rng<Rng>(r); | |
251 } | |
252 | |
253 template< class Rng > | |
254 inline iterator_range<const Rng> | |
255 operator&( combine_tag, const Rng& r ) | |
256 { | |
257 return iterator_range<const Rng>(r); | |
258 } | |
259 | |
260 template | |
261 < | |
262 class R1, | |
263 class R2, | |
264 class R3, | |
265 class R4, | |
266 class R5, | |
267 class Rng | |
268 > | |
269 inline BOOST_DEDUCED_TYPENAME zip_rng<R1,R2,R3,R4,R5>::next | |
270 operator&( const zip_rng<R1,R2,R3,R4,R5>& zip, | |
271 Rng& r ) | |
272 { | |
273 return zip_rng<R1,R2,R3,R4,R5>::next( zip, r ); | |
274 } | |
275 | |
276 } // namespace range_detail | |
277 | |
278 template< class Rng1, class Rng2 > | |
279 inline ::boost::range_detail::zip_range<Rng1, Rng2> combine( Rng1& r1, Rng2& r2 ) | |
280 { | |
281 return ::boost::range_detail::zip_range<Rng1, Rng2>(r1, r2); | |
282 } | |
283 | |
284 template< class Rng1, class Rng2 > | |
285 inline ::boost::range_detail::zip_range<const Rng1, Rng2> combine( const Rng1& r1, Rng2& r2 ) | |
286 { | |
287 return ::boost::range_detail::zip_range<const Rng1, Rng2>(r1, r2); | |
288 } | |
289 | |
290 template< class Rng1, class Rng2 > | |
291 inline ::boost::range_detail::zip_range<Rng1, const Rng2> combine( Rng1& r1, const Rng2& r2 ) | |
292 { | |
293 return ::boost::range_detail::zip_range<Rng1, const Rng2>(r1, r2); | |
294 } | |
295 | |
296 template< class Rng1, class Rng2 > | |
297 inline ::boost::range_detail::zip_range<const Rng1, const Rng2> combine( const Rng1& r1, const Rng2& r2 ) | |
298 { | |
299 return ::boost::range_detail::zip_range<const Rng1, const Rng2>(r1, r2); | |
300 } | |
301 | |
302 } // namespace boost | |
303 | |
304 #endif |