Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/spirit/home/support/container.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 /*============================================================================= | |
2 Copyright (c) 2001-2011 Joel de Guzman | |
3 Copyright (c) 2001-2011 Hartmut Kaiser | |
4 http://spirit.sourceforge.net/ | |
5 | |
6 Distributed under the Boost Software License, Version 1.0. (See accompanying | |
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 =============================================================================*/ | |
9 #if !defined(BOOST_SPIRIT_CONTAINER_FEBRUARY_06_2007_1001AM) | |
10 #define BOOST_SPIRIT_CONTAINER_FEBRUARY_06_2007_1001AM | |
11 | |
12 #if defined(_MSC_VER) | |
13 #pragma once | |
14 #endif | |
15 | |
16 #include <boost/spirit/home/support/unused.hpp> | |
17 #include <boost/spirit/home/support/attributes_fwd.hpp> | |
18 #include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits | |
19 #include <boost/mpl/has_xxx.hpp> | |
20 #include <boost/mpl/bool.hpp> | |
21 #include <boost/optional.hpp> | |
22 #include <boost/variant.hpp> | |
23 #include <boost/preprocessor/cat.hpp> | |
24 #include <boost/preprocessor/repeat.hpp> | |
25 #include <boost/range/iterator_range.hpp> | |
26 | |
27 namespace boost { namespace spirit { namespace traits | |
28 { | |
29 /////////////////////////////////////////////////////////////////////////// | |
30 // This file contains some container utils for stl containers. The | |
31 // utilities provided also accept spirit's unused_type; all no-ops. | |
32 // Compiler optimization will easily strip these away. | |
33 /////////////////////////////////////////////////////////////////////////// | |
34 | |
35 namespace detail | |
36 { | |
37 BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type) | |
38 BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator) | |
39 BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type) | |
40 BOOST_MPL_HAS_XXX_TRAIT_DEF(reference) | |
41 } | |
42 | |
43 template <typename T, typename Enable/* = void*/> | |
44 struct is_container | |
45 : mpl::bool_< | |
46 detail::has_value_type<T>::value && | |
47 detail::has_iterator<T>::value && | |
48 detail::has_size_type<T>::value && | |
49 detail::has_reference<T>::value> | |
50 {}; | |
51 | |
52 template <typename T> | |
53 struct is_container<T&> | |
54 : is_container<T> | |
55 {}; | |
56 | |
57 template <typename T> | |
58 struct is_container<boost::optional<T> > | |
59 : is_container<T> | |
60 {}; | |
61 | |
62 #define BOOST_SPIRIT_IS_CONTAINER(z, N, data) \ | |
63 is_container<BOOST_PP_CAT(T, N)>::value || \ | |
64 /***/ | |
65 | |
66 // make sure unused variant parameters do not affect the outcome | |
67 template <> | |
68 struct is_container<boost::detail::variant::void_> | |
69 : mpl::false_ | |
70 {}; | |
71 | |
72 template <BOOST_VARIANT_ENUM_PARAMS(typename T)> | |
73 struct is_container<variant<BOOST_VARIANT_ENUM_PARAMS(T)> > | |
74 : mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES | |
75 , BOOST_SPIRIT_IS_CONTAINER, _) false> | |
76 {}; | |
77 | |
78 #undef BOOST_SPIRIT_IS_CONTAINER | |
79 | |
80 template <typename T, typename Enable/* = void*/> | |
81 struct is_iterator_range | |
82 : mpl::false_ | |
83 {}; | |
84 | |
85 template <typename T> | |
86 struct is_iterator_range<iterator_range<T> > | |
87 : mpl::true_ | |
88 {}; | |
89 | |
90 /////////////////////////////////////////////////////////////////////////// | |
91 namespace detail | |
92 { | |
93 template <typename T> | |
94 struct remove_value_const | |
95 { | |
96 typedef T type; | |
97 }; | |
98 | |
99 template <typename T> | |
100 struct remove_value_const<T const> | |
101 : remove_value_const<T> | |
102 {}; | |
103 | |
104 template <typename F, typename S> | |
105 struct remove_value_const<std::pair<F, S> > | |
106 { | |
107 typedef typename remove_value_const<F>::type first_type; | |
108 typedef typename remove_value_const<S>::type second_type; | |
109 typedef std::pair<first_type, second_type> type; | |
110 }; | |
111 } | |
112 | |
113 /////////////////////////////////////////////////////////////////////// | |
114 //[customization_container_value_default | |
115 template <typename Container, typename Enable/* = void*/> | |
116 struct container_value | |
117 : detail::remove_value_const<typename Container::value_type> | |
118 {}; | |
119 //] | |
120 | |
121 template <typename T> | |
122 struct container_value<T&> | |
123 : container_value<T> | |
124 {}; | |
125 | |
126 // this will be instantiated if the optional holds a container | |
127 template <typename T> | |
128 struct container_value<boost::optional<T> > | |
129 : container_value<T> | |
130 {}; | |
131 | |
132 // this will be instantiated if the variant holds a container | |
133 template <BOOST_VARIANT_ENUM_PARAMS(typename T)> | |
134 struct container_value<variant<BOOST_VARIANT_ENUM_PARAMS(T)> > | |
135 { | |
136 typedef typename | |
137 variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types | |
138 types; | |
139 typedef typename | |
140 mpl::find_if<types, is_container<mpl::_1> >::type | |
141 iter; | |
142 | |
143 typedef typename container_value< | |
144 typename mpl::if_< | |
145 is_same<iter, typename mpl::end<types>::type> | |
146 , unused_type, typename mpl::deref<iter>::type | |
147 >::type | |
148 >::type type; | |
149 }; | |
150 | |
151 //[customization_container_value_unused | |
152 template <> | |
153 struct container_value<unused_type> | |
154 { | |
155 typedef unused_type type; | |
156 }; | |
157 //] | |
158 | |
159 template <> | |
160 struct container_value<unused_type const> | |
161 { | |
162 typedef unused_type type; | |
163 }; | |
164 | |
165 /////////////////////////////////////////////////////////////////////////// | |
166 template <typename Container, typename Enable/* = void*/> | |
167 struct container_iterator | |
168 { | |
169 typedef typename Container::iterator type; | |
170 }; | |
171 | |
172 template <typename Container> | |
173 struct container_iterator<Container&> | |
174 : container_iterator<Container> | |
175 {}; | |
176 | |
177 template <typename Container> | |
178 struct container_iterator<Container const> | |
179 { | |
180 typedef typename Container::const_iterator type; | |
181 }; | |
182 | |
183 template <typename T> | |
184 struct container_iterator<optional<T> > | |
185 : container_iterator<T> | |
186 {}; | |
187 | |
188 template <typename T> | |
189 struct container_iterator<optional<T> const> | |
190 : container_iterator<T const> | |
191 {}; | |
192 | |
193 template <typename Iterator> | |
194 struct container_iterator<iterator_range<Iterator> > | |
195 { | |
196 typedef typename range_const_iterator< | |
197 iterator_range<Iterator> >::type type; | |
198 }; | |
199 | |
200 template <> | |
201 struct container_iterator<unused_type> | |
202 { | |
203 typedef unused_type const* type; | |
204 }; | |
205 | |
206 template <> | |
207 struct container_iterator<unused_type const> | |
208 { | |
209 typedef unused_type const* type; | |
210 }; | |
211 | |
212 /////////////////////////////////////////////////////////////////////////// | |
213 template <typename T, typename Enable/* = void*/> | |
214 struct optional_attribute | |
215 { | |
216 typedef T const& type; | |
217 | |
218 static type call(T const& val) | |
219 { | |
220 return val; | |
221 } | |
222 | |
223 static bool is_valid(T const&) | |
224 { | |
225 return true; | |
226 } | |
227 }; | |
228 | |
229 template <typename T> | |
230 struct optional_attribute<boost::optional<T> > | |
231 { | |
232 typedef T const& type; | |
233 | |
234 static type call(boost::optional<T> const& val) | |
235 { | |
236 return boost::get<T>(val); | |
237 } | |
238 | |
239 static bool is_valid(boost::optional<T> const& val) | |
240 { | |
241 return val; | |
242 } | |
243 }; | |
244 | |
245 template <typename T> | |
246 typename optional_attribute<T>::type | |
247 optional_value(T const& val) | |
248 { | |
249 return optional_attribute<T>::call(val); | |
250 } | |
251 | |
252 inline unused_type optional_value(unused_type) | |
253 { | |
254 return unused; | |
255 } | |
256 | |
257 template <typename T> | |
258 bool has_optional_value(T const& val) | |
259 { | |
260 return optional_attribute<T>::is_valid(val); | |
261 } | |
262 | |
263 inline bool has_optional_value(unused_type) | |
264 { | |
265 return true; | |
266 } | |
267 | |
268 /////////////////////////////////////////////////////////////////////////// | |
269 template <typename Container, typename T> | |
270 bool push_back(Container& c, T const& val); | |
271 | |
272 //[customization_push_back_default | |
273 template <typename Container, typename T, typename Enable/* = void*/> | |
274 struct push_back_container | |
275 { | |
276 static bool call(Container& c, T const& val) | |
277 { | |
278 c.insert(c.end(), val); | |
279 return true; | |
280 } | |
281 }; | |
282 //] | |
283 | |
284 template <typename Container, typename T> | |
285 struct push_back_container<optional<Container>, T> | |
286 { | |
287 static bool call(boost::optional<Container>& c, T const& val) | |
288 { | |
289 if (!c) | |
290 c = Container(); | |
291 return push_back(boost::get<Container>(c), val); | |
292 } | |
293 }; | |
294 | |
295 namespace detail | |
296 { | |
297 template <typename T> | |
298 struct push_back_visitor : public static_visitor<> | |
299 { | |
300 typedef bool result_type; | |
301 | |
302 push_back_visitor(T const& t) : t_(t) {} | |
303 | |
304 template <typename Container> | |
305 bool push_back_impl(Container& c, mpl::true_) const | |
306 { | |
307 return push_back(c, t_); | |
308 } | |
309 | |
310 template <typename T_> | |
311 bool push_back_impl(T_&, mpl::false_) const | |
312 { | |
313 // this variant doesn't hold a container | |
314 BOOST_ASSERT(false && "This variant doesn't hold a container"); | |
315 return false; | |
316 } | |
317 | |
318 template <typename T_> | |
319 bool operator()(T_& c) const | |
320 { | |
321 return push_back_impl(c, typename is_container<T_>::type()); | |
322 } | |
323 | |
324 T const& t_; | |
325 }; | |
326 } | |
327 | |
328 template <BOOST_VARIANT_ENUM_PARAMS(typename T_), typename T> | |
329 struct push_back_container<variant<BOOST_VARIANT_ENUM_PARAMS(T_)>, T> | |
330 { | |
331 static bool call(variant<BOOST_VARIANT_ENUM_PARAMS(T_)>& c, T const& val) | |
332 { | |
333 return apply_visitor(detail::push_back_visitor<T>(val), c); | |
334 } | |
335 }; | |
336 | |
337 template <typename Container, typename T> | |
338 bool push_back(Container& c, T const& val) | |
339 { | |
340 return push_back_container<Container, T>::call(c, val); | |
341 } | |
342 | |
343 //[customization_push_back_unused | |
344 template <typename Container> | |
345 bool push_back(Container&, unused_type) | |
346 { | |
347 return true; | |
348 } | |
349 //] | |
350 | |
351 template <typename T> | |
352 bool push_back(unused_type, T const&) | |
353 { | |
354 return true; | |
355 } | |
356 | |
357 inline bool push_back(unused_type, unused_type) | |
358 { | |
359 return true; | |
360 } | |
361 | |
362 /////////////////////////////////////////////////////////////////////////// | |
363 template <typename Container, typename Enable/* = void*/> | |
364 struct is_empty_container | |
365 { | |
366 static bool call(Container const& c) | |
367 { | |
368 return c.empty(); | |
369 } | |
370 }; | |
371 | |
372 template <typename Container> | |
373 bool is_empty(Container const& c) | |
374 { | |
375 return is_empty_container<Container>::call(c); | |
376 } | |
377 | |
378 inline bool is_empty(unused_type) | |
379 { | |
380 return true; | |
381 } | |
382 | |
383 /////////////////////////////////////////////////////////////////////////// | |
384 // Ensure the attribute is actually a container type | |
385 template <typename Container, typename Enable/* = void*/> | |
386 struct make_container_attribute | |
387 { | |
388 static void call(Container&) | |
389 { | |
390 // for static types this function does nothing | |
391 } | |
392 }; | |
393 | |
394 template <typename T> | |
395 void make_container(T& t) | |
396 { | |
397 make_container_attribute<T>::call(t); | |
398 } | |
399 | |
400 inline void make_container(unused_type) | |
401 { | |
402 } | |
403 | |
404 /////////////////////////////////////////////////////////////////////////// | |
405 template <typename Container, typename Enable/* = void*/> | |
406 struct begin_container | |
407 { | |
408 static typename container_iterator<Container>::type call(Container& c) | |
409 { | |
410 return c.begin(); | |
411 } | |
412 }; | |
413 | |
414 template <typename Container> | |
415 typename spirit::result_of::begin<Container>::type | |
416 begin(Container& c) | |
417 { | |
418 return begin_container<Container>::call(c); | |
419 } | |
420 | |
421 inline unused_type const* | |
422 begin(unused_type) | |
423 { | |
424 return &unused; | |
425 } | |
426 | |
427 /////////////////////////////////////////////////////////////////////////// | |
428 template <typename Container, typename Enable/* = void*/> | |
429 struct end_container | |
430 { | |
431 static typename container_iterator<Container>::type call(Container& c) | |
432 { | |
433 return c.end(); | |
434 } | |
435 }; | |
436 | |
437 template <typename Container> | |
438 inline typename spirit::result_of::end<Container>::type | |
439 end(Container& c) | |
440 { | |
441 return end_container<Container>::call(c); | |
442 } | |
443 | |
444 inline unused_type const* | |
445 end(unused_type) | |
446 { | |
447 return &unused; | |
448 } | |
449 | |
450 /////////////////////////////////////////////////////////////////////////// | |
451 template <typename Iterator, typename Enable/* = void*/> | |
452 struct deref_iterator | |
453 { | |
454 typedef typename boost::detail::iterator_traits<Iterator>::reference type; | |
455 static type call(Iterator& it) | |
456 { | |
457 return *it; | |
458 } | |
459 }; | |
460 | |
461 template <typename Iterator> | |
462 typename deref_iterator<Iterator>::type | |
463 deref(Iterator& it) | |
464 { | |
465 return deref_iterator<Iterator>::call(it); | |
466 } | |
467 | |
468 inline unused_type | |
469 deref(unused_type const*) | |
470 { | |
471 return unused; | |
472 } | |
473 | |
474 /////////////////////////////////////////////////////////////////////////// | |
475 template <typename Iterator, typename Enable/* = void*/> | |
476 struct next_iterator | |
477 { | |
478 static void call(Iterator& it) | |
479 { | |
480 ++it; | |
481 } | |
482 }; | |
483 | |
484 template <typename Iterator> | |
485 void next(Iterator& it) | |
486 { | |
487 next_iterator<Iterator>::call(it); | |
488 } | |
489 | |
490 inline void next(unused_type const*) | |
491 { | |
492 // do nothing | |
493 } | |
494 | |
495 /////////////////////////////////////////////////////////////////////////// | |
496 template <typename Iterator, typename Enable/* = void*/> | |
497 struct compare_iterators | |
498 { | |
499 static bool call(Iterator const& it1, Iterator const& it2) | |
500 { | |
501 return it1 == it2; | |
502 } | |
503 }; | |
504 | |
505 template <typename Iterator> | |
506 bool compare(Iterator& it1, Iterator& it2) | |
507 { | |
508 return compare_iterators<Iterator>::call(it1, it2); | |
509 } | |
510 | |
511 inline bool compare(unused_type const*, unused_type const*) | |
512 { | |
513 return false; | |
514 } | |
515 }}} | |
516 | |
517 /////////////////////////////////////////////////////////////////////////////// | |
518 namespace boost { namespace spirit { namespace result_of | |
519 { | |
520 /////////////////////////////////////////////////////////////////////////// | |
521 template <typename T> | |
522 struct optional_value | |
523 { | |
524 typedef T type; | |
525 }; | |
526 | |
527 template <typename T> | |
528 struct optional_value<boost::optional<T> > | |
529 { | |
530 typedef T type; | |
531 }; | |
532 | |
533 template <typename T> | |
534 struct optional_value<boost::optional<T> const> | |
535 { | |
536 typedef T const type; | |
537 }; | |
538 | |
539 template <> | |
540 struct optional_value<unused_type> | |
541 { | |
542 typedef unused_type type; | |
543 }; | |
544 | |
545 template <> | |
546 struct optional_value<unused_type const> | |
547 { | |
548 typedef unused_type type; | |
549 }; | |
550 | |
551 /////////////////////////////////////////////////////////////////////////// | |
552 template <typename Container> | |
553 struct begin | |
554 : traits::container_iterator<Container> | |
555 {}; | |
556 | |
557 template <typename Container> | |
558 struct end | |
559 : traits::container_iterator<Container> | |
560 {}; | |
561 | |
562 template <typename Iterator> | |
563 struct deref | |
564 : traits::deref_iterator<Iterator> | |
565 {}; | |
566 | |
567 template <> | |
568 struct deref<unused_type const*> | |
569 { | |
570 typedef unused_type type; | |
571 }; | |
572 | |
573 }}} | |
574 | |
575 #endif |