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 |
---|
7 | // Eric Friedman |
---|
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 | #if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT) |
---|
25 | # include "boost/mpl/eval_if.hpp" |
---|
26 | # include "boost/mpl/identity.hpp" |
---|
27 | # include "boost/mpl/protect.hpp" |
---|
28 | # include "boost/mpl/transform.hpp" |
---|
29 | #else |
---|
30 | # include "boost/preprocessor/cat.hpp" |
---|
31 | # include "boost/preprocessor/repeat.hpp" |
---|
32 | #endif |
---|
33 | |
---|
34 | #include "boost/mpl/bool.hpp" |
---|
35 | #include "boost/mpl/is_sequence.hpp" |
---|
36 | #include "boost/variant/variant.hpp" |
---|
37 | |
---|
38 | namespace boost { |
---|
39 | |
---|
40 | namespace 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 | |
---|
50 | template < |
---|
51 | BOOST_VARIANT_ENUM_PARAMS(typename T) |
---|
52 | , typename RecursiveVariant |
---|
53 | BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity) |
---|
54 | > |
---|
55 | struct 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 | |
---|
71 | template < |
---|
72 | BOOST_VARIANT_ENUM_PARAMS(typename T) |
---|
73 | , typename RecursiveVariant |
---|
74 | BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity) |
---|
75 | > |
---|
76 | struct substitute< |
---|
77 | ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) > |
---|
78 | , RecursiveVariant |
---|
79 | , ::boost::recursive_variant_ |
---|
80 | BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity) |
---|
81 | > |
---|
82 | { |
---|
83 | |
---|
84 | #if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT) |
---|
85 | |
---|
86 | private: // helpers, for metafunction result (below) |
---|
87 | |
---|
88 | typedef typename mpl::eval_if< |
---|
89 | ::boost::detail::variant::is_over_sequence<T0> |
---|
90 | , mpl::identity< T0 > |
---|
91 | , make_variant_list< BOOST_VARIANT_ENUM_PARAMS(T) > |
---|
92 | >::type initial_types; |
---|
93 | |
---|
94 | typedef typename mpl::transform< |
---|
95 | initial_types |
---|
96 | , mpl::protect< quoted_enable_recursive<RecursiveVariant,mpl::true_> > |
---|
97 | >::type types; |
---|
98 | |
---|
99 | public: // metafunction result |
---|
100 | |
---|
101 | typedef ::boost::variant< types > type; |
---|
102 | |
---|
103 | #else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT) |
---|
104 | |
---|
105 | private: // helpers, for metafunction result (below) |
---|
106 | |
---|
107 | #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \ |
---|
108 | typedef typename enable_recursive< \ |
---|
109 | BOOST_PP_CAT(T,N) \ |
---|
110 | , RecursiveVariant \ |
---|
111 | , mpl::true_ \ |
---|
112 | >::type BOOST_PP_CAT(wknd_T,N); \ |
---|
113 | /**/ |
---|
114 | |
---|
115 | BOOST_PP_REPEAT( |
---|
116 | BOOST_VARIANT_LIMIT_TYPES |
---|
117 | , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS |
---|
118 | , _ |
---|
119 | ) |
---|
120 | |
---|
121 | #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS |
---|
122 | |
---|
123 | public: // metafunction result |
---|
124 | |
---|
125 | typedef ::boost::variant< BOOST_VARIANT_ENUM_PARAMS(wknd_T) > type; |
---|
126 | |
---|
127 | #endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround |
---|
128 | |
---|
129 | }; |
---|
130 | |
---|
131 | #else // defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) |
---|
132 | |
---|
133 | // |
---|
134 | // no specializations: embedded variants unsupported on these compilers! |
---|
135 | // |
---|
136 | |
---|
137 | #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) |
---|
138 | |
---|
139 | }} // namespace detail::variant |
---|
140 | |
---|
141 | /////////////////////////////////////////////////////////////////////////////// |
---|
142 | // metafunction make_recursive_variant |
---|
143 | // |
---|
144 | // See docs and boost/variant/variant_fwd.hpp for more information. |
---|
145 | // |
---|
146 | template < BOOST_VARIANT_ENUM_PARAMS(typename T) > |
---|
147 | struct make_recursive_variant |
---|
148 | { |
---|
149 | public: // metafunction result |
---|
150 | |
---|
151 | typedef boost::variant< |
---|
152 | detail::variant::recursive_flag< T0 > |
---|
153 | , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) |
---|
154 | > type; |
---|
155 | |
---|
156 | }; |
---|
157 | |
---|
158 | /////////////////////////////////////////////////////////////////////////////// |
---|
159 | // metafunction make_recursive_variant_over |
---|
160 | // |
---|
161 | // See docs and boost/variant/variant_fwd.hpp for more information. |
---|
162 | // |
---|
163 | template <typename Types> |
---|
164 | struct make_recursive_variant_over |
---|
165 | { |
---|
166 | private: // precondition assertions |
---|
167 | |
---|
168 | #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) |
---|
169 | BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value )); |
---|
170 | #endif |
---|
171 | |
---|
172 | public: // metafunction result |
---|
173 | |
---|
174 | typedef typename make_recursive_variant< |
---|
175 | detail::variant::over_sequence< Types > |
---|
176 | >::type type; |
---|
177 | |
---|
178 | }; |
---|
179 | |
---|
180 | } // namespace boost |
---|
181 | |
---|
182 | #endif // BOOST_VARIANT_RECURSIVE_VARIANT_HPP |
---|