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