williamr@2: //-----------------------------------------------------------------------------
williamr@2: // boost variant/recursive_variant.hpp header file
williamr@2: // See http://www.boost.org for updates, documentation, and revision history.
williamr@2: //-----------------------------------------------------------------------------
williamr@2: //
williamr@2: // Copyright (c) 2003
williamr@2: // Eric Friedman
williamr@2: //
williamr@2: // Distributed under the Boost Software License, Version 1.0. (See
williamr@2: // accompanying file LICENSE_1_0.txt or copy at
williamr@2: // http://www.boost.org/LICENSE_1_0.txt)
williamr@2: 
williamr@2: #ifndef BOOST_VARIANT_RECURSIVE_VARIANT_HPP
williamr@2: #define BOOST_VARIANT_RECURSIVE_VARIANT_HPP
williamr@2: 
williamr@2: #include "boost/variant/variant_fwd.hpp"
williamr@2: #include "boost/variant/detail/enable_recursive.hpp"
williamr@2: #include "boost/variant/detail/substitute_fwd.hpp"
williamr@2: #include "boost/variant/detail/make_variant_list.hpp"
williamr@2: #include "boost/variant/detail/over_sequence.hpp"
williamr@2: 
williamr@2: #include "boost/mpl/aux_/lambda_arity_param.hpp"
williamr@2: 
williamr@2: #if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
williamr@2: #   include "boost/mpl/eval_if.hpp"
williamr@2: #   include "boost/mpl/identity.hpp"
williamr@2: #   include "boost/mpl/protect.hpp"
williamr@2: #   include "boost/mpl/transform.hpp"
williamr@2: #else
williamr@2: #   include "boost/preprocessor/cat.hpp"
williamr@2: #   include "boost/preprocessor/repeat.hpp"
williamr@2: #endif
williamr@2: 
williamr@2: #include "boost/mpl/bool.hpp"
williamr@2: #include "boost/mpl/is_sequence.hpp"
williamr@2: #include "boost/variant/variant.hpp"
williamr@2: 
williamr@2: namespace boost {
williamr@2: 
williamr@2: namespace detail { namespace variant {
williamr@2: 
williamr@2: ///////////////////////////////////////////////////////////////////////////////
williamr@2: // (detail) metafunction specialization substitute
williamr@2: //
williamr@2: // Handles embedded variant types when substituting for recursive_variant_.
williamr@2: //
williamr@2: 
williamr@2: #if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
williamr@2: 
williamr@2: template <
williamr@2:       BOOST_VARIANT_ENUM_PARAMS(typename T)
williamr@2:     , typename RecursiveVariant
williamr@2:       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
williamr@2:     >
williamr@2: struct substitute<
williamr@2:       ::boost::variant<
williamr@2:           recursive_flag< T0 >
williamr@2:         , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
williamr@2:         >
williamr@2:     , RecursiveVariant
williamr@2:     , ::boost::recursive_variant_
williamr@2:       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
williamr@2:     >
williamr@2: {
williamr@2:     typedef ::boost::variant<
williamr@2:           recursive_flag< T0 >
williamr@2:         , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
williamr@2:         > type;
williamr@2: };
williamr@2: 
williamr@2: template <
williamr@2:       BOOST_VARIANT_ENUM_PARAMS(typename T)
williamr@2:     , typename RecursiveVariant
williamr@2:       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
williamr@2:     >
williamr@2: struct substitute<
williamr@2:       ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
williamr@2:     , RecursiveVariant
williamr@2:     , ::boost::recursive_variant_
williamr@2:       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
williamr@2:     >
williamr@2: {
williamr@2: 
williamr@2: #if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
williamr@2: 
williamr@2: private: // helpers, for metafunction result (below)
williamr@2: 
williamr@2:     typedef typename mpl::eval_if<
williamr@2:           ::boost::detail::variant::is_over_sequence<T0>
williamr@2:         , mpl::identity< T0 >
williamr@2:         , make_variant_list< BOOST_VARIANT_ENUM_PARAMS(T) >
williamr@2:         >::type initial_types;
williamr@2: 
williamr@2:     typedef typename mpl::transform<
williamr@2:           initial_types
williamr@2:         , mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
williamr@2:         >::type types;
williamr@2: 
williamr@2: public: // metafunction result
williamr@2: 
williamr@2:     typedef ::boost::variant< types > type;
williamr@2: 
williamr@2: #else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
williamr@2: 
williamr@2: private: // helpers, for metafunction result (below)
williamr@2: 
williamr@2:     #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_)  \
williamr@2:         typedef typename enable_recursive<   \
williamr@2:               BOOST_PP_CAT(T,N)              \
williamr@2:             , RecursiveVariant               \
williamr@2:             , mpl::true_                     \
williamr@2:             >::type BOOST_PP_CAT(wknd_T,N);  \
williamr@2:         /**/
williamr@2: 
williamr@2:     BOOST_PP_REPEAT(
williamr@2:           BOOST_VARIANT_LIMIT_TYPES
williamr@2:         , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
williamr@2:         , _
williamr@2:         )
williamr@2: 
williamr@2:     #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
williamr@2: 
williamr@2: public: // metafunction result
williamr@2: 
williamr@2:     typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
williamr@2: 
williamr@2: #endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
williamr@2: 
williamr@2: };
williamr@2: 
williamr@2: #else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
williamr@2: 
williamr@2: //
williamr@2: // no specializations: embedded variants unsupported on these compilers!
williamr@2: //
williamr@2: 
williamr@2: #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
williamr@2: 
williamr@2: }} // namespace detail::variant
williamr@2: 
williamr@2: ///////////////////////////////////////////////////////////////////////////////
williamr@2: // metafunction make_recursive_variant
williamr@2: //
williamr@2: // See docs and boost/variant/variant_fwd.hpp for more information.
williamr@2: //
williamr@2: template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
williamr@2: struct make_recursive_variant
williamr@2: {
williamr@2: public: // metafunction result
williamr@2: 
williamr@2:     typedef boost::variant<
williamr@2:           detail::variant::recursive_flag< T0 >
williamr@2:         , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
williamr@2:         > type;
williamr@2: 
williamr@2: };
williamr@2: 
williamr@2: ///////////////////////////////////////////////////////////////////////////////
williamr@2: // metafunction make_recursive_variant_over
williamr@2: //
williamr@2: // See docs and boost/variant/variant_fwd.hpp for more information.
williamr@2: //
williamr@2: template <typename Types>
williamr@2: struct make_recursive_variant_over
williamr@2: {
williamr@2: private: // precondition assertions
williamr@2: 
williamr@2: #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
williamr@2:     BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
williamr@2: #endif
williamr@2: 
williamr@2: public: // metafunction result
williamr@2: 
williamr@2:     typedef typename make_recursive_variant<
williamr@2:           detail::variant::over_sequence< Types >
williamr@2:         >::type type;
williamr@2: 
williamr@2: };
williamr@2: 
williamr@2: } // namespace boost
williamr@2: 
williamr@2: #endif // BOOST_VARIANT_RECURSIVE_VARIANT_HPP