extended_variant.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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/preprocessor/repetition/enum_params_with_a_default.hpp>
  13. ///////////////////////////////////////////////////////////////////////////////
  14. namespace boost { namespace spirit
  15. {
  16. template <
  17. BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
  18. BOOST_VARIANT_LIMIT_TYPES,
  19. typename T, boost::detail::variant::void_)
  20. // We should not be depending on detail::variant::void_
  21. // but I'm not sure if this can fixed. Any other way is
  22. // clumsy at best.
  23. >
  24. struct extended_variant
  25. {
  26. // tell spirit that this is an adapted variant
  27. struct adapted_variant_tag;
  28. typedef boost::variant<
  29. BOOST_VARIANT_ENUM_PARAMS(T)>
  30. variant_type;
  31. typedef typename variant_type::types types;
  32. typedef extended_variant<BOOST_VARIANT_ENUM_PARAMS(T)> base_type;
  33. extended_variant() : var() {}
  34. template <typename T>
  35. extended_variant(T const& var)
  36. : var(var) {}
  37. template <typename T>
  38. extended_variant(T& var)
  39. : var(var) {}
  40. template <typename F>
  41. typename F::result_type apply_visitor(F const& v)
  42. {
  43. return var.apply_visitor(v);
  44. }
  45. template <typename F>
  46. typename F::result_type apply_visitor(F const& v) const
  47. {
  48. return var.apply_visitor(v);
  49. }
  50. template <typename F>
  51. typename F::result_type apply_visitor(F& v)
  52. {
  53. return var.apply_visitor(v);
  54. }
  55. template <typename F>
  56. typename F::result_type apply_visitor(F& v) const
  57. {
  58. return var.apply_visitor(v);
  59. }
  60. variant_type const& get() const
  61. {
  62. return var;
  63. }
  64. variant_type& get()
  65. {
  66. return var;
  67. }
  68. variant_type var;
  69. };
  70. }}
  71. namespace boost
  72. {
  73. template <typename T, BOOST_VARIANT_ENUM_PARAMS(typename T)>
  74. inline T const&
  75. get(boost::spirit::extended_variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& x)
  76. {
  77. return boost::get<T>(x.get());
  78. }
  79. template <typename T, BOOST_VARIANT_ENUM_PARAMS(typename T)>
  80. inline T&
  81. get(boost::spirit::extended_variant<BOOST_VARIANT_ENUM_PARAMS(T)>& x)
  82. {
  83. return boost::get<T>(x.get());
  84. }
  85. template <typename T, BOOST_VARIANT_ENUM_PARAMS(typename T)>
  86. inline T const*
  87. get(boost::spirit::extended_variant<BOOST_VARIANT_ENUM_PARAMS(T)> const* x)
  88. {
  89. return boost::get<T>(&x->get());
  90. }
  91. template <typename T, BOOST_VARIANT_ENUM_PARAMS(typename T)>
  92. inline T*
  93. get(boost::spirit::extended_variant<BOOST_VARIANT_ENUM_PARAMS(T)>* x)
  94. {
  95. return boost::get<T>(&x->get());
  96. }
  97. }
  98. #endif