extended_variant.hpp 5.2 KB

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