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