|
1 //----------------------------------------------------------------------------- |
|
2 // boost variant/variant_fwd.hpp header file |
|
3 // See http://www.boost.org for updates, documentation, and revision history. |
|
4 //----------------------------------------------------------------------------- |
|
5 // |
|
6 // Copyright (c) 2003 |
|
7 // Eric Friedman, Itay Maman |
|
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_VARIANT_FWD_HPP |
|
14 #define BOOST_VARIANT_VARIANT_FWD_HPP |
|
15 |
|
16 #include "boost/variant/detail/config.hpp" |
|
17 |
|
18 #include "boost/blank_fwd.hpp" |
|
19 #include "boost/mpl/arg.hpp" |
|
20 #include "boost/mpl/limits/arity.hpp" |
|
21 #include "boost/mpl/aux_/na.hpp" |
|
22 #include "boost/preprocessor/cat.hpp" |
|
23 #include "boost/preprocessor/enum.hpp" |
|
24 #include "boost/preprocessor/enum_params.hpp" |
|
25 #include "boost/preprocessor/enum_shifted_params.hpp" |
|
26 #include "boost/preprocessor/repeat.hpp" |
|
27 |
|
28 /////////////////////////////////////////////////////////////////////////////// |
|
29 // macro BOOST_VARIANT_LIMIT_TYPES |
|
30 // |
|
31 // Implementation-defined preprocessor symbol describing the actual |
|
32 // length of variant's pseudo-variadic template parameter list. |
|
33 // |
|
34 #include "boost/mpl/limits/list.hpp" |
|
35 #define BOOST_VARIANT_LIMIT_TYPES \ |
|
36 BOOST_MPL_LIMIT_LIST_SIZE |
|
37 |
|
38 /////////////////////////////////////////////////////////////////////////////// |
|
39 // macro BOOST_VARIANT_NO_REFERENCE_SUPPORT |
|
40 // |
|
41 // Defined if variant does not support references as bounded types. |
|
42 // |
|
43 #if defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING) \ |
|
44 && !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND) \ |
|
45 && !defined(BOOST_VARIANT_NO_REFERENCE_SUPPORT) |
|
46 # define BOOST_VARIANT_NO_REFERENCE_SUPPORT |
|
47 #endif |
|
48 |
|
49 /////////////////////////////////////////////////////////////////////////////// |
|
50 // macro BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT |
|
51 // |
|
52 // Defined if variant does not support make_variant_over (see below). |
|
53 // |
|
54 #if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) |
|
55 # define BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT |
|
56 #endif |
|
57 |
|
58 /////////////////////////////////////////////////////////////////////////////// |
|
59 // macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT |
|
60 // |
|
61 // Defined if make_recursive_variant cannot be supported as documented. |
|
62 // |
|
63 // Note: Currently, MPL lambda facility is used as workaround if defined, and |
|
64 // so only types declared w/ MPL lambda workarounds will work. |
|
65 // |
|
66 |
|
67 #include "boost/variant/detail/substitute_fwd.hpp" |
|
68 |
|
69 #if defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) \ |
|
70 && !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT) |
|
71 # define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT |
|
72 #endif |
|
73 |
|
74 /////////////////////////////////////////////////////////////////////////////// |
|
75 // macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY |
|
76 // |
|
77 // Exposes maximum allowed arity of class templates with recursive_variant |
|
78 // arguments. That is, |
|
79 // make_recursive_variant< ..., T<[1], recursive_variant_, ... [N]> >. |
|
80 // |
|
81 #include "boost/mpl/limits/arity.hpp" |
|
82 #define BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY \ |
|
83 BOOST_MPL_LIMIT_METAFUNCTION_ARITY |
|
84 |
|
85 /////////////////////////////////////////////////////////////////////////////// |
|
86 // macro BOOST_VARIANT_ENUM_PARAMS |
|
87 // |
|
88 // Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES params. |
|
89 // |
|
90 // Rationale: Cleaner, simpler code for clients of variant library. |
|
91 // |
|
92 #define BOOST_VARIANT_ENUM_PARAMS( param ) \ |
|
93 BOOST_PP_ENUM_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param) |
|
94 |
|
95 /////////////////////////////////////////////////////////////////////////////// |
|
96 // macro BOOST_VARIANT_ENUM_SHIFTED_PARAMS |
|
97 // |
|
98 // Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES-1 params. |
|
99 // |
|
100 #define BOOST_VARIANT_ENUM_SHIFTED_PARAMS( param ) \ |
|
101 BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param) |
|
102 |
|
103 |
|
104 namespace boost { |
|
105 |
|
106 namespace detail { namespace variant { |
|
107 |
|
108 /////////////////////////////////////////////////////////////////////////////// |
|
109 // (detail) class void_ and class template convert_void |
|
110 // |
|
111 // Provides the mechanism by which void(NN) types are converted to |
|
112 // mpl::void_ (and thus can be passed to mpl::list). |
|
113 // |
|
114 // Rationale: This is particularly needed for the using-declarations |
|
115 // workaround (below), but also to avoid associating mpl namespace with |
|
116 // variant in argument dependent lookups (which used to happen because of |
|
117 // defaulting of template parameters to mpl::void_). |
|
118 // |
|
119 |
|
120 struct void_; |
|
121 |
|
122 template <typename T> |
|
123 struct convert_void |
|
124 { |
|
125 typedef T type; |
|
126 }; |
|
127 |
|
128 template <> |
|
129 struct convert_void< void_ > |
|
130 { |
|
131 typedef mpl::na type; |
|
132 }; |
|
133 |
|
134 /////////////////////////////////////////////////////////////////////////////// |
|
135 // (workaround) BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE |
|
136 // |
|
137 // Needed to work around compilers that don't support using-declaration |
|
138 // overloads. (See the variant::initializer workarounds below.) |
|
139 // |
|
140 |
|
141 #if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) |
|
142 |
|
143 // (detail) tags voidNN -- NN defined on [0, BOOST_VARIANT_LIMIT_TYPES) |
|
144 // |
|
145 // Defines void types that are each unique and specializations of |
|
146 // convert_void that yields mpl::na for each voidNN type. |
|
147 // |
|
148 |
|
149 #define BOOST_VARIANT_DETAIL_DEFINE_VOID_N(z,N,_) \ |
|
150 struct BOOST_PP_CAT(void,N); \ |
|
151 \ |
|
152 template <> \ |
|
153 struct convert_void< BOOST_PP_CAT(void,N) > \ |
|
154 { \ |
|
155 typedef mpl::na type; \ |
|
156 }; \ |
|
157 /**/ |
|
158 |
|
159 BOOST_PP_REPEAT( |
|
160 BOOST_VARIANT_LIMIT_TYPES |
|
161 , BOOST_VARIANT_DETAIL_DEFINE_VOID_N |
|
162 , _ |
|
163 ) |
|
164 |
|
165 #undef BOOST_VARIANT_DETAIL_DEFINE_VOID_N |
|
166 |
|
167 #endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround |
|
168 |
|
169 }} // namespace detail::variant |
|
170 |
|
171 /////////////////////////////////////////////////////////////////////////////// |
|
172 // (detail) macro BOOST_VARIANT_AUX_DECLARE_PARAM |
|
173 // |
|
174 // Template parameter list for variant and recursive_variant declarations. |
|
175 // |
|
176 |
|
177 #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) |
|
178 |
|
179 # define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \ |
|
180 typename BOOST_PP_CAT(T,N) = detail::variant::void_ \ |
|
181 /**/ |
|
182 |
|
183 #else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) |
|
184 |
|
185 # define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \ |
|
186 typename BOOST_PP_CAT(T,N) = BOOST_PP_CAT(detail::variant::void,N) \ |
|
187 /**/ |
|
188 |
|
189 #endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround |
|
190 |
|
191 #define BOOST_VARIANT_AUX_DECLARE_PARAMS \ |
|
192 BOOST_PP_ENUM( \ |
|
193 BOOST_VARIANT_LIMIT_TYPES \ |
|
194 , BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL \ |
|
195 , T \ |
|
196 ) \ |
|
197 /**/ |
|
198 |
|
199 /////////////////////////////////////////////////////////////////////////////// |
|
200 // class template variant (concept inspired by Andrei Alexandrescu) |
|
201 // |
|
202 // Efficient, type-safe bounded discriminated union. |
|
203 // |
|
204 // Preconditions: |
|
205 // - Each type must be unique. |
|
206 // - No type may be const-qualified. |
|
207 // |
|
208 // Proper declaration form: |
|
209 // variant<types> (where types is a type-sequence) |
|
210 // or |
|
211 // variant<T0,T1,...,Tn> (where T0 is NOT a type-sequence) |
|
212 // |
|
213 template < BOOST_VARIANT_AUX_DECLARE_PARAMS > class variant; |
|
214 |
|
215 /////////////////////////////////////////////////////////////////////////////// |
|
216 // metafunction make_recursive_variant |
|
217 // |
|
218 // Exposes a boost::variant with recursive_variant_ tags (below) substituted |
|
219 // with the variant itself (wrapped as needed with boost::recursive_wrapper). |
|
220 // |
|
221 template < BOOST_VARIANT_AUX_DECLARE_PARAMS > struct make_recursive_variant; |
|
222 |
|
223 #undef BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL |
|
224 #undef BOOST_VARIANT_AUX_DECLARE_PARAMS |
|
225 |
|
226 /////////////////////////////////////////////////////////////////////////////// |
|
227 // type recursive_variant_ |
|
228 // |
|
229 // Tag type indicates where recursive variant substitution should occur. |
|
230 // |
|
231 #if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT) |
|
232 struct recursive_variant_; |
|
233 #else |
|
234 typedef mpl::arg<1> recursive_variant_; |
|
235 #endif |
|
236 |
|
237 /////////////////////////////////////////////////////////////////////////////// |
|
238 // metafunction make_variant_over |
|
239 // |
|
240 // Result is a variant w/ types of the specified type sequence. |
|
241 // |
|
242 template <typename Types> struct make_variant_over; |
|
243 |
|
244 /////////////////////////////////////////////////////////////////////////////// |
|
245 // metafunction make_recursive_variant_over |
|
246 // |
|
247 // Result is a recursive variant w/ types of the specified type sequence. |
|
248 // |
|
249 template <typename Types> struct make_recursive_variant_over; |
|
250 |
|
251 } // namespace boost |
|
252 |
|
253 #endif // BOOST_VARIANT_VARIANT_FWD_HPP |