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-2024 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
48template <
49 BOOST_VARIANT_ENUM_PARAMS(typename T)
50 , typename RecursiveVariant
51 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
52 >
53struct substitute<
54 ::boost::variant<
55 recursive_flag< T0 >
56 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
57 >
58 , RecursiveVariant
59 , ::boost::recursive_variant_
60 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
61 >
62{
63 typedef ::boost::variant<
64 recursive_flag< T0 >
65 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
66 > type;
67};
68
69template <
70 BOOST_VARIANT_ENUM_PARAMS(typename T)
71 , typename RecursiveVariant
72 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
73 >
74struct substitute<
75 ::boost::variant<
76 ::boost::detail::variant::over_sequence< T0 >
77 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
78 >
79 , RecursiveVariant
80 , ::boost::recursive_variant_
81 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
82 >
83{
84private:
85
86 typedef T0 initial_types;
87
88 typedef typename mpl::transform<
89 initial_types
90 , mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> >
91 >::type types;
92
93public:
94
95 typedef typename mpl::if_<
96 mpl::equal<initial_types, types, ::boost::is_same<mpl::_1, mpl::_2> >
97 , ::boost::variant<
98 ::boost::detail::variant::over_sequence< T0 >
99 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
100 >
101 , ::boost::variant< over_sequence<types> >
102 >::type type;
103};
104
105template <
106 BOOST_VARIANT_ENUM_PARAMS(typename T)
107 , typename RecursiveVariant
108 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
109 >
110struct substitute<
111 ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >
112 , RecursiveVariant
113 , ::boost::recursive_variant_
114 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
115 >
116{
117 typedef ::boost::variant<
118 typename enable_recursive<
119 T0
120 , RecursiveVariant
121 , mpl::true_
122 >::type,
123 typename enable_recursive<
124 TN
125 , RecursiveVariant
126 , mpl::true_
127 >::type...
128 > type;
129};
130
131}} // namespace detail::variant
132
133///////////////////////////////////////////////////////////////////////////////
134// metafunction make_recursive_variant
135//
136// See docs and boost/variant/variant_fwd.hpp for more information.
137//
138template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
139struct make_recursive_variant
140{
141public: // metafunction result
142
143 typedef boost::variant<
144 detail::variant::recursive_flag< T0 >
145 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
146 > type;
147
148};
149
150///////////////////////////////////////////////////////////////////////////////
151// metafunction make_recursive_variant_over
152//
153// See docs and boost/variant/variant_fwd.hpp for more information.
154//
155template <typename Types>
156struct make_recursive_variant_over
157{
158private: // precondition assertions
159
160 BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
161
162public: // metafunction result
163
164 typedef typename make_recursive_variant<
165 detail::variant::over_sequence< Types >
166 >::type type;
167
168};
169
170} // namespace boost
171
172#endif // BOOST_VARIANT_RECURSIVE_VARIANT_HPP
173

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