1//-----------------------------------------------------------------------------
2// boost variant/recursive_variant.hpp header file
3// See http://www.boost.org for updates, documentation, and revision history.
4//-----------------------------------------------------------------------------
5//
6// Copyright (c) 2003 Eric Friedman
7// Copyright (c) 2013 Antony Polukhin
8//
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)
12
13#ifndef BOOST_VARIANT_RECURSIVE_VARIANT_HPP
14#define BOOST_VARIANT_RECURSIVE_VARIANT_HPP
15
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"
21
22#include "boost/mpl/aux_/lambda_arity_param.hpp"
23
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"
33
34#include "boost/mpl/bool.hpp"
35#include "boost/mpl/is_sequence.hpp"
36#include "boost/variant/variant.hpp"
37
38namespace boost {
39
40namespace detail { namespace variant {
41
42///////////////////////////////////////////////////////////////////////////////
43// (detail) metafunction specialization substitute
44//
45// Handles embedded variant types when substituting for recursive_variant_.
46//
47
48#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
49
50template <
51 BOOST_VARIANT_ENUM_PARAMS(typename T)
52 , typename RecursiveVariant
53 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
54 >
55struct substitute<
56 ::boost::variant<
57 recursive_flag< T0 >
58 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
59 >
60 , RecursiveVariant
61 , ::boost::recursive_variant_
62 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
63 >
64{
65 typedef ::boost::variant<
66 recursive_flag< T0 >
67 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
68 > type;
69};
70
71template <
72 BOOST_VARIANT_ENUM_PARAMS(typename T)
73 , typename RecursiveVariant
74 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
75 >
76struct substitute<
77 ::boost::variant<
78 ::boost::detail::variant::over_sequence< T0 >
79 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
80 >
81 , RecursiveVariant
82 , ::boost::recursive_variant_
83 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
84 >
85{
86private:
87
88 typedef T0 initial_types;
89
90 typedef typename mpl::transform<
91 initial_types
92 , mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
93 >::type types;
94
95public:
96
97 typedef typename mpl::if_<
98 mpl::equal<initial_types, types, ::boost::is_same<mpl::_1, mpl::_2> >
99 , ::boost::variant<
100 ::boost::detail::variant::over_sequence< T0 >
101 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
102 >
103 , ::boost::variant< over_sequence<types> >
104 >::type type;
105};
106
107template <
108 BOOST_VARIANT_ENUM_PARAMS(typename T)
109 , typename RecursiveVariant
110 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
111 >
112struct substitute<
113 ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
114 , RecursiveVariant
115 , ::boost::recursive_variant_
116 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
117 >
118{
119#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
120
121 typedef ::boost::variant<
122 typename enable_recursive<
123 T0
124 , RecursiveVariant
125 , mpl::true_
126 >::type,
127 typename enable_recursive<
128 TN
129 , RecursiveVariant
130 , mpl::true_
131 >::type...
132 > type;
133
134#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
135
136private: // helpers, for metafunction result (below)
137
138 #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
139 typedef typename enable_recursive< \
140 BOOST_PP_CAT(T,N) \
141 , RecursiveVariant \
142 , mpl::true_ \
143 >::type BOOST_PP_CAT(wknd_T,N); \
144 /**/
145
146 BOOST_PP_REPEAT(
147 BOOST_VARIANT_LIMIT_TYPES
148 , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
149 , _
150 )
151
152 #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
153
154public: // metafunction result
155
156 typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type;
157#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
158};
159
160#else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
161
162//
163// no specializations: embedded variants unsupported on these compilers!
164//
165
166#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
167
168}} // namespace detail::variant
169
170///////////////////////////////////////////////////////////////////////////////
171// metafunction make_recursive_variant
172//
173// See docs and boost/variant/variant_fwd.hpp for more information.
174//
175template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
176struct make_recursive_variant
177{
178public: // metafunction result
179
180 typedef boost::variant<
181 detail::variant::recursive_flag< T0 >
182 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
183 > type;
184
185};
186
187///////////////////////////////////////////////////////////////////////////////
188// metafunction make_recursive_variant_over
189//
190// See docs and boost/variant/variant_fwd.hpp for more information.
191//
192template <typename Types>
193struct make_recursive_variant_over
194{
195private: // precondition assertions
196
197 BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
198
199public: // metafunction result
200
201 typedef typename make_recursive_variant<
202 detail::variant::over_sequence< Types >
203 >::type type;
204
205};
206
207} // namespace boost
208
209#endif // BOOST_VARIANT_RECURSIVE_VARIANT_HPP
210

source code of boost/boost/variant/recursive_variant.hpp