Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2011 Joel de Guzman
|
Chris@16
|
3
|
Chris@16
|
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 ==============================================================================*/
|
Chris@16
|
7 #if !defined(BOOST_SPIRIT_EXTENDED_VARIANT_AUGUST_6_2011_0859AM)
|
Chris@16
|
8 #define BOOST_SPIRIT_EXTENDED_VARIANT_AUGUST_6_2011_0859AM
|
Chris@16
|
9
|
Chris@16
|
10 #if defined(_MSC_VER)
|
Chris@16
|
11 #pragma once
|
Chris@16
|
12 #endif
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/variant.hpp>
|
Chris@101
|
15 #include <boost/mpl/limits/list.hpp>
|
Chris@101
|
16 #include <boost/preprocessor/repetition/enum_params.hpp>
|
Chris@16
|
17 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
Chris@16
|
18
|
Chris@101
|
19 #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
Chris@101
|
20 #define BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES BOOST_MPL_LIMIT_LIST_SIZE
|
Chris@101
|
21 #else
|
Chris@101
|
22 #define BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES BOOST_VARIANT_LIMIT_TYPES
|
Chris@101
|
23 #endif
|
Chris@101
|
24
|
Chris@101
|
25 #define BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T) \
|
Chris@101
|
26 BOOST_PP_ENUM_PARAMS(BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES, T) \
|
Chris@101
|
27 /**/
|
Chris@101
|
28
|
Chris@16
|
29 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
30 namespace boost { namespace spirit
|
Chris@16
|
31 {
|
Chris@16
|
32 template <
|
Chris@16
|
33 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
|
Chris@16
|
34 BOOST_VARIANT_LIMIT_TYPES,
|
Chris@16
|
35 typename T, boost::detail::variant::void_)
|
Chris@16
|
36 // We should not be depending on detail::variant::void_
|
Chris@16
|
37 // but I'm not sure if this can fixed. Any other way is
|
Chris@16
|
38 // clumsy at best.
|
Chris@16
|
39 >
|
Chris@16
|
40 struct extended_variant
|
Chris@16
|
41 {
|
Chris@16
|
42 // tell spirit that this is an adapted variant
|
Chris@16
|
43 struct adapted_variant_tag;
|
Chris@16
|
44
|
Chris@16
|
45 typedef boost::variant<
|
Chris@101
|
46 BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>
|
Chris@16
|
47 variant_type;
|
Chris@16
|
48 typedef typename variant_type::types types;
|
Chris@16
|
49
|
Chris@101
|
50 typedef extended_variant<
|
Chris@101
|
51 BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)
|
Chris@101
|
52 > base_type;
|
Chris@16
|
53
|
Chris@16
|
54 extended_variant() : var() {}
|
Chris@16
|
55
|
Chris@16
|
56 template <typename T>
|
Chris@16
|
57 extended_variant(T const& var)
|
Chris@16
|
58 : var(var) {}
|
Chris@16
|
59
|
Chris@16
|
60 template <typename T>
|
Chris@16
|
61 extended_variant(T& var)
|
Chris@16
|
62 : var(var) {}
|
Chris@16
|
63
|
Chris@16
|
64 template <typename F>
|
Chris@16
|
65 typename F::result_type apply_visitor(F const& v)
|
Chris@16
|
66 {
|
Chris@16
|
67 return var.apply_visitor(v);
|
Chris@16
|
68 }
|
Chris@16
|
69
|
Chris@16
|
70 template <typename F>
|
Chris@16
|
71 typename F::result_type apply_visitor(F const& v) const
|
Chris@16
|
72 {
|
Chris@16
|
73 return var.apply_visitor(v);
|
Chris@16
|
74 }
|
Chris@16
|
75
|
Chris@16
|
76 template <typename F>
|
Chris@16
|
77 typename F::result_type apply_visitor(F& v)
|
Chris@16
|
78 {
|
Chris@16
|
79 return var.apply_visitor(v);
|
Chris@16
|
80 }
|
Chris@16
|
81
|
Chris@16
|
82 template <typename F>
|
Chris@16
|
83 typename F::result_type apply_visitor(F& v) const
|
Chris@16
|
84 {
|
Chris@16
|
85 return var.apply_visitor(v);
|
Chris@16
|
86 }
|
Chris@16
|
87
|
Chris@16
|
88 variant_type const& get() const
|
Chris@16
|
89 {
|
Chris@16
|
90 return var;
|
Chris@16
|
91 }
|
Chris@16
|
92
|
Chris@16
|
93 variant_type& get()
|
Chris@16
|
94 {
|
Chris@16
|
95 return var;
|
Chris@16
|
96 }
|
Chris@16
|
97
|
Chris@16
|
98 variant_type var;
|
Chris@16
|
99 };
|
Chris@16
|
100 }}
|
Chris@16
|
101
|
Chris@16
|
102 namespace boost
|
Chris@16
|
103 {
|
Chris@101
|
104 template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
|
Chris@16
|
105 inline T const&
|
Chris@101
|
106 get(boost::spirit::extended_variant<
|
Chris@101
|
107 BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)> const& x)
|
Chris@16
|
108 {
|
Chris@16
|
109 return boost::get<T>(x.get());
|
Chris@16
|
110 }
|
Chris@16
|
111
|
Chris@101
|
112 template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
|
Chris@16
|
113 inline T&
|
Chris@101
|
114 get(boost::spirit::extended_variant<
|
Chris@101
|
115 BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>& x)
|
Chris@16
|
116 {
|
Chris@16
|
117 return boost::get<T>(x.get());
|
Chris@16
|
118 }
|
Chris@16
|
119
|
Chris@101
|
120 template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
|
Chris@16
|
121 inline T const*
|
Chris@101
|
122 get(boost::spirit::extended_variant<
|
Chris@101
|
123 BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)> const* x)
|
Chris@16
|
124 {
|
Chris@16
|
125 return boost::get<T>(&x->get());
|
Chris@16
|
126 }
|
Chris@16
|
127
|
Chris@101
|
128 template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
|
Chris@16
|
129 inline T*
|
Chris@101
|
130 get(boost::spirit::extended_variant<
|
Chris@101
|
131 BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>* x)
|
Chris@16
|
132 {
|
Chris@16
|
133 return boost::get<T>(&x->get());
|
Chris@16
|
134 }
|
Chris@16
|
135 }
|
Chris@16
|
136
|
Chris@101
|
137 #undef BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS
|
Chris@101
|
138 #undef BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES
|
Chris@101
|
139
|
Chris@16
|
140 #endif
|