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