1 //-----------------------------------------------------------------------------
2 // boost variant/recursive_variant.hpp header file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
6 // Copyright (c) 2003 Eric Friedman
7 // Copyright (c) 2013 Antony Polukhin
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
13 #ifndef BOOST_VARIANT_RECURSIVE_VARIANT_HPP
14 #define BOOST_VARIANT_RECURSIVE_VARIANT_HPP
16 #include <boost/variant/variant_fwd.hpp>
17 #include <boost/variant/detail/enable_recursive.hpp>
18 #include <boost/variant/detail/substitute_fwd.hpp>
19 #include <boost/variant/detail/make_variant_list.hpp>
20 #include <boost/variant/detail/over_sequence.hpp>
22 #include <boost/mpl/aux_/lambda_arity_param.hpp>
24 #include <boost/mpl/equal.hpp>
25 #include <boost/mpl/eval_if.hpp>
26 #include <boost/mpl/identity.hpp>
27 #include <boost/mpl/if.hpp>
28 #include <boost/mpl/protect.hpp>
29 #include <boost/mpl/transform.hpp>
30 #include <boost/type_traits/is_same.hpp>
31 #include <boost/preprocessor/cat.hpp>
32 #include <boost/preprocessor/repeat.hpp>
34 #include <boost/mpl/bool.hpp>
35 #include <boost/mpl/is_sequence.hpp>
36 #include <boost/variant/variant.hpp>
40 namespace detail { namespace variant {
42 ///////////////////////////////////////////////////////////////////////////////
43 // (detail) metafunction specialization substitute
45 // Handles embedded variant types when substituting for recursive_variant_.
48 #if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
51 BOOST_VARIANT_ENUM_PARAMS(typename T)
52 , typename RecursiveVariant
53 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
58 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
61 , ::boost::recursive_variant_
62 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
65 typedef ::boost::variant<
67 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
72 BOOST_VARIANT_ENUM_PARAMS(typename T)
73 , typename RecursiveVariant
74 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
78 ::boost::detail::variant::over_sequence< T0 >
79 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
82 , ::boost::recursive_variant_
83 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
88 typedef T0 initial_types;
90 typedef typename mpl::transform<
92 , mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
97 typedef typename mpl::if_<
98 mpl::equal<initial_types, types, ::boost::is_same<mpl::_1, mpl::_2> >
100 ::boost::detail::variant::over_sequence< T0 >
101 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
103 , ::boost::variant< over_sequence<types> >
108 BOOST_VARIANT_ENUM_PARAMS(typename T)
109 , typename RecursiveVariant
110 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
113 ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
115 , ::boost::recursive_variant_
116 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
119 #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
121 typedef ::boost::variant<
122 typename enable_recursive<
127 typename enable_recursive<
134 #else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
136 private: // helpers, for metafunction result (below)
138 #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
139 typedef typename enable_recursive< \
143 >::type BOOST_PP_CAT(wknd_T,N); \
147 BOOST_VARIANT_LIMIT_TYPES
148 , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
152 #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
154 public: // metafunction result
156 typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
157 #endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
160 #else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
163 // no specializations: embedded variants unsupported on these compilers!
166 #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
168 }} // namespace detail::variant
170 ///////////////////////////////////////////////////////////////////////////////
171 // metafunction make_recursive_variant
173 // See docs and boost/variant/variant_fwd.hpp for more information.
175 template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
176 struct make_recursive_variant
178 public: // metafunction result
180 typedef boost::variant<
181 detail::variant::recursive_flag< T0 >
182 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
187 ///////////////////////////////////////////////////////////////////////////////
188 // metafunction make_recursive_variant_over
190 // See docs and boost/variant/variant_fwd.hpp for more information.
192 template <typename Types>
193 struct make_recursive_variant_over
195 private: // precondition assertions
197 BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
199 public: // metafunction result
201 typedef typename make_recursive_variant<
202 detail::variant::over_sequence< Types >
209 #endif // BOOST_VARIANT_RECURSIVE_VARIANT_HPP