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 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 > 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 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::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