text: /*=============================================================================
      Copyright (c) 2001-2011 Joel de Guzman
  
      Distributed under the Boost Software License, Version 1.0. (See accompanying
      file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  ==============================================================================*/
  #if !defined(BOOST_SPIRIT_EXTENDED_VARIANT_AUGUST_6_2011_0859AM)
  #define BOOST_SPIRIT_EXTENDED_VARIANT_AUGUST_6_2011_0859AM
  
  #if defined(_MSC_VER)
  #pragma once
  #endif
  
  #include <boost/variant.hpp>
  #include <boost/mpl/limits/list.hpp>
  #include <boost/preprocessor/repetition/enum_params.hpp>
  #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
  
  #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
  #define BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES BOOST_MPL_LIMIT_LIST_SIZE
  #else
  #define BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES BOOST_VARIANT_LIMIT_TYPES
  #endif
  
  #define BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)                          \
      BOOST_PP_ENUM_PARAMS(BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES, T)        \
      /**/
  
  ///////////////////////////////////////////////////////////////////////////////
  namespace boost { namespace spirit
  {
      template <
          BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
              BOOST_VARIANT_LIMIT_TYPES,
              typename T, boost::detail::variant::void_)
              // We should not be depending on detail::variant::void_
              // but I'm not sure if this can fixed. Any other way is
              // clumsy at best.
          >
      struct extended_variant
      {
          // tell spirit that this is an adapted variant
          struct adapted_variant_tag;
  
          typedef boost::variant<
              BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>
          variant_type;
          typedef typename variant_type::types types;
  
          typedef extended_variant<
              BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)
          > base_type;
  
          extended_variant() : var() {}
  
          template <typename T>
          extended_variant(T const& var)
              : var(var) {}
  
          template <typename T>
          extended_variant(T& var)
              : var(var) {}
  
          template <typename F>
          typename F::result_type apply_visitor(F const& v)
          {
              return var.apply_visitor(v);
          }
  
          template <typename F>
          typename F::result_type apply_visitor(F const& v) const
          {
              return var.apply_visitor(v);
          }
  
          template <typename F>
          typename F::result_type apply_visitor(F& v)
          {
              return var.apply_visitor(v);
          }
  
          template <typename F>
          typename F::result_type apply_visitor(F& v) const
          {
              return var.apply_visitor(v);
          }
  
          variant_type const& get() const
          {
              return var;
          }
  
          variant_type& get()
          {
              return var;
          }
  
          variant_type var;
      };
  }}
  
  namespace boost
  {
      template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
      inline T const&
      get(boost::spirit::extended_variant<
          BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)> const& x)
      {
          return boost::get<T>(x.get());
      }
  
      template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
      inline T&
      get(boost::spirit::extended_variant<
          BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>& x)
      {
          return boost::get<T>(x.get());
      }
  
      template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
      inline T const*
      get(boost::spirit::extended_variant<
          BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)> const* x)
      {
          return boost::get<T>(&x->get());
      }
  
      template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
      inline T*
      get(boost::spirit::extended_variant<
          BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>* x)
      {
          return boost::get<T>(&x->get());
      }
  }
  
  #undef BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS
  #undef BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES
  
  #endif
  