]> git.lyx.org Git - features.git/blob - 3rdparty/boost/boost/variant/variant_fwd.hpp
Replace Boost.Signals with Boost.Signals2
[features.git] / 3rdparty / boost / boost / variant / variant_fwd.hpp
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 Eric Friedman, Itay Maman
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_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_NO_REFERENCE_SUPPORT
30 //
31 // Defined if variant does not support references as bounded types. 
32 //
33 #if defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING) \
34  && !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND) \
35  && !defined(BOOST_VARIANT_NO_REFERENCE_SUPPORT)
36 #   define BOOST_VARIANT_NO_REFERENCE_SUPPORT
37 #endif
38
39 ///////////////////////////////////////////////////////////////////////////////
40 // macro BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
41 //
42 // Defined if variant does not support make_variant_over (see below). 
43 //
44 #if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
45 #   define BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
46 #endif
47
48 ///////////////////////////////////////////////////////////////////////////////
49 // macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
50 //
51 // Defined if make_recursive_variant cannot be supported as documented.
52 //
53 // Note: Currently, MPL lambda facility is used as workaround if defined, and
54 // so only types declared w/ MPL lambda workarounds will work.
55 //
56
57 #include "boost/variant/detail/substitute_fwd.hpp"
58
59 #if defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) \
60   && !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
61 #   define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
62 #endif
63
64
65 ///////////////////////////////////////////////////////////////////////////////
66 // macro BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
67 //
68
69 /* 
70     GCC before 4.0 had no variadic tempaltes; 
71     GCC 4.6 has incomplete implementation of variadic templates.
72
73     MSVC2013 has variadic templates, but they have issues.
74
75     NOTE: Clang compiler defines __GNUC__
76 */
77 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
78   || (!defined(__clang__) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) \
79   || (defined(_MSC_VER) && (_MSC_VER <= 1900)) \
80   || defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) \
81   || defined (BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
82
83 #ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
84 #   define BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
85 #endif
86
87 #endif
88
89 #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
90 #include <boost/preprocessor/seq/size.hpp>
91
92 #define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_class class)(
93 #define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_typename typename)(
94
95 #define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_class class...
96 #define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_typename typename...
97
98 #define ARGS_VARIADER_1(x) x ## N...
99 #define ARGS_VARIADER_2(x) BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_ ## x ## N
100
101 #define BOOST_VARIANT_MAKE_VARIADIC(sequence, x)        BOOST_VARIANT_MAKE_VARIADIC_I(BOOST_PP_SEQ_SIZE(sequence), x)
102 #define BOOST_VARIANT_MAKE_VARIADIC_I(argscount, x)     BOOST_VARIANT_MAKE_VARIADIC_II(argscount, x)
103 #define BOOST_VARIANT_MAKE_VARIADIC_II(argscount, orig) ARGS_VARIADER_ ## argscount(orig)
104
105 ///////////////////////////////////////////////////////////////////////////////
106 // BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS
107 //
108 // Convenience macro for enumeration of variant params.
109 // When variadic templates are available expands:
110 //      BOOST_VARIANT_ENUM_PARAMS(class Something)      => class Something0, class... SomethingN
111 //      BOOST_VARIANT_ENUM_PARAMS(typename Something)   => typename Something0, typename... SomethingN
112 //      BOOST_VARIANT_ENUM_PARAMS(Something)            => Something0, SomethingN...
113 //      BOOST_VARIANT_ENUM_PARAMS(Something)            => Something0, SomethingN...
114 //      BOOST_VARIANT_ENUM_SHIFTED_PARAMS(class Something)      => class... SomethingN
115 //      BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename Something)   => typename... SomethingN
116 //      BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something)            => SomethingN...
117 //      BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something)            => SomethingN...
118 //
119 // Rationale: Cleaner, simpler code for clients of variant library. Minimal 
120 // code modifications to move from C++03 to C++11.
121 //
122 // With BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES defined
123 // will be used BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS from below `#else`
124 //
125
126 #define BOOST_VARIANT_ENUM_PARAMS(x) \
127     x ## 0, \
128     BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
129     /**/
130
131 #define BOOST_VARIANT_ENUM_SHIFTED_PARAMS(x) \
132     BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
133     /**/
134
135 #else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
136
137 ///////////////////////////////////////////////////////////////////////////////
138 // macro BOOST_VARIANT_LIMIT_TYPES
139 //
140 // Implementation-defined preprocessor symbol describing the actual
141 // length of variant's pseudo-variadic template parameter list.
142 //
143 #include "boost/mpl/limits/list.hpp"
144 #define BOOST_VARIANT_LIMIT_TYPES \
145     BOOST_MPL_LIMIT_LIST_SIZE
146
147 ///////////////////////////////////////////////////////////////////////////////
148 // macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY
149 //
150 // Exposes maximum allowed arity of class templates with recursive_variant
151 // arguments. That is,
152 //   make_recursive_variant< ..., T<[1], recursive_variant_, ... [N]> >.
153 //
154 #include "boost/mpl/limits/arity.hpp"
155 #define BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY \
156     BOOST_MPL_LIMIT_METAFUNCTION_ARITY
157
158 ///////////////////////////////////////////////////////////////////////////////
159 // macro BOOST_VARIANT_ENUM_PARAMS
160 //
161 // Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES params.
162 //
163 // Rationale: Cleaner, simpler code for clients of variant library.
164 //
165 #define BOOST_VARIANT_ENUM_PARAMS( param )  \
166     BOOST_PP_ENUM_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
167
168 ///////////////////////////////////////////////////////////////////////////////
169 // macro BOOST_VARIANT_ENUM_SHIFTED_PARAMS
170 //
171 // Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES-1 params.
172 //
173 #define BOOST_VARIANT_ENUM_SHIFTED_PARAMS( param )  \
174     BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
175
176 #endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
177
178
179 namespace boost {
180
181 namespace detail { namespace variant {
182
183 ///////////////////////////////////////////////////////////////////////////////
184 // (detail) class void_ and class template convert_void
185 // 
186 // Provides the mechanism by which void(NN) types are converted to
187 // mpl::void_ (and thus can be passed to mpl::list).
188 //
189 // Rationale: This is particularly needed for the using-declarations
190 // workaround (below), but also to avoid associating mpl namespace with
191 // variant in argument dependent lookups (which used to happen because of
192 // defaulting of template parameters to mpl::void_).
193 //
194
195 struct void_;
196
197 template <typename T>
198 struct convert_void
199 {
200     typedef T type;
201 };
202
203 template <>
204 struct convert_void< void_ >
205 {
206     typedef mpl::na type;
207 };
208
209 ///////////////////////////////////////////////////////////////////////////////
210 // (workaround) BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE
211 //
212 // Needed to work around compilers that don't support using-declaration
213 // overloads. (See the variant::initializer workarounds below.)
214 //
215
216 #if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
217 // (detail) tags voidNN -- NN defined on [0, BOOST_VARIANT_LIMIT_TYPES)
218 //
219 // Defines void types that are each unique and specializations of
220 // convert_void that yields mpl::na for each voidNN type.
221 //
222
223 #define BOOST_VARIANT_DETAIL_DEFINE_VOID_N(z,N,_)          \
224     struct BOOST_PP_CAT(void,N);                           \
225                                                            \
226     template <>                                            \
227     struct convert_void< BOOST_PP_CAT(void,N) >            \
228     {                                                      \
229         typedef mpl::na type;                              \
230     };                                                     \
231     /**/
232
233 BOOST_PP_REPEAT(
234       BOOST_VARIANT_LIMIT_TYPES
235     , BOOST_VARIANT_DETAIL_DEFINE_VOID_N
236     , _
237     )
238
239 #undef BOOST_VARIANT_DETAIL_DEFINE_VOID_N
240
241 #endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
242
243 }} // namespace detail::variant
244
245 #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
246 #   define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T)
247 #else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
248
249 ///////////////////////////////////////////////////////////////////////////////
250 // (detail) macro BOOST_VARIANT_AUX_DECLARE_PARAM
251 //
252 // Template parameter list for variant and recursive_variant declarations.
253 //
254
255 #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
256
257 #   define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \
258     typename BOOST_PP_CAT(T,N) = detail::variant::void_ \
259     /**/
260
261 #else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
262
263 #   define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \
264     typename BOOST_PP_CAT(T,N) = BOOST_PP_CAT(detail::variant::void,N) \
265     /**/
266
267 #endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
268
269 #define BOOST_VARIANT_AUX_DECLARE_PARAMS \
270     BOOST_PP_ENUM( \
271           BOOST_VARIANT_LIMIT_TYPES \
272         , BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL \
273         , T \
274         ) \
275     /**/
276
277 #endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
278
279 ///////////////////////////////////////////////////////////////////////////////
280 // class template variant (concept inspired by Andrei Alexandrescu)
281 //
282 // Efficient, type-safe bounded discriminated union.
283 //
284 // Preconditions:
285 //  - Each type must be unique.
286 //  - No type may be const-qualified.
287 //
288 // Proper declaration form:
289 //   variant<types>    (where types is a type-sequence)
290 // or
291 //   variant<T0,T1,...,Tn>  (where T0 is NOT a type-sequence)
292 //
293 template < BOOST_VARIANT_AUX_DECLARE_PARAMS > class variant;
294
295 ///////////////////////////////////////////////////////////////////////////////
296 // metafunction make_recursive_variant
297 //
298 // Exposes a boost::variant with recursive_variant_ tags (below) substituted
299 // with the variant itself (wrapped as needed with boost::recursive_wrapper).
300 //
301 template < BOOST_VARIANT_AUX_DECLARE_PARAMS > struct make_recursive_variant;
302
303 #undef BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL
304 #undef BOOST_VARIANT_AUX_DECLARE_PARAMS
305
306 ///////////////////////////////////////////////////////////////////////////////
307 // type recursive_variant_
308 //
309 // Tag type indicates where recursive variant substitution should occur.
310 //
311 #if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
312     struct recursive_variant_ {};
313 #else
314     typedef mpl::arg<1> recursive_variant_;
315 #endif
316
317 ///////////////////////////////////////////////////////////////////////////////
318 // metafunction make_variant_over
319 //
320 // Result is a variant w/ types of the specified type sequence.
321 //
322 template <typename Types> struct make_variant_over;
323
324 ///////////////////////////////////////////////////////////////////////////////
325 // metafunction make_recursive_variant_over
326 //
327 // Result is a recursive variant w/ types of the specified type sequence.
328 //
329 template <typename Types> struct make_recursive_variant_over;
330
331 } // namespace boost
332
333 #endif // BOOST_VARIANT_VARIANT_FWD_HPP