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