scc 2025.09
SystemC components library
variant.hpp
1// Copyright 2016-2018 by Martin Moene
2//
3// https://github.com/martinmoene/variant-lite
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8#pragma once
9
10#ifndef NONSTD_VARIANT_LITE_HPP
11#define NONSTD_VARIANT_LITE_HPP
12
13#define variant_lite_MAJOR 2
14#define variant_lite_MINOR 0
15#define variant_lite_PATCH 0
16
17#define variant_lite_VERSION \
18 variant_STRINGIFY(variant_lite_MAJOR) "." variant_STRINGIFY(variant_lite_MINOR) "." variant_STRINGIFY(variant_lite_PATCH)
19
20#define variant_STRINGIFY(x) variant_STRINGIFY_(x)
21#define variant_STRINGIFY_(x) #x
22
23// variant-lite configuration:
24
25#define variant_VARIANT_DEFAULT 0
26#define variant_VARIANT_NONSTD 1
27#define variant_VARIANT_STD 2
28
29// tweak header support:
30
31#ifdef __has_include
32#if __has_include(<nonstd/variant.tweak.hpp>)
33#include <nonstd/variant.tweak.hpp>
34#endif
35#define variant_HAVE_TWEAK_HEADER 1
36#else
37#define variant_HAVE_TWEAK_HEADER 0
38// # pragma message("variant.hpp: Note: Tweak header not supported.")
39#endif
40
41// variant selection and configuration:
42
43#ifndef variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
44#define variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO 0
45#endif
46
47#ifndef variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
48#define variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO 0
49#endif
50
51// Control presence of exception handling (try and auto discover):
52
53#ifndef variant_CONFIG_NO_EXCEPTIONS
54#if defined(_MSC_VER)
55#include <cstddef> // for _HAS_EXCEPTIONS
56#endif
57#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
58#define variant_CONFIG_NO_EXCEPTIONS 0
59#else
60#define variant_CONFIG_NO_EXCEPTIONS 1
61#endif
62#endif
63
64// C++ language version detection (C++23 is speculative):
65// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
66
67#ifndef variant_CPLUSPLUS
68#if defined(_MSVC_LANG) && !defined(__clang__)
69#define variant_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
70#else
71#define variant_CPLUSPLUS __cplusplus
72#endif
73#endif
74
75#define variant_CPP98_OR_GREATER (variant_CPLUSPLUS >= 199711L)
76#define variant_CPP11_OR_GREATER (variant_CPLUSPLUS >= 201103L)
77#define variant_CPP11_OR_GREATER_ (variant_CPLUSPLUS >= 201103L)
78#define variant_CPP14_OR_GREATER (variant_CPLUSPLUS >= 201402L)
79#define variant_CPP17_OR_GREATER (variant_CPLUSPLUS >= 201703L)
80#define variant_CPP20_OR_GREATER (variant_CPLUSPLUS >= 202002L)
81#define variant_CPP23_OR_GREATER (variant_CPLUSPLUS >= 202300L)
82
83// Use C++17 std::variant if available and requested:
84
85#if variant_CPP17_OR_GREATER && defined(__has_include)
86#if __has_include(<variant> )
87#define variant_HAVE_STD_VARIANT 1
88#else
89#define variant_HAVE_STD_VARIANT 0
90#endif
91#else
92#define variant_HAVE_STD_VARIANT 0
93#endif
94
95#if !defined(variant_CONFIG_SELECT_VARIANT)
96#define variant_CONFIG_SELECT_VARIANT (variant_HAVE_STD_VARIANT ? variant_VARIANT_STD : variant_VARIANT_NONSTD)
97#endif
98
99#define variant_USES_STD_VARIANT \
100 ((variant_CONFIG_SELECT_VARIANT == variant_VARIANT_STD) || \
101 ((variant_CONFIG_SELECT_VARIANT == variant_VARIANT_DEFAULT) && variant_HAVE_STD_VARIANT))
102
103//
104// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite:
105//
106
107#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
108#define nonstd_lite_HAVE_IN_PLACE_TYPES 1
109
110// C++17 std::in_place in <utility>:
111
112#if variant_CPP17_OR_GREATER
113
114#include <utility>
115
116namespace nonstd {
117
118using std::in_place;
119using std::in_place_index;
120using std::in_place_index_t;
121using std::in_place_t;
122using std::in_place_type;
123using std::in_place_type_t;
124
125#define nonstd_lite_in_place_t(T) std::in_place_t
126#define nonstd_lite_in_place_type_t(T) std::in_place_type_t<T>
127#define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
128
129#define nonstd_lite_in_place(T) \
130 std::in_place_t {}
131#define nonstd_lite_in_place_type(T) \
132 std::in_place_type_t<T> {}
133#define nonstd_lite_in_place_index(K) \
134 std::in_place_index_t<K> {}
135
136} // namespace nonstd
137
138#else // variant_CPP17_OR_GREATER
139
140#include <cstddef>
141
142namespace nonstd {
143namespace detail {
144
145template <class T> struct in_place_type_tag {};
146
147template <std::size_t K> struct in_place_index_tag {};
148
149} // namespace detail
150
151struct in_place_t {};
152
153template <class T> inline in_place_t in_place(detail::in_place_type_tag<T> = detail::in_place_type_tag<T>()) { return in_place_t(); }
154
155template <std::size_t K> inline in_place_t in_place(detail::in_place_index_tag<K> = detail::in_place_index_tag<K>()) {
156 return in_place_t();
157}
158
159template <class T> inline in_place_t in_place_type(detail::in_place_type_tag<T> = detail::in_place_type_tag<T>()) { return in_place_t(); }
160
161template <std::size_t K> inline in_place_t in_place_index(detail::in_place_index_tag<K> = detail::in_place_index_tag<K>()) {
162 return in_place_t();
163}
164
165// mimic templated typedef:
166
167#define nonstd_lite_in_place_t(T) nonstd::in_place_t (&)(nonstd::detail::in_place_type_tag<T>)
168#define nonstd_lite_in_place_type_t(T) nonstd::in_place_t (&)(nonstd::detail::in_place_type_tag<T>)
169#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t (&)(nonstd::detail::in_place_index_tag<K>)
170
171#define nonstd_lite_in_place(T) nonstd::in_place_type<T>
172#define nonstd_lite_in_place_type(T) nonstd::in_place_type<T>
173#define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
174
175} // namespace nonstd
176
177#endif // variant_CPP17_OR_GREATER
178#endif // nonstd_lite_HAVE_IN_PLACE_TYPES
179
180// in_place_index-like disambiguation tag identical for all C++ versions:
181
182namespace nonstd {
183namespace variants {
184namespace detail {
185
186template <std::size_t K> struct index_tag_t {};
187
188template <std::size_t K> inline void index_tag(index_tag_t<K> = index_tag_t<K>()) {}
189
190#define variant_index_tag_t(K) void (&)(nonstd::variants::detail::index_tag_t<K>)
191#define variant_index_tag(K) nonstd::variants::detail::index_tag<K>
192
193} // namespace detail
194} // namespace variants
195} // namespace nonstd
196
197//
198// Use C++17 std::variant:
199//
200
201#if variant_USES_STD_VARIANT
202
203#include <functional> // std::hash<>
204#include <variant>
205
206#if !variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
207#define variant_size_V(T) nonstd::variant_size<T>::value
208#endif
209
210#if !variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
211#define variant_alternative_T(K, T) typename nonstd::variant_alternative<K, T>::type
212#endif
213
214namespace nonstd {
215
216using std::bad_variant_access;
217using std::hash;
218using std::monostate;
219using std::variant;
220using std::variant_alternative;
221using std::variant_alternative_t;
222using std::variant_size;
223using std::variant_size_v;
224
225using std::get;
226using std::get_if;
227using std::holds_alternative;
228using std::visit;
229using std::operator==;
230using std::operator!=;
231using std::operator<;
232using std::operator<=;
233using std::operator>;
234using std::operator>=;
235using std::swap;
236
237constexpr auto variant_npos = std::variant_npos;
238} // namespace nonstd
239
240#else // variant_USES_STD_VARIANT
241
242#include <cstddef>
243#include <limits>
244#include <new>
245#include <utility>
246
247#if variant_CONFIG_NO_EXCEPTIONS
248#include <cassert>
249#else
250#include <stdexcept>
251#endif
252
253// variant-lite type and visitor argument count configuration (script/generate_header.py):
254
255#define variant_CONFIG_MAX_TYPE_COUNT 16
256#define variant_CONFIG_MAX_VISITOR_ARG_COUNT 5
257
258// variant-lite alignment configuration:
259
260#ifndef variant_CONFIG_MAX_ALIGN_HACK
261#define variant_CONFIG_MAX_ALIGN_HACK 0
262#endif
263
264#ifndef variant_CONFIG_ALIGN_AS
265// no default, used in #if defined()
266#endif
267
268#ifndef variant_CONFIG_ALIGN_AS_FALLBACK
269#define variant_CONFIG_ALIGN_AS_FALLBACK double
270#endif
271
272// half-open range [lo..hi):
273#define variant_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi))
274
275// Compiler versions:
276//
277// MSVC++ 6.0 _MSC_VER == 1200 variant_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
278// MSVC++ 7.0 _MSC_VER == 1300 variant_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
279// MSVC++ 7.1 _MSC_VER == 1310 variant_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
280// MSVC++ 8.0 _MSC_VER == 1400 variant_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
281// MSVC++ 9.0 _MSC_VER == 1500 variant_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
282// MSVC++ 10.0 _MSC_VER == 1600 variant_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
283// MSVC++ 11.0 _MSC_VER == 1700 variant_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
284// MSVC++ 12.0 _MSC_VER == 1800 variant_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
285// MSVC++ 14.0 _MSC_VER == 1900 variant_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
286// MSVC++ 14.1 _MSC_VER >= 1910 variant_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
287// MSVC++ 14.2 _MSC_VER >= 1920 variant_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
288
289#if defined(_MSC_VER) && !defined(__clang__)
290#define variant_COMPILER_MSVC_VER (_MSC_VER)
291#define variant_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * (5 + (_MSC_VER < 1900)))
292#else
293#define variant_COMPILER_MSVC_VER 0
294#define variant_COMPILER_MSVC_VERSION 0
295#endif
296
297#define variant_COMPILER_VERSION(major, minor, patch) (10 * (10 * (major) + (minor)) + (patch))
298
299#if defined(__clang__)
300#define variant_COMPILER_CLANG_VERSION variant_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
301#else
302#define variant_COMPILER_CLANG_VERSION 0
303#endif
304
305#if defined(__GNUC__) && !defined(__clang__)
306#define variant_COMPILER_GNUC_VERSION variant_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
307#else
308#define variant_COMPILER_GNUC_VERSION 0
309#endif
310
311#if variant_BETWEEN(variant_COMPILER_MSVC_VER, 1300, 1900)
312#pragma warning(push)
313#pragma warning(disable : 4345) // initialization behavior changed
314#endif
315
316// Presence of language and library features:
317
318#define variant_HAVE(feature) (variant_HAVE_##feature)
319
320#ifdef _HAS_CPP0X
321#define variant_HAS_CPP0X _HAS_CPP0X
322#else
323#define variant_HAS_CPP0X 0
324#endif
325
326// Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
327
328#if variant_COMPILER_MSVC_VER >= 1900
329#undef variant_CPP11_OR_GREATER
330#define variant_CPP11_OR_GREATER 1
331#endif
332
333#define variant_CPP11_90 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1500)
334#define variant_CPP11_100 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1600)
335#define variant_CPP11_110 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1700)
336#define variant_CPP11_120 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1800)
337#define variant_CPP11_140 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1900)
338#define variant_CPP11_141 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1910)
339
340#define variant_CPP14_000 (variant_CPP14_OR_GREATER)
341#define variant_CPP17_000 (variant_CPP17_OR_GREATER)
342
343// Presence of C++11 language features:
344
345#define variant_HAVE_CONSTEXPR_11 variant_CPP11_140
346#define variant_HAVE_INITIALIZER_LIST variant_CPP11_120
347#define variant_HAVE_NOEXCEPT variant_CPP11_140
348#define variant_HAVE_NULLPTR variant_CPP11_100
349#define variant_HAVE_OVERRIDE variant_CPP11_140
350
351// Presence of C++14 language features:
352
353#define variant_HAVE_CONSTEXPR_14 variant_CPP14_000
354
355// Presence of C++17 language features:
356
357// no flag
358
359// Presence of C++ library features:
360
361#define variant_HAVE_CONDITIONAL variant_CPP11_120
362#define variant_HAVE_REMOVE_CV variant_CPP11_120
363#define variant_HAVE_STD_ADD_POINTER variant_CPP11_100
364#define variant_HAVE_TYPE_TRAITS variant_CPP11_90
365#define variant_HAVE_ENABLE_IF variant_CPP11_100
366#define variant_HAVE_IS_SAME variant_CPP11_100
367
368#define variant_HAVE_TR1_TYPE_TRAITS (!!variant_COMPILER_GNUC_VERSION)
369#define variant_HAVE_TR1_ADD_POINTER (!!variant_COMPILER_GNUC_VERSION || variant_CPP11_90)
370
371// C++ feature usage:
372
373#if variant_HAVE_CONSTEXPR_11
374#define variant_constexpr constexpr
375#else
376#define variant_constexpr /*constexpr*/
377#endif
378
379#if variant_HAVE_CONSTEXPR_14
380#define variant_constexpr14 constexpr
381#else
382#define variant_constexpr14 /*constexpr*/
383#endif
384
385#if variant_HAVE_NOEXCEPT
386#define variant_noexcept noexcept
387#else
388#define variant_noexcept /*noexcept*/
389#endif
390
391#if variant_HAVE_NULLPTR
392#define variant_nullptr nullptr
393#else
394#define variant_nullptr NULL
395#endif
396
397#if variant_HAVE_OVERRIDE
398#define variant_override override
399#else
400#define variant_override /*override*/
401#endif
402
403// additional includes:
404
405#if variant_CPP11_OR_GREATER
406#include <functional> // std::hash
407#endif
408
409#if variant_HAVE_INITIALIZER_LIST
410#include <initializer_list>
411#endif
412
413#if variant_HAVE_TYPE_TRAITS
414#include <type_traits>
415#elif variant_HAVE_TR1_TYPE_TRAITS
416#include <tr1/type_traits>
417#endif
418
419//
420// variant:
421//
422
423namespace nonstd {
424namespace variants {
425
426// C++11 emulation:
427
428namespace std11 {
429
430#if variant_HAVE_STD_ADD_POINTER
431
432using std::add_pointer;
433
434#elif variant_HAVE_TR1_ADD_POINTER
435
436using std::tr1::add_pointer;
437
438#else
439
440template <class T> struct remove_reference { typedef T type; };
441template <class T> struct remove_reference<T&> { typedef T type; };
442
443template <class T> struct add_pointer { typedef typename remove_reference<T>::type* type; };
444
445#endif // variant_HAVE_STD_ADD_POINTER
446
447#if variant_HAVE_REMOVE_CV
448
449using std::remove_cv;
450
451#else
452
453template <class T> struct remove_const { typedef T type; };
454template <class T> struct remove_const<const T> { typedef T type; };
455
456template <class T> struct remove_volatile { typedef T type; };
457template <class T> struct remove_volatile<volatile T> { typedef T type; };
458
459template <class T> struct remove_cv { typedef typename remove_volatile<typename remove_const<T>::type>::type type; };
460
461#endif // variant_HAVE_REMOVE_CV
462
463#if variant_HAVE_CONDITIONAL
464
465using std::conditional;
466
467#else
468
469template <bool Cond, class Then, class Else> struct conditional;
470
471template <class Then, class Else> struct conditional<true, Then, Else> { typedef Then type; };
472
473template <class Then, class Else> struct conditional<false, Then, Else> { typedef Else type; };
474
475#endif // variant_HAVE_CONDITIONAL
476
477#if variant_HAVE_ENABLE_IF
478
479using std::enable_if;
480
481#else
482
483template <bool B, class T = void> struct enable_if {};
484
485template <class T> struct enable_if<true, T> { typedef T type; };
486
487#endif // variant_HAVE_ENABLE_IF
488
489#if variant_HAVE_IS_SAME
490
491using std::is_same;
492
493#else
494
495template <class T, class U> struct is_same {
496 enum V { value = 0 };
497};
498
499template <class T> struct is_same<T, T> {
500 enum V { value = 1 };
501};
502
503#endif // variant_HAVE_IS_SAME
504
505} // namespace std11
506
507// Method enabling
508
509#if variant_CPP11_OR_GREATER
510
511#define variant_REQUIRES_T(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0
512
513#define variant_REQUIRES_R(R, ...) typename std::enable_if<(__VA_ARGS__), R>::type
514
515#define variant_REQUIRES_A(...) , typename std::enable_if<(__VA_ARGS__), void*>::type = nullptr
516
517#endif // variant_CPP11_OR_GREATER
518
519#define variant_REQUIRES_0(...) template <bool B = (__VA_ARGS__), typename std11::enable_if<B, int>::type = 0>
520
521#define variant_REQUIRES_B(...) , bool B = (__VA_ARGS__), typename std11::enable_if<B, int>::type = 0
522
524
525namespace std17 {
526
527#if variant_CPP17_OR_GREATER
528
529using std::is_nothrow_swappable;
530using std::is_swappable;
531
532#elif variant_CPP11_OR_GREATER
533
534namespace detail {
535
536using std::swap;
537
538struct is_swappable {
539 template <typename T, typename = decltype(swap(std::declval<T&>(), std::declval<T&>()))> static std::true_type test(int);
540
541 template <typename> static std::false_type test(...);
542};
543
544struct is_nothrow_swappable {
545 // wrap noexcept(epr) in separate function as work-around for VC140 (VS2015):
546
547 template <typename T> static constexpr bool test() { return noexcept(swap(std::declval<T&>(), std::declval<T&>())); }
548
549 template <typename T> static auto test(int) -> std::integral_constant<bool, test<T>()> {}
550
551 template <typename> static std::false_type test(...);
552};
553
554} // namespace detail
555
556// is [nothow] swappable:
557
558template <typename T> struct is_swappable : decltype(detail::is_swappable::test<T>(0)) {};
559
560template <typename T> struct is_nothrow_swappable : decltype(detail::is_nothrow_swappable::test<T>(0)) {};
561
562#endif // variant_CPP17_OR_GREATER
563
564} // namespace std17
565
566// detail:
567
568namespace detail {
569
570// typelist:
571
572#define variant_TL1(T1) detail::typelist<T1, detail::nulltype>
573#define variant_TL2(T1, T2) detail::typelist<T1, variant_TL1(T2)>
574#define variant_TL3(T1, T2, T3) detail::typelist<T1, variant_TL2(T2, T3)>
575#define variant_TL4(T1, T2, T3, T4) detail::typelist<T1, variant_TL3(T2, T3, T4)>
576#define variant_TL5(T1, T2, T3, T4, T5) detail::typelist<T1, variant_TL4(T2, T3, T4, T5)>
577#define variant_TL6(T1, T2, T3, T4, T5, T6) detail::typelist<T1, variant_TL5(T2, T3, T4, T5, T6)>
578#define variant_TL7(T1, T2, T3, T4, T5, T6, T7) detail::typelist<T1, variant_TL6(T2, T3, T4, T5, T6, T7)>
579#define variant_TL8(T1, T2, T3, T4, T5, T6, T7, T8) detail::typelist<T1, variant_TL7(T2, T3, T4, T5, T6, T7, T8)>
580#define variant_TL9(T1, T2, T3, T4, T5, T6, T7, T8, T9) detail::typelist<T1, variant_TL8(T2, T3, T4, T5, T6, T7, T8, T9)>
581#define variant_TL10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) detail::typelist<T1, variant_TL9(T2, T3, T4, T5, T6, T7, T8, T9, T10)>
582#define variant_TL11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \
583 detail::typelist<T1, variant_TL10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)>
584#define variant_TL12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \
585 detail::typelist<T1, variant_TL11(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)>
586#define variant_TL13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \
587 detail::typelist<T1, variant_TL12(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)>
588#define variant_TL14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) \
589 detail::typelist<T1, variant_TL13(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)>
590#define variant_TL15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) \
591 detail::typelist<T1, variant_TL14(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)>
592#define variant_TL16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) \
593 detail::typelist<T1, variant_TL15(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)>
594
595// variant parameter unused type tags:
596
597template <class T> struct TX : T {
598 inline TX<T> operator+() const { return TX<T>(); }
599 inline TX<T> operator-() const { return TX<T>(); }
600
601 inline TX<T> operator!() const { return TX<T>(); }
602 inline TX<T> operator~() const { return TX<T>(); }
603
604 inline TX<T>* operator&() const { return variant_nullptr; }
605
606 template <class U> inline TX<T> operator*(U const&) const { return TX<T>(); }
607 template <class U> inline TX<T> operator/(U const&) const { return TX<T>(); }
608
609 template <class U> inline TX<T> operator%(U const&) const { return TX<T>(); }
610 template <class U> inline TX<T> operator+(U const&) const { return TX<T>(); }
611 template <class U> inline TX<T> operator-(U const&) const { return TX<T>(); }
612
613 template <class U> inline TX<T> operator<<(U const&) const { return TX<T>(); }
614 template <class U> inline TX<T> operator>>(U const&) const { return TX<T>(); }
615
616 inline bool operator==(T const&) const { return false; }
617 inline bool operator<(T const&) const { return false; }
618
619 template <class U> inline TX<T> operator&(U const&) const { return TX<T>(); }
620 template <class U> inline TX<T> operator|(U const&) const { return TX<T>(); }
621 template <class U> inline TX<T> operator^(U const&) const { return TX<T>(); }
622
623 template <class U> inline TX<T> operator&&(U const&) const { return TX<T>(); }
624 template <class U> inline TX<T> operator||(U const&) const { return TX<T>(); }
625};
626
627struct S0 {};
628typedef TX<S0> T0;
629struct S1 {};
630typedef TX<S1> T1;
631struct S2 {};
632typedef TX<S2> T2;
633struct S3 {};
634typedef TX<S3> T3;
635struct S4 {};
636typedef TX<S4> T4;
637struct S5 {};
638typedef TX<S5> T5;
639struct S6 {};
640typedef TX<S6> T6;
641struct S7 {};
642typedef TX<S7> T7;
643struct S8 {};
644typedef TX<S8> T8;
645struct S9 {};
646typedef TX<S9> T9;
647struct S10 {};
648typedef TX<S10> T10;
649struct S11 {};
650typedef TX<S11> T11;
651struct S12 {};
652typedef TX<S12> T12;
653struct S13 {};
654typedef TX<S13> T13;
655struct S14 {};
656typedef TX<S14> T14;
657struct S15 {};
658typedef TX<S15> T15;
659
660struct nulltype {};
661
662template <class Head, class Tail> struct typelist {
663 typedef Head head;
664 typedef Tail tail;
665};
666
667// typelist max element size:
668
669template <class List> struct typelist_max;
670
671template <> struct typelist_max<nulltype> {
672 enum V { value = 0 };
673 typedef void type;
674};
675
676template <class Head, class Tail> struct typelist_max<typelist<Head, Tail>> {
677private:
678 enum TV { tail_value = size_t(typelist_max<Tail>::value) };
679
680 typedef typename typelist_max<Tail>::type tail_type;
681
682public:
683 enum V { value = (sizeof(Head) > tail_value) ? sizeof(Head) : std::size_t(tail_value) };
684
685 typedef typename std11::conditional<(sizeof(Head) > tail_value), Head, tail_type>::type type;
686};
687
688#if variant_CPP11_OR_GREATER
689
690// typelist max alignof element type:
691
692template <class List> struct typelist_max_alignof;
693
694template <> struct typelist_max_alignof<nulltype> {
695 enum V { value = 0 };
696};
697
698template <class Head, class Tail> struct typelist_max_alignof<typelist<Head, Tail>> {
699private:
700 enum TV { tail_value = size_t(typelist_max_alignof<Tail>::value) };
701
702public:
703 enum V { value = (alignof(Head) > tail_value) ? alignof(Head) : std::size_t(tail_value) };
704};
705
706#endif
707
708// typelist size (length):
709
710template <class List> struct typelist_size {
711 enum V { value = 1 };
712};
713
714template <> struct typelist_size<T0> {
715 enum V { value = 0 };
716};
717template <> struct typelist_size<T1> {
718 enum V { value = 0 };
719};
720template <> struct typelist_size<T2> {
721 enum V { value = 0 };
722};
723template <> struct typelist_size<T3> {
724 enum V { value = 0 };
725};
726template <> struct typelist_size<T4> {
727 enum V { value = 0 };
728};
729template <> struct typelist_size<T5> {
730 enum V { value = 0 };
731};
732template <> struct typelist_size<T6> {
733 enum V { value = 0 };
734};
735template <> struct typelist_size<T7> {
736 enum V { value = 0 };
737};
738template <> struct typelist_size<T8> {
739 enum V { value = 0 };
740};
741template <> struct typelist_size<T9> {
742 enum V { value = 0 };
743};
744template <> struct typelist_size<T10> {
745 enum V { value = 0 };
746};
747template <> struct typelist_size<T11> {
748 enum V { value = 0 };
749};
750template <> struct typelist_size<T12> {
751 enum V { value = 0 };
752};
753template <> struct typelist_size<T13> {
754 enum V { value = 0 };
755};
756template <> struct typelist_size<T14> {
757 enum V { value = 0 };
758};
759template <> struct typelist_size<T15> {
760 enum V { value = 0 };
761};
762
763template <> struct typelist_size<nulltype> {
764 enum V { value = 0 };
765};
766
767template <class Head, class Tail> struct typelist_size<typelist<Head, Tail>> {
768 enum V { value = size_t(typelist_size<Head>::value) + size_t(typelist_size<Tail>::value) };
769};
770
771// typelist index of type:
772
773template <class List, class T> struct typelist_index_of;
774
775template <class T> struct typelist_index_of<nulltype, T> {
776 enum V { value = -1 };
777};
778
779template <class Tail, class T> struct typelist_index_of<typelist<T, Tail>, T> {
780 enum V { value = 0 };
781};
782
783template <class Head, class Tail, class T> struct typelist_index_of<typelist<Head, Tail>, T> {
784private:
785 enum TV { nextVal = typelist_index_of<Tail, T>::value };
786
787public:
788 enum V { value = nextVal == -1 ? -1 : 1 + nextVal };
789};
790
791// typelist type at index:
792
793template <class List, std::size_t i> struct typelist_type_at;
794
795template <class Head, class Tail> struct typelist_type_at<typelist<Head, Tail>, 0> { typedef Head type; };
796
797template <class Head, class Tail, std::size_t i> struct typelist_type_at<typelist<Head, Tail>, i> {
798 typedef typename typelist_type_at<Tail, i - 1>::type type;
799};
800
801// typelist type is unique:
802
803template <class List, std::size_t CmpIndex, std::size_t LastChecked = typelist_size<List>::value> struct typelist_type_is_unique {
804private:
805 typedef typename typelist_type_at<List, CmpIndex>::type cmp_type;
806 typedef typename typelist_type_at<List, LastChecked - 1>::type cur_type;
807
808public:
809 enum V {
810 value = ((CmpIndex == (LastChecked - 1)) | !std11::is_same<cmp_type, cur_type>::value) &&
811 typelist_type_is_unique<List, CmpIndex, LastChecked - 1>::value
812 };
813};
814
815template <class List, std::size_t CmpIndex> struct typelist_type_is_unique<List, CmpIndex, 0> {
816 enum V { value = 1 };
817};
818
819template <class List, class T> struct typelist_contains_unique_type : typelist_type_is_unique<List, typelist_index_of<List, T>::value> {};
820
821#if variant_CONFIG_MAX_ALIGN_HACK
822
823// Max align, use most restricted type for alignment:
824
825#define variant_UNIQUE(name) variant_UNIQUE2(name, __LINE__)
826#define variant_UNIQUE2(name, line) variant_UNIQUE3(name, line)
827#define variant_UNIQUE3(name, line) name##line
828
829#define variant_ALIGN_TYPE(type) \
830 type variant_UNIQUE(_t); \
831 struct_t<type> variant_UNIQUE(_st)
832
833template <class T> struct struct_t { T _; };
834
835union max_align_t {
836 variant_ALIGN_TYPE(char);
837 variant_ALIGN_TYPE(short int);
838 variant_ALIGN_TYPE(int);
839 variant_ALIGN_TYPE(long int);
840 variant_ALIGN_TYPE(float);
841 variant_ALIGN_TYPE(double);
842 variant_ALIGN_TYPE(long double);
843 variant_ALIGN_TYPE(char*);
844 variant_ALIGN_TYPE(short int*);
845 variant_ALIGN_TYPE(int*);
846 variant_ALIGN_TYPE(long int*);
847 variant_ALIGN_TYPE(float*);
848 variant_ALIGN_TYPE(double*);
849 variant_ALIGN_TYPE(long double*);
850 variant_ALIGN_TYPE(void*);
851
852#ifdef HAVE_LONG_LONG
853 variant_ALIGN_TYPE(long long);
854#endif
855
856 struct Unknown;
857
858 Unknown (*variant_UNIQUE(_))(Unknown);
859 Unknown* Unknown::*variant_UNIQUE(_);
860 Unknown (Unknown::*variant_UNIQUE(_))(Unknown);
861
862 struct_t<Unknown (*)(Unknown)> variant_UNIQUE(_);
863 struct_t<Unknown * Unknown::*> variant_UNIQUE(_);
864 struct_t<Unknown (Unknown::*)(Unknown)> variant_UNIQUE(_);
865};
866
867#undef variant_UNIQUE
868#undef variant_UNIQUE2
869#undef variant_UNIQUE3
870
871#undef variant_ALIGN_TYPE
872
873#elif defined(variant_CONFIG_ALIGN_AS) // variant_CONFIG_MAX_ALIGN_HACK
874
875// Use user-specified type for alignment:
876
877#define variant_ALIGN_AS(unused) variant_CONFIG_ALIGN_AS
878
879#else // variant_CONFIG_MAX_ALIGN_HACK
880
881// Determine POD type to use for alignment:
882
883#define variant_ALIGN_AS(to_align) typename detail::type_of_size<detail::alignment_types, detail::alignment_of<to_align>::value>::type
884
885template <typename T> struct alignment_of;
886
887template <typename T> struct alignment_of_hack {
888 char c;
889 T t;
890 alignment_of_hack();
891};
892
893template <size_t A, size_t S> struct alignment_logic {
894 enum V { value = A < S ? A : S };
895};
896
897template <typename T> struct alignment_of {
898 enum V { value = alignment_logic<sizeof(alignment_of_hack<T>) - sizeof(T), sizeof(T)>::value };
899};
900
901template <typename List, size_t N> struct type_of_size {
902 typedef typename std11::conditional<N == sizeof(typename List::head), typename List::head,
903 typename type_of_size<typename List::tail, N>::type>::type type;
904};
905
906template <size_t N> struct type_of_size<nulltype, N> { typedef variant_CONFIG_ALIGN_AS_FALLBACK type; };
907
908template <typename T> struct struct_t { T _; };
909
910#define variant_ALIGN_TYPE(type) typelist < type, typelist < struct_t<type>
911
912struct Unknown;
913
914typedef variant_ALIGN_TYPE(char), variant_ALIGN_TYPE(short), variant_ALIGN_TYPE(int), variant_ALIGN_TYPE(long), variant_ALIGN_TYPE(float),
915 variant_ALIGN_TYPE(double), variant_ALIGN_TYPE(long double),
916
917 variant_ALIGN_TYPE(char*), variant_ALIGN_TYPE(short*), variant_ALIGN_TYPE(int*), variant_ALIGN_TYPE(long*), variant_ALIGN_TYPE(float*),
918 variant_ALIGN_TYPE(double*), variant_ALIGN_TYPE(long double*),
919
920 variant_ALIGN_TYPE(Unknown (*)(Unknown)), variant_ALIGN_TYPE(Unknown* Unknown::*), variant_ALIGN_TYPE(Unknown (Unknown::*)(Unknown)),
921
922 nulltype >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> alignment_types;
923
924#undef variant_ALIGN_TYPE
925
926#endif // variant_CONFIG_MAX_ALIGN_HACK
927
928#if variant_CPP11_OR_GREATER
929
930template <typename T> inline std::size_t hash(T const& v) { return std::hash<T>()(v); }
931
932inline std::size_t hash(T0 const&) { return 0; }
933inline std::size_t hash(T1 const&) { return 0; }
934inline std::size_t hash(T2 const&) { return 0; }
935inline std::size_t hash(T3 const&) { return 0; }
936inline std::size_t hash(T4 const&) { return 0; }
937inline std::size_t hash(T5 const&) { return 0; }
938inline std::size_t hash(T6 const&) { return 0; }
939inline std::size_t hash(T7 const&) { return 0; }
940inline std::size_t hash(T8 const&) { return 0; }
941inline std::size_t hash(T9 const&) { return 0; }
942inline std::size_t hash(T10 const&) { return 0; }
943inline std::size_t hash(T11 const&) { return 0; }
944inline std::size_t hash(T12 const&) { return 0; }
945inline std::size_t hash(T13 const&) { return 0; }
946inline std::size_t hash(T14 const&) { return 0; }
947inline std::size_t hash(T15 const&) { return 0; }
948
949#endif // variant_CPP11_OR_GREATER
950
951template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
952 class T12, class T13, class T14, class T15>
953struct helper {
954 typedef signed char type_index_t;
955 typedef variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) variant_types;
956
957 template <class U> static U* as(void* data) { return reinterpret_cast<U*>(data); }
958
959 template <class U> static U const* as(void const* data) { return reinterpret_cast<const U*>(data); }
960
961 static type_index_t to_index_t(std::size_t index) { return static_cast<type_index_t>(index); }
962
963 static void destroy(type_index_t index, void* data) {
964 switch(index) {
965 case 0:
966 as<T0>(data)->~T0();
967 break;
968 case 1:
969 as<T1>(data)->~T1();
970 break;
971 case 2:
972 as<T2>(data)->~T2();
973 break;
974 case 3:
975 as<T3>(data)->~T3();
976 break;
977 case 4:
978 as<T4>(data)->~T4();
979 break;
980 case 5:
981 as<T5>(data)->~T5();
982 break;
983 case 6:
984 as<T6>(data)->~T6();
985 break;
986 case 7:
987 as<T7>(data)->~T7();
988 break;
989 case 8:
990 as<T8>(data)->~T8();
991 break;
992 case 9:
993 as<T9>(data)->~T9();
994 break;
995 case 10:
996 as<T10>(data)->~T10();
997 break;
998 case 11:
999 as<T11>(data)->~T11();
1000 break;
1001 case 12:
1002 as<T12>(data)->~T12();
1003 break;
1004 case 13:
1005 as<T13>(data)->~T13();
1006 break;
1007 case 14:
1008 as<T14>(data)->~T14();
1009 break;
1010 case 15:
1011 as<T15>(data)->~T15();
1012 break;
1013 }
1014 }
1015
1016#if variant_CPP11_OR_GREATER
1017 template <class T, class... Args> static type_index_t construct_t(void* data, Args&&... args) {
1018 new(data) T(std::forward<Args>(args)...);
1019
1021 }
1022
1023 template <std::size_t K, class... Args> static type_index_t construct_i(void* data, Args&&... args) {
1025
1026 construct_t<type>(data, std::forward<Args>(args)...);
1027
1028 return to_index_t(K);
1029 }
1030
1031 static type_index_t move_construct(type_index_t const from_index, void* from_value, void* to_value) {
1032 switch(from_index) {
1033 case 0:
1034 new(to_value) T0(std::move(*as<T0>(from_value)));
1035 break;
1036 case 1:
1037 new(to_value) T1(std::move(*as<T1>(from_value)));
1038 break;
1039 case 2:
1040 new(to_value) T2(std::move(*as<T2>(from_value)));
1041 break;
1042 case 3:
1043 new(to_value) T3(std::move(*as<T3>(from_value)));
1044 break;
1045 case 4:
1046 new(to_value) T4(std::move(*as<T4>(from_value)));
1047 break;
1048 case 5:
1049 new(to_value) T5(std::move(*as<T5>(from_value)));
1050 break;
1051 case 6:
1052 new(to_value) T6(std::move(*as<T6>(from_value)));
1053 break;
1054 case 7:
1055 new(to_value) T7(std::move(*as<T7>(from_value)));
1056 break;
1057 case 8:
1058 new(to_value) T8(std::move(*as<T8>(from_value)));
1059 break;
1060 case 9:
1061 new(to_value) T9(std::move(*as<T9>(from_value)));
1062 break;
1063 case 10:
1064 new(to_value) T10(std::move(*as<T10>(from_value)));
1065 break;
1066 case 11:
1067 new(to_value) T11(std::move(*as<T11>(from_value)));
1068 break;
1069 case 12:
1070 new(to_value) T12(std::move(*as<T12>(from_value)));
1071 break;
1072 case 13:
1073 new(to_value) T13(std::move(*as<T13>(from_value)));
1074 break;
1075 case 14:
1076 new(to_value) T14(std::move(*as<T14>(from_value)));
1077 break;
1078 case 15:
1079 new(to_value) T15(std::move(*as<T15>(from_value)));
1080 break;
1081 }
1082 return from_index;
1083 }
1084
1085 static type_index_t move_assign(type_index_t const from_index, void* from_value, void* to_value) {
1086 switch(from_index) {
1087 case 0:
1088 *as<T0>(to_value) = std::move(*as<T0>(from_value));
1089 break;
1090 case 1:
1091 *as<T1>(to_value) = std::move(*as<T1>(from_value));
1092 break;
1093 case 2:
1094 *as<T2>(to_value) = std::move(*as<T2>(from_value));
1095 break;
1096 case 3:
1097 *as<T3>(to_value) = std::move(*as<T3>(from_value));
1098 break;
1099 case 4:
1100 *as<T4>(to_value) = std::move(*as<T4>(from_value));
1101 break;
1102 case 5:
1103 *as<T5>(to_value) = std::move(*as<T5>(from_value));
1104 break;
1105 case 6:
1106 *as<T6>(to_value) = std::move(*as<T6>(from_value));
1107 break;
1108 case 7:
1109 *as<T7>(to_value) = std::move(*as<T7>(from_value));
1110 break;
1111 case 8:
1112 *as<T8>(to_value) = std::move(*as<T8>(from_value));
1113 break;
1114 case 9:
1115 *as<T9>(to_value) = std::move(*as<T9>(from_value));
1116 break;
1117 case 10:
1118 *as<T10>(to_value) = std::move(*as<T10>(from_value));
1119 break;
1120 case 11:
1121 *as<T11>(to_value) = std::move(*as<T11>(from_value));
1122 break;
1123 case 12:
1124 *as<T12>(to_value) = std::move(*as<T12>(from_value));
1125 break;
1126 case 13:
1127 *as<T13>(to_value) = std::move(*as<T13>(from_value));
1128 break;
1129 case 14:
1130 *as<T14>(to_value) = std::move(*as<T14>(from_value));
1131 break;
1132 case 15:
1133 *as<T15>(to_value) = std::move(*as<T15>(from_value));
1134 break;
1135 }
1136 return from_index;
1137 }
1138#endif
1139
1140 static type_index_t copy_construct(type_index_t const from_index, const void* from_value, void* to_value) {
1141 switch(from_index) {
1142 case 0:
1143 new(to_value) T0(*as<T0>(from_value));
1144 break;
1145 case 1:
1146 new(to_value) T1(*as<T1>(from_value));
1147 break;
1148 case 2:
1149 new(to_value) T2(*as<T2>(from_value));
1150 break;
1151 case 3:
1152 new(to_value) T3(*as<T3>(from_value));
1153 break;
1154 case 4:
1155 new(to_value) T4(*as<T4>(from_value));
1156 break;
1157 case 5:
1158 new(to_value) T5(*as<T5>(from_value));
1159 break;
1160 case 6:
1161 new(to_value) T6(*as<T6>(from_value));
1162 break;
1163 case 7:
1164 new(to_value) T7(*as<T7>(from_value));
1165 break;
1166 case 8:
1167 new(to_value) T8(*as<T8>(from_value));
1168 break;
1169 case 9:
1170 new(to_value) T9(*as<T9>(from_value));
1171 break;
1172 case 10:
1173 new(to_value) T10(*as<T10>(from_value));
1174 break;
1175 case 11:
1176 new(to_value) T11(*as<T11>(from_value));
1177 break;
1178 case 12:
1179 new(to_value) T12(*as<T12>(from_value));
1180 break;
1181 case 13:
1182 new(to_value) T13(*as<T13>(from_value));
1183 break;
1184 case 14:
1185 new(to_value) T14(*as<T14>(from_value));
1186 break;
1187 case 15:
1188 new(to_value) T15(*as<T15>(from_value));
1189 break;
1190 }
1191 return from_index;
1192 }
1193
1194 static type_index_t copy_assign(type_index_t const from_index, const void* from_value, void* to_value) {
1195 switch(from_index) {
1196 case 0:
1197 *as<T0>(to_value) = *as<T0>(from_value);
1198 break;
1199 case 1:
1200 *as<T1>(to_value) = *as<T1>(from_value);
1201 break;
1202 case 2:
1203 *as<T2>(to_value) = *as<T2>(from_value);
1204 break;
1205 case 3:
1206 *as<T3>(to_value) = *as<T3>(from_value);
1207 break;
1208 case 4:
1209 *as<T4>(to_value) = *as<T4>(from_value);
1210 break;
1211 case 5:
1212 *as<T5>(to_value) = *as<T5>(from_value);
1213 break;
1214 case 6:
1215 *as<T6>(to_value) = *as<T6>(from_value);
1216 break;
1217 case 7:
1218 *as<T7>(to_value) = *as<T7>(from_value);
1219 break;
1220 case 8:
1221 *as<T8>(to_value) = *as<T8>(from_value);
1222 break;
1223 case 9:
1224 *as<T9>(to_value) = *as<T9>(from_value);
1225 break;
1226 case 10:
1227 *as<T10>(to_value) = *as<T10>(from_value);
1228 break;
1229 case 11:
1230 *as<T11>(to_value) = *as<T11>(from_value);
1231 break;
1232 case 12:
1233 *as<T12>(to_value) = *as<T12>(from_value);
1234 break;
1235 case 13:
1236 *as<T13>(to_value) = *as<T13>(from_value);
1237 break;
1238 case 14:
1239 *as<T14>(to_value) = *as<T14>(from_value);
1240 break;
1241 case 15:
1242 *as<T15>(to_value) = *as<T15>(from_value);
1243 break;
1244 }
1245 return from_index;
1246 }
1247};
1248
1249} // namespace detail
1250
1251//
1252// Variant:
1253//
1254
1255template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
1256 class T12, class T13, class T14, class T15>
1257class variant;
1258
1259// 19.7.8 Class monostate
1260
1261class monostate {};
1262
1263// 19.7.9 monostate relational operators
1264
1265inline variant_constexpr bool operator<(monostate, monostate) variant_noexcept { return false; }
1266inline variant_constexpr bool operator>(monostate, monostate) variant_noexcept { return false; }
1267inline variant_constexpr bool operator<=(monostate, monostate) variant_noexcept { return true; }
1268inline variant_constexpr bool operator>=(monostate, monostate) variant_noexcept { return true; }
1269inline variant_constexpr bool operator==(monostate, monostate) variant_noexcept { return true; }
1270inline variant_constexpr bool operator!=(monostate, monostate) variant_noexcept { return false; }
1271
1272// 19.7.4 variant helper classes
1273
1274// obtain the size of the variant's list of alternatives at compile time
1275
1276template <class T> struct variant_size; /* undefined */
1277
1278template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
1279 class T12, class T13, class T14, class T15>
1280struct variant_size<variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> {
1281 enum _ { value = detail::typelist_size<variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)>::value };
1282};
1283
1284#if variant_CPP14_OR_GREATER
1285template <class T> constexpr std::size_t variant_size_v = variant_size<T>::value;
1286#endif
1287
1288#if !variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
1289#define variant_size_V(T) nonstd::variant_size<T>::value
1290#endif
1291
1292// obtain the type of the alternative specified by its index, at compile time:
1293
1294template <std::size_t K, class T> struct variant_alternative; /* undefined */
1295
1296template <std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10,
1297 class T11, class T12, class T13, class T14, class T15>
1298struct variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> {
1299 typedef
1300 typename detail::typelist_type_at<variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15), K>::type type;
1301};
1302
1303#if variant_CPP11_OR_GREATER
1304template <std::size_t K, class T> using variant_alternative_t = typename variant_alternative<K, T>::type;
1305#endif
1306
1307#if !variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
1308#define variant_alternative_T(K, T) typename nonstd::variant_alternative<K, T>::type
1309#endif
1310
1311// NTS:implement specializes the std::uses_allocator type trait
1312// std::uses_allocator<nonstd::variant>
1313
1314// index of the variant in the invalid state (constant)
1315
1316#if variant_CPP11_OR_GREATER
1317variant_constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
1318#else
1319static const std::size_t variant_npos = static_cast<std::size_t>(-1);
1320#endif
1321
1322#if !variant_CONFIG_NO_EXCEPTIONS
1323
1324// 19.7.11 Class bad_variant_access
1325
1326class bad_variant_access : public std::exception {
1327public:
1328#if variant_CPP11_OR_GREATER
1329 virtual const char* what() const variant_noexcept variant_override
1330#else
1331 virtual const char* what() const throw()
1332#endif
1333 {
1334 return "bad variant access";
1335 }
1336};
1337
1338#endif // variant_CONFIG_NO_EXCEPTIONS
1339
1340// 19.7.3 Class template variant
1341
1342template <class T0, class T1 = detail::T1, class T2 = detail::T2, class T3 = detail::T3, class T4 = detail::T4, class T5 = detail::T5,
1343 class T6 = detail::T6, class T7 = detail::T7, class T8 = detail::T8, class T9 = detail::T9, class T10 = detail::T10,
1344 class T11 = detail::T11, class T12 = detail::T12, class T13 = detail::T13, class T14 = detail::T14, class T15 = detail::T15>
1345class variant {
1347 typedef variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) variant_types;
1348
1349public:
1350 // 19.7.3.1 Constructors
1351
1352 variant()
1353 : type_index(0) {
1354 new(ptr()) T0();
1355 }
1356
1357#if variant_CPP11_OR_GREATER
1358 template <variant_index_tag_t(0) = variant_index_tag(0) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 0>::value)>
1359 variant(T0 const& t0)
1360 : type_index(0) {
1361 new(ptr()) T0(t0);
1362 }
1363
1364 template <variant_index_tag_t(1) = variant_index_tag(1) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 1>::value)>
1365 variant(T1 const& t1)
1366 : type_index(1) {
1367 new(ptr()) T1(t1);
1368 }
1369
1370 template <variant_index_tag_t(2) = variant_index_tag(2) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 2>::value)>
1371 variant(T2 const& t2)
1372 : type_index(2) {
1373 new(ptr()) T2(t2);
1374 }
1375
1376 template <variant_index_tag_t(3) = variant_index_tag(3) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 3>::value)>
1377 variant(T3 const& t3)
1378 : type_index(3) {
1379 new(ptr()) T3(t3);
1380 }
1381
1382 template <variant_index_tag_t(4) = variant_index_tag(4) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 4>::value)>
1383 variant(T4 const& t4)
1384 : type_index(4) {
1385 new(ptr()) T4(t4);
1386 }
1387
1388 template <variant_index_tag_t(5) = variant_index_tag(5) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 5>::value)>
1389 variant(T5 const& t5)
1390 : type_index(5) {
1391 new(ptr()) T5(t5);
1392 }
1393
1394 template <variant_index_tag_t(6) = variant_index_tag(6) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 6>::value)>
1395 variant(T6 const& t6)
1396 : type_index(6) {
1397 new(ptr()) T6(t6);
1398 }
1399
1400 template <variant_index_tag_t(7) = variant_index_tag(7) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 7>::value)>
1401 variant(T7 const& t7)
1402 : type_index(7) {
1403 new(ptr()) T7(t7);
1404 }
1405
1406 template <variant_index_tag_t(8) = variant_index_tag(8) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 8>::value)>
1407 variant(T8 const& t8)
1408 : type_index(8) {
1409 new(ptr()) T8(t8);
1410 }
1411
1412 template <variant_index_tag_t(9) = variant_index_tag(9) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 9>::value)>
1413 variant(T9 const& t9)
1414 : type_index(9) {
1415 new(ptr()) T9(t9);
1416 }
1417
1418 template <variant_index_tag_t(10) = variant_index_tag(10) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 10>::value)>
1419 variant(T10 const& t10)
1420 : type_index(10) {
1421 new(ptr()) T10(t10);
1422 }
1423
1424 template <variant_index_tag_t(11) = variant_index_tag(11) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 11>::value)>
1425 variant(T11 const& t11)
1426 : type_index(11) {
1427 new(ptr()) T11(t11);
1428 }
1429
1430 template <variant_index_tag_t(12) = variant_index_tag(12) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 12>::value)>
1431 variant(T12 const& t12)
1432 : type_index(12) {
1433 new(ptr()) T12(t12);
1434 }
1435
1436 template <variant_index_tag_t(13) = variant_index_tag(13) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 13>::value)>
1437 variant(T13 const& t13)
1438 : type_index(13) {
1439 new(ptr()) T13(t13);
1440 }
1441
1442 template <variant_index_tag_t(14) = variant_index_tag(14) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 14>::value)>
1443 variant(T14 const& t14)
1444 : type_index(14) {
1445 new(ptr()) T14(t14);
1446 }
1447
1448 template <variant_index_tag_t(15) = variant_index_tag(15) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 15>::value)>
1449 variant(T15 const& t15)
1450 : type_index(15) {
1451 new(ptr()) T15(t15);
1452 }
1453
1454#else
1455
1456 variant(T0 const& t0)
1457 : type_index(0) {
1458 new(ptr()) T0(t0);
1459 }
1460 variant(T1 const& t1)
1461 : type_index(1) {
1462 new(ptr()) T1(t1);
1463 }
1464 variant(T2 const& t2)
1465 : type_index(2) {
1466 new(ptr()) T2(t2);
1467 }
1468 variant(T3 const& t3)
1469 : type_index(3) {
1470 new(ptr()) T3(t3);
1471 }
1472 variant(T4 const& t4)
1473 : type_index(4) {
1474 new(ptr()) T4(t4);
1475 }
1476 variant(T5 const& t5)
1477 : type_index(5) {
1478 new(ptr()) T5(t5);
1479 }
1480 variant(T6 const& t6)
1481 : type_index(6) {
1482 new(ptr()) T6(t6);
1483 }
1484 variant(T7 const& t7)
1485 : type_index(7) {
1486 new(ptr()) T7(t7);
1487 }
1488 variant(T8 const& t8)
1489 : type_index(8) {
1490 new(ptr()) T8(t8);
1491 }
1492 variant(T9 const& t9)
1493 : type_index(9) {
1494 new(ptr()) T9(t9);
1495 }
1496 variant(T10 const& t10)
1497 : type_index(10) {
1498 new(ptr()) T10(t10);
1499 }
1500 variant(T11 const& t11)
1501 : type_index(11) {
1502 new(ptr()) T11(t11);
1503 }
1504 variant(T12 const& t12)
1505 : type_index(12) {
1506 new(ptr()) T12(t12);
1507 }
1508 variant(T13 const& t13)
1509 : type_index(13) {
1510 new(ptr()) T13(t13);
1511 }
1512 variant(T14 const& t14)
1513 : type_index(14) {
1514 new(ptr()) T14(t14);
1515 }
1516 variant(T15 const& t15)
1517 : type_index(15) {
1518 new(ptr()) T15(t15);
1519 }
1520
1521#endif
1522
1523#if variant_CPP11_OR_GREATER
1524 template <variant_index_tag_t(0) = variant_index_tag(0) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 0>::value)>
1525 variant(T0&& t0)
1526 : type_index(0) {
1527 new(ptr()) T0(std::move(t0));
1528 }
1529
1530 template <variant_index_tag_t(1) = variant_index_tag(1) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 1>::value)>
1531 variant(T1&& t1)
1532 : type_index(1) {
1533 new(ptr()) T1(std::move(t1));
1534 }
1535
1536 template <variant_index_tag_t(2) = variant_index_tag(2) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 2>::value)>
1537 variant(T2&& t2)
1538 : type_index(2) {
1539 new(ptr()) T2(std::move(t2));
1540 }
1541
1542 template <variant_index_tag_t(3) = variant_index_tag(3) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 3>::value)>
1543 variant(T3&& t3)
1544 : type_index(3) {
1545 new(ptr()) T3(std::move(t3));
1546 }
1547
1548 template <variant_index_tag_t(4) = variant_index_tag(4) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 4>::value)>
1549 variant(T4&& t4)
1550 : type_index(4) {
1551 new(ptr()) T4(std::move(t4));
1552 }
1553
1554 template <variant_index_tag_t(5) = variant_index_tag(5) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 5>::value)>
1555 variant(T5&& t5)
1556 : type_index(5) {
1557 new(ptr()) T5(std::move(t5));
1558 }
1559
1560 template <variant_index_tag_t(6) = variant_index_tag(6) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 6>::value)>
1561 variant(T6&& t6)
1562 : type_index(6) {
1563 new(ptr()) T6(std::move(t6));
1564 }
1565
1566 template <variant_index_tag_t(7) = variant_index_tag(7) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 7>::value)>
1567 variant(T7&& t7)
1568 : type_index(7) {
1569 new(ptr()) T7(std::move(t7));
1570 }
1571
1572 template <variant_index_tag_t(8) = variant_index_tag(8) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 8>::value)>
1573 variant(T8&& t8)
1574 : type_index(8) {
1575 new(ptr()) T8(std::move(t8));
1576 }
1577
1578 template <variant_index_tag_t(9) = variant_index_tag(9) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 9>::value)>
1579 variant(T9&& t9)
1580 : type_index(9) {
1581 new(ptr()) T9(std::move(t9));
1582 }
1583
1584 template <variant_index_tag_t(10) = variant_index_tag(10) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 10>::value)>
1585 variant(T10&& t10)
1586 : type_index(10) {
1587 new(ptr()) T10(std::move(t10));
1588 }
1589
1590 template <variant_index_tag_t(11) = variant_index_tag(11) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 11>::value)>
1591 variant(T11&& t11)
1592 : type_index(11) {
1593 new(ptr()) T11(std::move(t11));
1594 }
1595
1596 template <variant_index_tag_t(12) = variant_index_tag(12) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 12>::value)>
1597 variant(T12&& t12)
1598 : type_index(12) {
1599 new(ptr()) T12(std::move(t12));
1600 }
1601
1602 template <variant_index_tag_t(13) = variant_index_tag(13) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 13>::value)>
1603 variant(T13&& t13)
1604 : type_index(13) {
1605 new(ptr()) T13(std::move(t13));
1606 }
1607
1608 template <variant_index_tag_t(14) = variant_index_tag(14) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 14>::value)>
1609 variant(T14&& t14)
1610 : type_index(14) {
1611 new(ptr()) T14(std::move(t14));
1612 }
1613
1614 template <variant_index_tag_t(15) = variant_index_tag(15) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 15>::value)>
1615 variant(T15&& t15)
1616 : type_index(15) {
1617 new(ptr()) T15(std::move(t15));
1618 }
1619#endif
1620
1621 variant(variant const& other)
1622 : type_index(other.type_index) {
1623 (void)helper_type::copy_construct(other.type_index, other.ptr(), ptr());
1624 }
1625
1626#if variant_CPP11_OR_GREATER
1627
1628 variant(variant&& other) noexcept(
1629 std::is_nothrow_move_constructible<T0>::value&& std::is_nothrow_move_constructible<T1>::value&&
1630 std::is_nothrow_move_constructible<T2>::value&& std::is_nothrow_move_constructible<T3>::value&&
1631 std::is_nothrow_move_constructible<T4>::value&& std::is_nothrow_move_constructible<T5>::value&&
1632 std::is_nothrow_move_constructible<T6>::value&& std::is_nothrow_move_constructible<T7>::value&&
1633 std::is_nothrow_move_constructible<T8>::value&& std::is_nothrow_move_constructible<T9>::value&&
1634 std::is_nothrow_move_constructible<T10>::value&& std::is_nothrow_move_constructible<T11>::value&&
1635 std::is_nothrow_move_constructible<T12>::value&& std::is_nothrow_move_constructible<T13>::value&&
1636 std::is_nothrow_move_constructible<T14>::value&& std::is_nothrow_move_constructible<T15>::value)
1637 : type_index(other.type_index) {
1638 (void)helper_type::move_construct(other.type_index, other.ptr(), ptr());
1639 }
1640
1641 template <std::size_t K> using type_at_t = typename detail::typelist_type_at<variant_types, K>::type;
1642
1643 template <class T, class... Args variant_REQUIRES_T(std::is_constructible<T, Args...>::value)>
1644 explicit variant(nonstd_lite_in_place_type_t(T), Args&&... args) {
1645 type_index = variant_npos_internal();
1646 type_index = helper_type::template construct_t<T>(ptr(), std::forward<Args>(args)...);
1647 }
1648
1649 template <class T, class U, class... Args variant_REQUIRES_T(std::is_constructible<T, std::initializer_list<U>&, Args...>::value)>
1650 explicit variant(nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args) {
1651 type_index = variant_npos_internal();
1652 type_index = helper_type::template construct_t<T>(ptr(), il, std::forward<Args>(args)...);
1653 }
1654
1655 template <std::size_t K, class... Args variant_REQUIRES_T(std::is_constructible<type_at_t<K>, Args...>::value)>
1656 explicit variant(nonstd_lite_in_place_index_t(K), Args&&... args) {
1657 type_index = variant_npos_internal();
1658 type_index = helper_type::template construct_i<K>(ptr(), std::forward<Args>(args)...);
1659 }
1660
1661 template <size_t K, class U,
1662 class... Args variant_REQUIRES_T(std::is_constructible<type_at_t<K>, std::initializer_list<U>&, Args...>::value)>
1663 explicit variant(nonstd_lite_in_place_index_t(K), std::initializer_list<U> il, Args&&... args) {
1664 type_index = variant_npos_internal();
1665 type_index = helper_type::template construct_i<K>(ptr(), il, std::forward<Args>(args)...);
1666 }
1667
1668#endif // variant_CPP11_OR_GREATER
1669
1670 // 19.7.3.2 Destructor
1671
1672 ~variant() {
1673 if(!valueless_by_exception()) {
1674 helper_type::destroy(type_index, ptr());
1675 }
1676 }
1677
1678 // 19.7.3.3 Assignment
1679
1680 variant& operator=(variant const& other) { return copy_assign(other); }
1681
1682#if variant_CPP11_OR_GREATER
1683
1684 variant& operator=(variant&& other) noexcept(
1685 std::is_nothrow_move_assignable<T0>::value&& std::is_nothrow_move_assignable<T1>::value&&
1686 std::is_nothrow_move_assignable<T2>::value&& std::is_nothrow_move_assignable<T3>::value&&
1687 std::is_nothrow_move_assignable<T4>::value&& std::is_nothrow_move_assignable<T5>::value&&
1688 std::is_nothrow_move_assignable<T6>::value&& std::is_nothrow_move_assignable<T7>::value&&
1689 std::is_nothrow_move_assignable<T8>::value&& std::is_nothrow_move_assignable<T9>::value&&
1690 std::is_nothrow_move_assignable<T10>::value&& std::is_nothrow_move_assignable<T11>::value&&
1691 std::is_nothrow_move_assignable<T12>::value&& std::is_nothrow_move_assignable<T13>::value&&
1692 std::is_nothrow_move_assignable<T14>::value&& std::is_nothrow_move_assignable<T15>::value) {
1693 return move_assign(std::move(other));
1694 }
1695
1696 template <variant_index_tag_t(0) = variant_index_tag(0) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 0>::value)>
1697 variant& operator=(T0&& t0) {
1698 return assign_value<0>(std::move(t0));
1699 }
1700
1701 template <variant_index_tag_t(1) = variant_index_tag(1) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 1>::value)>
1702 variant& operator=(T1&& t1) {
1703 return assign_value<1>(std::move(t1));
1704 }
1705
1706 template <variant_index_tag_t(2) = variant_index_tag(2) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 2>::value)>
1707 variant& operator=(T2&& t2) {
1708 return assign_value<2>(std::move(t2));
1709 }
1710
1711 template <variant_index_tag_t(3) = variant_index_tag(3) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 3>::value)>
1712 variant& operator=(T3&& t3) {
1713 return assign_value<3>(std::move(t3));
1714 }
1715
1716 template <variant_index_tag_t(4) = variant_index_tag(4) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 4>::value)>
1717 variant& operator=(T4&& t4) {
1718 return assign_value<4>(std::move(t4));
1719 }
1720
1721 template <variant_index_tag_t(5) = variant_index_tag(5) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 5>::value)>
1722 variant& operator=(T5&& t5) {
1723 return assign_value<5>(std::move(t5));
1724 }
1725
1726 template <variant_index_tag_t(6) = variant_index_tag(6) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 6>::value)>
1727 variant& operator=(T6&& t6) {
1728 return assign_value<6>(std::move(t6));
1729 }
1730
1731 template <variant_index_tag_t(7) = variant_index_tag(7) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 7>::value)>
1732 variant& operator=(T7&& t7) {
1733 return assign_value<7>(std::move(t7));
1734 }
1735
1736 template <variant_index_tag_t(8) = variant_index_tag(8) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 8>::value)>
1737 variant& operator=(T8&& t8) {
1738 return assign_value<8>(std::move(t8));
1739 }
1740
1741 template <variant_index_tag_t(9) = variant_index_tag(9) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 9>::value)>
1742 variant& operator=(T9&& t9) {
1743 return assign_value<9>(std::move(t9));
1744 }
1745
1746 template <variant_index_tag_t(10) = variant_index_tag(10) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 10>::value)>
1747 variant& operator=(T10&& t10) {
1748 return assign_value<10>(std::move(t10));
1749 }
1750
1751 template <variant_index_tag_t(11) = variant_index_tag(11) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 11>::value)>
1752 variant& operator=(T11&& t11) {
1753 return assign_value<11>(std::move(t11));
1754 }
1755
1756 template <variant_index_tag_t(12) = variant_index_tag(12) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 12>::value)>
1757 variant& operator=(T12&& t12) {
1758 return assign_value<12>(std::move(t12));
1759 }
1760
1761 template <variant_index_tag_t(13) = variant_index_tag(13) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 13>::value)>
1762 variant& operator=(T13&& t13) {
1763 return assign_value<13>(std::move(t13));
1764 }
1765
1766 template <variant_index_tag_t(14) = variant_index_tag(14) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 14>::value)>
1767 variant& operator=(T14&& t14) {
1768 return assign_value<14>(std::move(t14));
1769 }
1770
1771 template <variant_index_tag_t(15) = variant_index_tag(15) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 15>::value)>
1772 variant& operator=(T15&& t15) {
1773 return assign_value<15>(std::move(t15));
1774 }
1775
1776#endif
1777
1778#if variant_CPP11_OR_GREATER
1779
1780 template <variant_index_tag_t(0) = variant_index_tag(0) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 0>::value)>
1781 variant& operator=(T0 const& t0) {
1782 return assign_value<0>(t0);
1783 }
1784
1785 template <variant_index_tag_t(1) = variant_index_tag(1) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 1>::value)>
1786 variant& operator=(T1 const& t1) {
1787 return assign_value<1>(t1);
1788 }
1789
1790 template <variant_index_tag_t(2) = variant_index_tag(2) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 2>::value)>
1791 variant& operator=(T2 const& t2) {
1792 return assign_value<2>(t2);
1793 }
1794
1795 template <variant_index_tag_t(3) = variant_index_tag(3) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 3>::value)>
1796 variant& operator=(T3 const& t3) {
1797 return assign_value<3>(t3);
1798 }
1799
1800 template <variant_index_tag_t(4) = variant_index_tag(4) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 4>::value)>
1801 variant& operator=(T4 const& t4) {
1802 return assign_value<4>(t4);
1803 }
1804
1805 template <variant_index_tag_t(5) = variant_index_tag(5) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 5>::value)>
1806 variant& operator=(T5 const& t5) {
1807 return assign_value<5>(t5);
1808 }
1809
1810 template <variant_index_tag_t(6) = variant_index_tag(6) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 6>::value)>
1811 variant& operator=(T6 const& t6) {
1812 return assign_value<6>(t6);
1813 }
1814
1815 template <variant_index_tag_t(7) = variant_index_tag(7) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 7>::value)>
1816 variant& operator=(T7 const& t7) {
1817 return assign_value<7>(t7);
1818 }
1819
1820 template <variant_index_tag_t(8) = variant_index_tag(8) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 8>::value)>
1821 variant& operator=(T8 const& t8) {
1822 return assign_value<8>(t8);
1823 }
1824
1825 template <variant_index_tag_t(9) = variant_index_tag(9) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 9>::value)>
1826 variant& operator=(T9 const& t9) {
1827 return assign_value<9>(t9);
1828 }
1829
1830 template <variant_index_tag_t(10) = variant_index_tag(10) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 10>::value)>
1831 variant& operator=(T10 const& t10) {
1832 return assign_value<10>(t10);
1833 }
1834
1835 template <variant_index_tag_t(11) = variant_index_tag(11) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 11>::value)>
1836 variant& operator=(T11 const& t11) {
1837 return assign_value<11>(t11);
1838 }
1839
1840 template <variant_index_tag_t(12) = variant_index_tag(12) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 12>::value)>
1841 variant& operator=(T12 const& t12) {
1842 return assign_value<12>(t12);
1843 }
1844
1845 template <variant_index_tag_t(13) = variant_index_tag(13) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 13>::value)>
1846 variant& operator=(T13 const& t13) {
1847 return assign_value<13>(t13);
1848 }
1849
1850 template <variant_index_tag_t(14) = variant_index_tag(14) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 14>::value)>
1851 variant& operator=(T14 const& t14) {
1852 return assign_value<14>(t14);
1853 }
1854
1855 template <variant_index_tag_t(15) = variant_index_tag(15) variant_REQUIRES_B(detail::typelist_type_is_unique<variant_types, 15>::value)>
1856 variant& operator=(T15 const& t15) {
1857 return assign_value<15>(t15);
1858 }
1859
1860#else
1861
1862 variant& operator=(T0 const& t0) { return assign_value<0>(t0); }
1863 variant& operator=(T1 const& t1) { return assign_value<1>(t1); }
1864 variant& operator=(T2 const& t2) { return assign_value<2>(t2); }
1865 variant& operator=(T3 const& t3) { return assign_value<3>(t3); }
1866 variant& operator=(T4 const& t4) { return assign_value<4>(t4); }
1867 variant& operator=(T5 const& t5) { return assign_value<5>(t5); }
1868 variant& operator=(T6 const& t6) { return assign_value<6>(t6); }
1869 variant& operator=(T7 const& t7) { return assign_value<7>(t7); }
1870 variant& operator=(T8 const& t8) { return assign_value<8>(t8); }
1871 variant& operator=(T9 const& t9) { return assign_value<9>(t9); }
1872 variant& operator=(T10 const& t10) { return assign_value<10>(t10); }
1873 variant& operator=(T11 const& t11) { return assign_value<11>(t11); }
1874 variant& operator=(T12 const& t12) { return assign_value<12>(t12); }
1875 variant& operator=(T13 const& t13) { return assign_value<13>(t13); }
1876 variant& operator=(T14 const& t14) { return assign_value<14>(t14); }
1877 variant& operator=(T15 const& t15) { return assign_value<15>(t15); }
1878
1879#endif
1880
1881 std::size_t index() const { return variant_npos_internal() == type_index ? variant_npos : static_cast<std::size_t>(type_index); }
1882
1883 // 19.7.3.4 Modifiers
1884
1885#if variant_CPP11_OR_GREATER
1886
1887 template <class T, class... Args variant_REQUIRES_T(std::is_constructible<T, Args...>::value)
1888 variant_REQUIRES_T(detail::typelist_contains_unique_type<variant_types, T>::value)>
1889 T& emplace(Args&&... args) {
1890 helper_type::destroy(type_index, ptr());
1891 type_index = variant_npos_internal();
1892 type_index = helper_type::template construct_t<T>(ptr(), std::forward<Args>(args)...);
1893
1894 return *as<T>();
1895 }
1896
1897 template <class T, class U,
1898 class... Args variant_REQUIRES_T(std::is_constructible<T, std::initializer_list<U>&, Args...>::value)
1899 variant_REQUIRES_T(detail::typelist_contains_unique_type<variant_types, T>::value)>
1900 T& emplace(std::initializer_list<U> il, Args&&... args) {
1901 helper_type::destroy(type_index, ptr());
1902 type_index = variant_npos_internal();
1903 type_index = helper_type::template construct_t<T>(ptr(), il, std::forward<Args>(args)...);
1904
1905 return *as<T>();
1906 }
1907
1908 template <size_t K, class... Args variant_REQUIRES_T(std::is_constructible<type_at_t<K>, Args...>::value)>
1909 variant_alternative_t<K, variant>& emplace(Args&&... args) {
1910 return this->template emplace<type_at_t<K>>(std::forward<Args>(args)...);
1911 }
1912
1913 template <size_t K, class U,
1914 class... Args variant_REQUIRES_T(std::is_constructible<type_at_t<K>, std::initializer_list<U>&, Args...>::value)>
1915 variant_alternative_t<K, variant>& emplace(std::initializer_list<U> il, Args&&... args) {
1916 return this->template emplace<type_at_t<K>>(il, std::forward<Args>(args)...);
1917 }
1918
1919#endif // variant_CPP11_OR_GREATER
1920
1921 // 19.7.3.5 Value status
1922
1923 bool valueless_by_exception() const { return type_index == variant_npos_internal(); }
1924
1925 // 19.7.3.6 Swap
1926
1927 void swap(variant& other)
1928#if variant_CPP11_OR_GREATER
1929 noexcept(
1930 std::is_nothrow_move_constructible<T0>::value&& std17::is_nothrow_swappable<T0>::value&& std::is_nothrow_move_constructible<
1931 T1>::value&& std17::is_nothrow_swappable<T1>::value&& std::is_nothrow_move_constructible<T2>::value&&
1932 std17::is_nothrow_swappable<T2>::value&& std::is_nothrow_move_constructible<T3>::value&& std17::is_nothrow_swappable<
1933 T3>::value&& std::is_nothrow_move_constructible<T4>::value&& std17::is_nothrow_swappable<T4>::value&&
1934 std::is_nothrow_move_constructible<T5>::value&& std17::is_nothrow_swappable<
1935 T5>::value&& std::is_nothrow_move_constructible<T6>::value&& std17::is_nothrow_swappable<T6>::value&&
1936 std::is_nothrow_move_constructible<T7>::value&& std17::is_nothrow_swappable<
1937 T7>::value&& std::is_nothrow_move_constructible<T8>::value&& std17::is_nothrow_swappable<T8>::value&&
1938 std::is_nothrow_move_constructible<T9>::value&& std17::is_nothrow_swappable<T9>::value&&
1939 std::is_nothrow_move_constructible<T10>::value&& std17::is_nothrow_swappable<T10>::value&&
1940 std::is_nothrow_move_constructible<T11>::value&& std17::is_nothrow_swappable<T11>::value&&
1941 std::is_nothrow_move_constructible<T12>::value&& std17::is_nothrow_swappable<T12>::value&&
1942 std::is_nothrow_move_constructible<T13>::value&& std17::is_nothrow_swappable<T13>::value&&
1943 std::is_nothrow_move_constructible<T14>::value&& std17::is_nothrow_swappable<T14>::value&&
1944 std::is_nothrow_move_constructible<T15>::value&& std17::is_nothrow_swappable<T15>::value
1945
1946 )
1947#endif
1948 {
1949 if(valueless_by_exception() && other.valueless_by_exception()) {
1950 // no effect
1951 } else if(type_index == other.type_index) {
1952 this->swap_value(type_index, other);
1953 } else {
1954#if variant_CPP11_OR_GREATER
1955 variant tmp(std::move(*this));
1956 *this = std::move(other);
1957 other = std::move(tmp);
1958#else
1959 variant tmp(*this);
1960 *this = other;
1961 other = tmp;
1962#endif
1963 }
1964 }
1965
1966 //
1967 // non-standard:
1968 //
1969
1970 template <class T> static variant_constexpr std::size_t index_of() variant_noexcept {
1971 return to_size_t(detail::typelist_index_of<variant_types, typename std11::remove_cv<T>::type>::value);
1972 }
1973
1974 template <class T> T& get() {
1975#if variant_CONFIG_NO_EXCEPTIONS
1976 assert(index_of<T>() == index());
1977#else
1978 if(index_of<T>() != index()) {
1979 throw bad_variant_access();
1980 }
1981#endif
1982 return *as<T>();
1983 }
1984
1985 template <class T> T const& get() const {
1986#if variant_CONFIG_NO_EXCEPTIONS
1987 assert(index_of<T>() == index());
1988#else
1989 if(index_of<T>() != index()) {
1990 throw bad_variant_access();
1991 }
1992#endif
1993 return *as<const T>();
1994 }
1995
1996 template <std::size_t K> typename variant_alternative<K, variant>::type& get() {
1997 return this->template get<typename detail::typelist_type_at<variant_types, K>::type>();
1998 }
1999
2000 template <std::size_t K> typename variant_alternative<K, variant>::type const& get() const {
2001 return this->template get<typename detail::typelist_type_at<variant_types, K>::type>();
2002 }
2003
2004private:
2005 typedef typename helper_type::type_index_t type_index_t;
2006
2007 void* ptr() variant_noexcept { return &data; }
2008
2009 void const* ptr() const variant_noexcept { return &data; }
2010
2011 template <class U> U* as() { return reinterpret_cast<U*>(ptr()); }
2012
2013 template <class U> U const* as() const { return reinterpret_cast<U const*>(ptr()); }
2014
2015 template <class U> static variant_constexpr std::size_t to_size_t(U index) { return static_cast<std::size_t>(index); }
2016
2017 variant_constexpr type_index_t variant_npos_internal() const variant_noexcept { return static_cast<type_index_t>(-1); }
2018
2019 variant& copy_assign(variant const& other) {
2020 if(valueless_by_exception() && other.valueless_by_exception()) {
2021 // no effect
2022 } else if(!valueless_by_exception() && other.valueless_by_exception()) {
2023 helper_type::destroy(type_index, ptr());
2024 type_index = variant_npos_internal();
2025 } else if(index() == other.index()) {
2026 type_index = helper_type::copy_assign(other.type_index, other.ptr(), ptr());
2027 } else {
2028 helper_type::destroy(type_index, ptr());
2029 type_index = variant_npos_internal();
2030 type_index = helper_type::copy_construct(other.type_index, other.ptr(), ptr());
2031 }
2032 return *this;
2033 }
2034
2035#if variant_CPP11_OR_GREATER
2036
2037 variant& move_assign(variant&& other) {
2038 if(valueless_by_exception() && other.valueless_by_exception()) {
2039 // no effect
2040 } else if(!valueless_by_exception() && other.valueless_by_exception()) {
2041 helper_type::destroy(type_index, ptr());
2042 type_index = variant_npos_internal();
2043 } else if(index() == other.index()) {
2044 type_index = helper_type::move_assign(other.type_index, other.ptr(), ptr());
2045 } else {
2046 helper_type::destroy(type_index, ptr());
2047 type_index = variant_npos_internal();
2048 type_index = helper_type::move_construct(other.type_index, other.ptr(), ptr());
2049 }
2050 return *this;
2051 }
2052
2053 template <std::size_t K, class T> variant& assign_value(T&& value) {
2054 if(index() == K) {
2055 *as<T>() = std::forward<T>(value);
2056 } else {
2057 helper_type::destroy(type_index, ptr());
2058 type_index = variant_npos_internal();
2059 new(ptr()) T(std::forward<T>(value));
2060 type_index = K;
2061 }
2062 return *this;
2063 }
2064
2065#endif // variant_CPP11_OR_GREATER
2066
2067 template <std::size_t K, class T> variant& assign_value(T const& value) {
2068 if(index() == K) {
2069 *as<T>() = value;
2070 } else {
2071 helper_type::destroy(type_index, ptr());
2072 type_index = variant_npos_internal();
2073 new(ptr()) T(value);
2074 type_index = K;
2075 }
2076 return *this;
2077 }
2078
2079 void swap_value(type_index_t index, variant& other) {
2080 using std::swap;
2081 switch(index) {
2082 case 0:
2083 swap(this->get<0>(), other.get<0>());
2084 break;
2085 case 1:
2086 swap(this->get<1>(), other.get<1>());
2087 break;
2088 case 2:
2089 swap(this->get<2>(), other.get<2>());
2090 break;
2091 case 3:
2092 swap(this->get<3>(), other.get<3>());
2093 break;
2094 case 4:
2095 swap(this->get<4>(), other.get<4>());
2096 break;
2097 case 5:
2098 swap(this->get<5>(), other.get<5>());
2099 break;
2100 case 6:
2101 swap(this->get<6>(), other.get<6>());
2102 break;
2103 case 7:
2104 swap(this->get<7>(), other.get<7>());
2105 break;
2106 case 8:
2107 swap(this->get<8>(), other.get<8>());
2108 break;
2109 case 9:
2110 swap(this->get<9>(), other.get<9>());
2111 break;
2112 case 10:
2113 swap(this->get<10>(), other.get<10>());
2114 break;
2115 case 11:
2116 swap(this->get<11>(), other.get<11>());
2117 break;
2118 case 12:
2119 swap(this->get<12>(), other.get<12>());
2120 break;
2121 case 13:
2122 swap(this->get<13>(), other.get<13>());
2123 break;
2124 case 14:
2125 swap(this->get<14>(), other.get<14>());
2126 break;
2127 case 15:
2128 swap(this->get<15>(), other.get<15>());
2129 break;
2130 }
2131 }
2132
2133private:
2134 enum { data_size = detail::typelist_max<variant_types>::value };
2135
2136#if variant_CPP11_OR_GREATER
2137
2138 enum { data_align = detail::typelist_max_alignof<variant_types>::value };
2139
2140 using aligned_storage_t = typename std::aligned_storage<data_size, data_align>::type;
2141 aligned_storage_t data;
2142
2143#elif variant_CONFIG_MAX_ALIGN_HACK
2144
2145 typedef union {
2146 unsigned char data[data_size];
2147 } aligned_storage_t;
2148
2149 detail::max_align_t hack;
2150 aligned_storage_t data;
2151
2152#else
2153 typedef typename detail::typelist_max<variant_types>::type max_type;
2154
2155 typedef variant_ALIGN_AS(max_type) align_as_type;
2156
2157 typedef union {
2158 align_as_type data[1 + (data_size - 1) / sizeof(align_as_type)];
2159 } aligned_storage_t;
2160 aligned_storage_t data;
2161
2162 // # undef variant_ALIGN_AS
2163
2164#endif // variant_CONFIG_MAX_ALIGN_HACK
2165
2166 type_index_t type_index;
2167};
2168
2169// 19.7.5 Value access
2170
2171template <class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2172 class T12, class T13, class T14, class T15>
2173inline bool holds_alternative(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& v) variant_noexcept {
2175}
2176
2177template <class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2178 class T12, class T13, class T14, class T15>
2180 nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2181 return v.template get<R>();
2182}
2183
2184template <class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2185 class T12, class T13, class T14, class T15>
2186inline R const& get(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& v,
2187 nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2188 return v.template get<R>();
2189}
2190
2191template <std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10,
2192 class T11, class T12, class T13, class T14, class T15>
2195 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2196#if variant_CONFIG_NO_EXCEPTIONS
2197 assert(K == v.index());
2198#else
2199 if(K != v.index()) {
2200 throw bad_variant_access();
2201 }
2202#endif
2203 return v.template get<K>();
2204}
2205
2206template <std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10,
2207 class T11, class T12, class T13, class T14, class T15>
2210 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2211#if variant_CONFIG_NO_EXCEPTIONS
2212 assert(K == v.index());
2213#else
2214 if(K != v.index()) {
2215 throw bad_variant_access();
2216 }
2217#endif
2218 return v.template get<K>();
2219}
2220
2221#if variant_CPP11_OR_GREATER
2222
2223template <class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2224 class T12, class T13, class T14, class T15>
2226 nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2227 return std::move(v.template get<R>());
2228}
2229
2230template <class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2231 class T12, class T13, class T14, class T15>
2233 nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2234 return std::move(v.template get<R>());
2235}
2236
2237template <std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10,
2238 class T11, class T12, class T13, class T14, class T15>
2241 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2242#if variant_CONFIG_NO_EXCEPTIONS
2243 assert(K == v.index());
2244#else
2245 if(K != v.index()) {
2246 throw bad_variant_access();
2247 }
2248#endif
2249 return std::move(v.template get<K>());
2250}
2251
2252template <std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10,
2253 class T11, class T12, class T13, class T14, class T15>
2256 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2257#if variant_CONFIG_NO_EXCEPTIONS
2258 assert(K == v.index());
2259#else
2260 if(K != v.index()) {
2261 throw bad_variant_access();
2262 }
2263#endif
2264 return std::move(v.template get<K>());
2265}
2266
2267#endif // variant_CPP11_OR_GREATER
2268
2269template <class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2270 class T12, class T13, class T14, class T15>
2271inline typename std11::add_pointer<T>::type get_if(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>* pv,
2272 nonstd_lite_in_place_type_t(T) = nonstd_lite_in_place_type(T)) {
2274 ? &get<T>(*pv)
2275 : variant_nullptr;
2276}
2277
2278template <class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2279 class T12, class T13, class T14, class T15>
2280inline typename std11::add_pointer<const T>::type
2282 nonstd_lite_in_place_type_t(T) = nonstd_lite_in_place_type(T)) {
2284 ? &get<T>(*pv)
2285 : variant_nullptr;
2286}
2287
2288template <std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10,
2289 class T11, class T12, class T13, class T14, class T15>
2290inline typename std11::add_pointer<
2293 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2294 return (pv->index() == K) ? &get<K>(*pv) : variant_nullptr;
2295}
2296
2297template <std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10,
2298 class T11, class T12, class T13, class T14, class T15>
2299inline typename std11::add_pointer<
2302 nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K)) {
2303 return (pv->index() == K) ? &get<K>(*pv) : variant_nullptr;
2304}
2305
2306// 19.7.10 Specialized algorithms
2307
2308template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2309 class T12, class T13, class T14,
2310 class T15
2311#if variant_CPP11_OR_GREATER
2312 variant_REQUIRES_T(
2313 std::is_move_constructible<T0>::value&& std17::is_swappable<T0>::value&& std::is_move_constructible<
2314 T1>::value&& std17::is_swappable<T1>::value&& std::is_move_constructible<T2>::value&& std17::is_swappable<T2>::value&&
2315 std::is_move_constructible<T3>::value&& std17::is_swappable<T3>::value&& std::is_move_constructible<T4>::value&&
2316 std17::is_swappable<T4>::value&& std::is_move_constructible<T5>::value&& std17::is_swappable<T5>::value&&
2317 std::is_move_constructible<T6>::value&& std17::is_swappable<T6>::value&& std::is_move_constructible<
2318 T7>::value&& std17::is_swappable<T7>::value&& std::is_move_constructible<T8>::value&&
2319 std17::is_swappable<T8>::value&& std::is_move_constructible<T9>::value&& std17::is_swappable<T9>::value&&
2320 std::is_move_constructible<T10>::value&& std17::is_swappable<T10>::value&& std::is_move_constructible<
2321 T11>::value&& std17::is_swappable<T11>::value&& std::is_move_constructible<T12>::value&&
2322 std17::is_swappable<T12>::value&& std::is_move_constructible<T13>::value&& std17::is_swappable<
2323 T13>::value&& std::is_move_constructible<T14>::value&& std17::is_swappable<T14>::value&&
2324 std::is_move_constructible<T15>::value&& std17::is_swappable<T15>::value)
2325#endif
2326 >
2329#if variant_CPP11_OR_GREATER
2330 noexcept(noexcept(a.swap(b)))
2331#endif
2332{
2333 a.swap(b);
2334}
2335
2336// 19.7.7 Visitation
2337
2338// Variant 'visitor' implementation
2339
2340namespace detail {
2341
2342template <typename R, typename VT> struct VisitorApplicatorImpl {
2343 template <typename Visitor, typename T> static R apply(Visitor const& v, T const& arg) { return v(arg); }
2344};
2345
2346template <typename R, typename VT> struct VisitorApplicatorImpl<R, TX<VT>> {
2347 template <typename Visitor, typename T> static R apply(Visitor const&, T) {
2348 // prevent default construction of a const reference, see issue #39:
2349 std::terminate();
2350 }
2351};
2352
2353template <typename R> struct VisitorApplicator;
2354
2355template <typename R, typename Visitor, typename V1> struct VisitorUnwrapper;
2356
2357#if variant_CPP11_OR_GREATER
2358template <size_t NumVars, typename R, typename Visitor, typename... T>
2359#else
2360template <size_t NumVars, typename R, typename Visitor, typename T1, typename T2 = S0, typename T3 = S0, typename T4 = S0, typename T5 = S0>
2361#endif
2363
2364template <typename R, typename Visitor, typename T2> struct TypedVisitorUnwrapper<2, R, Visitor, T2> {
2365 const Visitor& visitor;
2366 T2 const& val2;
2367
2368 TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_)
2369 : visitor(visitor_)
2370 , val2(val2_)
2371
2372 {}
2373
2374 template <typename T> R operator()(const T& val1) const { return visitor(val1, val2); }
2375};
2376
2377template <typename R, typename Visitor, typename T2, typename T3> struct TypedVisitorUnwrapper<3, R, Visitor, T2, T3> {
2378 const Visitor& visitor;
2379 T2 const& val2;
2380 T3 const& val3;
2381
2382 TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_, T3 const& val3_)
2383 : visitor(visitor_)
2384 , val2(val2_)
2385 , val3(val3_)
2386
2387 {}
2388
2389 template <typename T> R operator()(const T& val1) const { return visitor(val1, val2, val3); }
2390};
2391
2392template <typename R, typename Visitor, typename T2, typename T3, typename T4> struct TypedVisitorUnwrapper<4, R, Visitor, T2, T3, T4> {
2393 const Visitor& visitor;
2394 T2 const& val2;
2395 T3 const& val3;
2396 T4 const& val4;
2397
2398 TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_, T3 const& val3_, T4 const& val4_)
2399 : visitor(visitor_)
2400 , val2(val2_)
2401 , val3(val3_)
2402 , val4(val4_)
2403
2404 {}
2405
2406 template <typename T> R operator()(const T& val1) const { return visitor(val1, val2, val3, val4); }
2407};
2408
2409template <typename R, typename Visitor, typename T2, typename T3, typename T4, typename T5>
2410struct TypedVisitorUnwrapper<5, R, Visitor, T2, T3, T4, T5> {
2411 const Visitor& visitor;
2412 T2 const& val2;
2413 T3 const& val3;
2414 T4 const& val4;
2415 T5 const& val5;
2416
2417 TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_, T3 const& val3_, T4 const& val4_, T5 const& val5_)
2418 : visitor(visitor_)
2419 , val2(val2_)
2420 , val3(val3_)
2421 , val4(val4_)
2422 , val5(val5_)
2423
2424 {}
2425
2426 template <typename T> R operator()(const T& val1) const { return visitor(val1, val2, val3, val4, val5); }
2427};
2428
2429template <typename R, typename Visitor, typename V2> struct VisitorUnwrapper {
2430 const Visitor& visitor;
2431 const V2& r;
2432
2433 VisitorUnwrapper(const Visitor& visitor_, const V2& r_)
2434 : visitor(visitor_)
2435 , r(r_) {}
2436
2437 template <typename T1> R operator()(T1 const& val1) const {
2438 typedef TypedVisitorUnwrapper<2, R, Visitor, T1> visitor_type;
2439 return VisitorApplicator<R>::apply(visitor_type(visitor, val1), r);
2440 }
2441
2442 template <typename T1, typename T2> R operator()(T1 const& val1, T2 const& val2) const {
2444 return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2), r);
2445 }
2446
2447 template <typename T1, typename T2, typename T3> R operator()(T1 const& val1, T2 const& val2, T3 const& val3) const {
2449 return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2, val3), r);
2450 }
2451
2452 template <typename T1, typename T2, typename T3, typename T4>
2453 R operator()(T1 const& val1, T2 const& val2, T3 const& val3, T4 const& val4) const {
2455 return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2, val3, val4), r);
2456 }
2457
2458 template <typename T1, typename T2, typename T3, typename T4, typename T5>
2459 R operator()(T1 const& val1, T2 const& val2, T3 const& val3, T4 const& val4, T5 const& val5) const {
2461 return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2, val3, val4, val5), r);
2462 }
2463};
2464
2465template <typename R> struct VisitorApplicator {
2466 template <typename Visitor, typename V1> static R apply(const Visitor& v, const V1& arg) {
2467 switch(arg.index()) {
2468 case 0:
2469 return apply_visitor<0>(v, arg);
2470 case 1:
2471 return apply_visitor<1>(v, arg);
2472 case 2:
2473 return apply_visitor<2>(v, arg);
2474 case 3:
2475 return apply_visitor<3>(v, arg);
2476 case 4:
2477 return apply_visitor<4>(v, arg);
2478 case 5:
2479 return apply_visitor<5>(v, arg);
2480 case 6:
2481 return apply_visitor<6>(v, arg);
2482 case 7:
2483 return apply_visitor<7>(v, arg);
2484 case 8:
2485 return apply_visitor<8>(v, arg);
2486 case 9:
2487 return apply_visitor<9>(v, arg);
2488 case 10:
2489 return apply_visitor<10>(v, arg);
2490 case 11:
2491 return apply_visitor<11>(v, arg);
2492 case 12:
2493 return apply_visitor<12>(v, arg);
2494 case 13:
2495 return apply_visitor<13>(v, arg);
2496 case 14:
2497 return apply_visitor<14>(v, arg);
2498 case 15:
2499 return apply_visitor<15>(v, arg);
2500
2501 // prevent default construction of a const reference, see issue #39:
2502 default:
2503 std::terminate();
2504 }
2505 }
2506
2507 template <size_t Idx, typename Visitor, typename V1> static R apply_visitor(const Visitor& v, const V1& arg) {
2508
2509#if variant_CPP11_OR_GREATER
2511#else
2512 typedef typename variant_alternative<Idx, V1>::type value_type;
2513#endif
2514 return VisitorApplicatorImpl<R, value_type>::apply(v, get<Idx>(arg));
2515 }
2516
2517#if variant_CPP11_OR_GREATER
2518 template <typename Visitor, typename V1, typename V2, typename... V>
2519 static R apply(const Visitor& v, const V1& arg1, const V2& arg2, const V... args) {
2520 typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
2521 Unwrapper unwrapper(v, arg1);
2522 return apply(unwrapper, arg2, args...);
2523 }
2524#else
2525
2526 template <typename Visitor, typename V1, typename V2> static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2) {
2527 typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
2528 Unwrapper unwrapper(v, arg1);
2529 return apply(unwrapper, arg2);
2530 }
2531
2532 template <typename Visitor, typename V1, typename V2, typename V3>
2533 static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3) {
2534 typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
2535 Unwrapper unwrapper(v, arg1);
2536 return apply(unwrapper, arg2, arg3);
2537 }
2538
2539 template <typename Visitor, typename V1, typename V2, typename V3, typename V4>
2540 static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4) {
2541 typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
2542 Unwrapper unwrapper(v, arg1);
2543 return apply(unwrapper, arg2, arg3, arg4);
2544 }
2545
2546 template <typename Visitor, typename V1, typename V2, typename V3, typename V4, typename V5>
2547 static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4, V5 const& arg5) {
2548 typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
2549 Unwrapper unwrapper(v, arg1);
2550 return apply(unwrapper, arg2, arg3, arg4, arg5);
2551 }
2552
2553#endif
2554};
2555
2556#if variant_CPP11_OR_GREATER
2557template <size_t NumVars, typename Visitor, typename... V> struct VisitorImpl {
2558 typedef decltype(std::declval<Visitor>()(get<0>(static_cast<const V&>(std::declval<V>()))...)) result_type;
2559 typedef VisitorApplicator<result_type> applicator_type;
2560};
2561#endif
2562} // namespace detail
2563
2564#if variant_CPP11_OR_GREATER
2565// No perfect forwarding here in order to simplify code
2566template <typename Visitor, typename... V>
2567inline auto visit(Visitor const& v, V const&... vars) -> typename detail::VisitorImpl<sizeof...(V), Visitor, V...>::result_type {
2568 typedef detail::VisitorImpl<sizeof...(V), Visitor, V...> impl_type;
2569 return impl_type::applicator_type::apply(v, vars...);
2570}
2571#else
2572
2573template <typename R, typename Visitor, typename V1> inline R visit(const Visitor& v, V1 const& arg1) {
2574 return detail::VisitorApplicator<R>::apply(v, arg1);
2575}
2576
2577template <typename R, typename Visitor, typename V1, typename V2> inline R visit(const Visitor& v, V1 const& arg1, V2 const& arg2) {
2578 return detail::VisitorApplicator<R>::apply(v, arg1, arg2);
2579}
2580
2581template <typename R, typename Visitor, typename V1, typename V2, typename V3>
2582inline R visit(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3) {
2583 return detail::VisitorApplicator<R>::apply(v, arg1, arg2, arg3);
2584}
2585
2586template <typename R, typename Visitor, typename V1, typename V2, typename V3, typename V4>
2587inline R visit(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4) {
2588 return detail::VisitorApplicator<R>::apply(v, arg1, arg2, arg3, arg4);
2589}
2590
2591template <typename R, typename Visitor, typename V1, typename V2, typename V3, typename V4, typename V5>
2592inline R visit(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4, V5 const& arg5) {
2593 return detail::VisitorApplicator<R>::apply(v, arg1, arg2, arg3, arg4, arg5);
2594}
2595
2596#endif
2597
2598// 19.7.6 Relational operators
2599
2600namespace detail {
2601
2602template <class Variant> struct Comparator {
2603 static inline bool equal(Variant const& v, Variant const& w) {
2604 switch(v.index()) {
2605 case 0:
2606 return get<0>(v) == get<0>(w);
2607 case 1:
2608 return get<1>(v) == get<1>(w);
2609 case 2:
2610 return get<2>(v) == get<2>(w);
2611 case 3:
2612 return get<3>(v) == get<3>(w);
2613 case 4:
2614 return get<4>(v) == get<4>(w);
2615 case 5:
2616 return get<5>(v) == get<5>(w);
2617 case 6:
2618 return get<6>(v) == get<6>(w);
2619 case 7:
2620 return get<7>(v) == get<7>(w);
2621 case 8:
2622 return get<8>(v) == get<8>(w);
2623 case 9:
2624 return get<9>(v) == get<9>(w);
2625 case 10:
2626 return get<10>(v) == get<10>(w);
2627 case 11:
2628 return get<11>(v) == get<11>(w);
2629 case 12:
2630 return get<12>(v) == get<12>(w);
2631 case 13:
2632 return get<13>(v) == get<13>(w);
2633 case 14:
2634 return get<14>(v) == get<14>(w);
2635 case 15:
2636 return get<15>(v) == get<15>(w);
2637
2638 default:
2639 return false;
2640 }
2641 }
2642
2643 static inline bool less_than(Variant const& v, Variant const& w) {
2644 switch(v.index()) {
2645 case 0:
2646 return get<0>(v) < get<0>(w);
2647 case 1:
2648 return get<1>(v) < get<1>(w);
2649 case 2:
2650 return get<2>(v) < get<2>(w);
2651 case 3:
2652 return get<3>(v) < get<3>(w);
2653 case 4:
2654 return get<4>(v) < get<4>(w);
2655 case 5:
2656 return get<5>(v) < get<5>(w);
2657 case 6:
2658 return get<6>(v) < get<6>(w);
2659 case 7:
2660 return get<7>(v) < get<7>(w);
2661 case 8:
2662 return get<8>(v) < get<8>(w);
2663 case 9:
2664 return get<9>(v) < get<9>(w);
2665 case 10:
2666 return get<10>(v) < get<10>(w);
2667 case 11:
2668 return get<11>(v) < get<11>(w);
2669 case 12:
2670 return get<12>(v) < get<12>(w);
2671 case 13:
2672 return get<13>(v) < get<13>(w);
2673 case 14:
2674 return get<14>(v) < get<14>(w);
2675 case 15:
2676 return get<15>(v) < get<15>(w);
2677
2678 default:
2679 return false;
2680 }
2681 }
2682};
2683
2684} // namespace detail
2685
2686template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2687 class T12, class T13, class T14, class T15>
2690 if(v.index() != w.index())
2691 return false;
2692 else if(v.valueless_by_exception())
2693 return true;
2694 else
2696}
2697
2698template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2699 class T12, class T13, class T14, class T15>
2702 return !(v == w);
2703}
2704
2705template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2706 class T12, class T13, class T14, class T15>
2707inline bool operator<(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& v,
2708 variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& w) {
2709 if(w.valueless_by_exception())
2710 return false;
2711 else if(v.valueless_by_exception())
2712 return true;
2713 else if(v.index() < w.index())
2714 return true;
2715 else if(v.index() > w.index())
2716 return false;
2717 else
2718 return detail::Comparator<variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>::less_than(v, w);
2719}
2720
2721template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2722 class T12, class T13, class T14, class T15>
2725 return w < v;
2726}
2727
2728template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2729 class T12, class T13, class T14, class T15>
2732 return !(v > w);
2733}
2734
2735template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2736 class T12, class T13, class T14, class T15>
2739 return !(v < w);
2740}
2741
2742} // namespace variants
2743
2744using namespace variants;
2745
2746} // namespace nonstd
2747
2748#if variant_CPP11_OR_GREATER
2749
2750// 19.7.12 Hash support
2751
2752namespace std {
2753
2754template <> struct hash<nonstd::monostate> {
2755 std::size_t operator()(nonstd::monostate) const variant_noexcept { return 42; }
2756};
2757
2758template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11,
2759 class T12, class T13, class T14, class T15>
2760struct hash<nonstd::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> {
2761 std::size_t
2762 operator()(nonstd::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& v) const variant_noexcept {
2763 namespace nvd = nonstd::variants::detail;
2764
2765 switch(v.index()) {
2766 case 0:
2767 return nvd::hash(0) ^ nvd::hash(get<0>(v));
2768 case 1:
2769 return nvd::hash(1) ^ nvd::hash(get<1>(v));
2770 case 2:
2771 return nvd::hash(2) ^ nvd::hash(get<2>(v));
2772 case 3:
2773 return nvd::hash(3) ^ nvd::hash(get<3>(v));
2774 case 4:
2775 return nvd::hash(4) ^ nvd::hash(get<4>(v));
2776 case 5:
2777 return nvd::hash(5) ^ nvd::hash(get<5>(v));
2778 case 6:
2779 return nvd::hash(6) ^ nvd::hash(get<6>(v));
2780 case 7:
2781 return nvd::hash(7) ^ nvd::hash(get<7>(v));
2782 case 8:
2783 return nvd::hash(8) ^ nvd::hash(get<8>(v));
2784 case 9:
2785 return nvd::hash(9) ^ nvd::hash(get<9>(v));
2786 case 10:
2787 return nvd::hash(10) ^ nvd::hash(get<10>(v));
2788 case 11:
2789 return nvd::hash(11) ^ nvd::hash(get<11>(v));
2790 case 12:
2791 return nvd::hash(12) ^ nvd::hash(get<12>(v));
2792 case 13:
2793 return nvd::hash(13) ^ nvd::hash(get<13>(v));
2794 case 14:
2795 return nvd::hash(14) ^ nvd::hash(get<14>(v));
2796 case 15:
2797 return nvd::hash(15) ^ nvd::hash(get<15>(v));
2798
2799 default:
2800 return 0;
2801 }
2802 }
2803};
2804
2805} // namespace std
2806
2807#endif // variant_CPP11_OR_GREATER
2808
2809#if variant_BETWEEN(variant_COMPILER_MSVC_VER, 1300, 1900)
2810#pragma warning(pop)
2811#endif
2812
2813#endif // variant_USES_STD_VARIANT
2814
2815#endif // NONSTD_VARIANT_LITE_HPP
Used to represent an optional with no data; essentially a bool.
Definition optional.hpp:103
type traits C++17:
Definition variant.hpp:525
A tag type to tell optional to construct its value in-place.
Definition optional.hpp:106