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