• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
extended_variantboost::spirit::extended_variant64         extended_variant() : var() {}
65 
66         template <typename T>
extended_variantboost::spirit::extended_variant67         extended_variant(T const& var)
68             : var(var) {}
69 
70         template <typename T>
extended_variantboost::spirit::extended_variant71         extended_variant(T& var)
72             : var(var) {}
73 
74         template <typename F>
apply_visitorboost::spirit::extended_variant75         typename F::result_type apply_visitor(F const& v)
76         {
77             return var.apply_visitor(v);
78         }
79 
80         template <typename F>
apply_visitorboost::spirit::extended_variant81         typename F::result_type apply_visitor(F const& v) const
82         {
83             return var.apply_visitor(v);
84         }
85 
86         template <typename F>
apply_visitorboost::spirit::extended_variant87         typename F::result_type apply_visitor(F& v)
88         {
89             return var.apply_visitor(v);
90         }
91 
92         template <typename F>
apply_visitorboost::spirit::extended_variant93         typename F::result_type apply_visitor(F& v) const
94         {
95             return var.apply_visitor(v);
96         }
97 
getboost::spirit::extended_variant98         variant_type const& get() const
99         {
100             return var;
101         }
102 
getboost::spirit::extended_variant103         variant_type& get()
104         {
105             return var;
106         }
107 
swapboost::spirit::extended_variant108         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&
get(boost::spirit::extended_variant<BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS (T)> const & x)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&
get(boost::spirit::extended_variant<BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS (T)> & x)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*
get(boost::spirit::extended_variant<BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS (T)> const * x)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*
get(boost::spirit::extended_variant<BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS (T)> * x)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
186