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