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