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
179namespace boost {
180
181namespace 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
195struct void_;
196
197template <typename T>
198struct convert_void
199{
200 typedef T type;
201};
202
203template <>
204struct 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
233BOOST_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//
293template < 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//
301template < 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//
322template <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//
329template <typename Types> struct make_recursive_variant_over;
330
331} // namespace boost
332
333#endif // BOOST_VARIANT_VARIANT_FWD_HPP
334

source code of boost/boost/variant/variant_fwd.hpp