scc  2024.06
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 
116 namespace nonstd {
117 
118 using std::in_place;
119 using std::in_place_index;
120 using std::in_place_index_t;
121 using std::in_place_t;
122 using std::in_place_type;
123 using 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 
142 namespace nonstd {
143 namespace detail {
144 
145 template <class T> struct in_place_type_tag {};
146 
147 template <std::size_t K> struct in_place_index_tag {};
148 
149 } // namespace detail
150 
151 struct in_place_t {};
152 
153 template <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 
155 template <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 
159 template <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 
161 template <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 
182 namespace nonstd {
183 namespace variants {
184 namespace detail {
185 
186 template <std::size_t K> struct index_tag_t {};
187 
188 template <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 
214 namespace nonstd {
215 
216 using std::bad_variant_access;
217 using std::hash;
218 using std::monostate;
219 using std::variant;
220 using std::variant_alternative;
221 using std::variant_alternative_t;
222 using std::variant_size;
223 using std::variant_size_v;
224 
225 using std::get;
226 using std::get_if;
227 using std::holds_alternative;
228 using std::visit;
229 using std::operator==;
230 using std::operator!=;
231 using std::operator<;
232 using std::operator<=;
233 using std::operator>;
234 using std::operator>=;
235 using std::swap;
236 
237 constexpr 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 
423 namespace nonstd {
424 namespace variants {
425 
426 // C++11 emulation:
427 
428 namespace std11 {
429 
430 #if variant_HAVE_STD_ADD_POINTER
431 
432 using std::add_pointer;
433 
434 #elif variant_HAVE_TR1_ADD_POINTER
435 
436 using std::tr1::add_pointer;
437 
438 #else
439 
440 template <class T> struct remove_reference { typedef T type; };
441 template <class T> struct remove_reference<T&> { typedef T type; };
442 
443 template <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 
449 using std::remove_cv;
450 
451 #else
452 
453 template <class T> struct remove_const { typedef T type; };
454 template <class T> struct remove_const<const T> { typedef T type; };
455 
456 template <class T> struct remove_volatile { typedef T type; };
457 template <class T> struct remove_volatile<volatile T> { typedef T type; };
458 
459 template <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 
465 using std::conditional;
466 
467 #else
468 
469 template <bool Cond, class Then, class Else> struct conditional;
470 
471 template <class Then, class Else> struct conditional<true, Then, Else> { typedef Then type; };
472 
473 template <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 
479 using std::enable_if;
480 
481 #else
482 
483 template <bool B, class T = void> struct enable_if {};
484 
485 template <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 
491 using std::is_same;
492 
493 #else
494 
495 template <class T, class U> struct is_same {
496  enum V { value = 0 };
497 };
498 
499 template <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 
525 namespace std17 {
526 
527 #if variant_CPP17_OR_GREATER
528 
529 using std::is_nothrow_swappable;
530 using std::is_swappable;
531 
532 #elif variant_CPP11_OR_GREATER
533 
534 namespace detail {
535 
536 using std::swap;
537 
538 struct 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 
544 struct 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 
558 template <typename T> struct is_swappable : decltype(detail::is_swappable::test<T>(0)) {};
559 
560 template <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 
568 namespace 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 
597 template <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 
627 struct S0 {};
628 typedef TX<S0> T0;
629 struct S1 {};
630 typedef TX<S1> T1;
631 struct S2 {};
632 typedef TX<S2> T2;
633 struct S3 {};
634 typedef TX<S3> T3;
635 struct S4 {};
636 typedef TX<S4> T4;
637 struct S5 {};
638 typedef TX<S5> T5;
639 struct S6 {};
640 typedef TX<S6> T6;
641 struct S7 {};
642 typedef TX<S7> T7;
643 struct S8 {};
644 typedef TX<S8> T8;
645 struct S9 {};
646 typedef TX<S9> T9;
647 struct S10 {};
648 typedef TX<S10> T10;
649 struct S11 {};
650 typedef TX<S11> T11;
651 struct S12 {};
652 typedef TX<S12> T12;
653 struct S13 {};
654 typedef TX<S13> T13;
655 struct S14 {};
656 typedef TX<S14> T14;
657 struct S15 {};
658 typedef TX<S15> T15;
659 
660 struct nulltype {};
661 
662 template <class Head, class Tail> struct typelist {
663  typedef Head head;
664  typedef Tail tail;
665 };
666 
667 // typelist max element size:
668 
669 template <class List> struct typelist_max;
670 
671 template <> struct typelist_max<nulltype> {
672  enum V { value = 0 };
673  typedef void type;
674 };
675 
676 template <class Head, class Tail> struct typelist_max<typelist<Head, Tail>> {
677 private:
678  enum TV { tail_value = size_t(typelist_max<Tail>::value) };
679 
680  typedef typename typelist_max<Tail>::type tail_type;
681 
682 public:
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 
692 template <class List> struct typelist_max_alignof;
693 
694 template <> struct typelist_max_alignof<nulltype> {
695  enum V { value = 0 };
696 };
697 
698 template <class Head, class Tail> struct typelist_max_alignof<typelist<Head, Tail>> {
699 private:
700  enum TV { tail_value = size_t(typelist_max_alignof<Tail>::value) };
701 
702 public:
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 
710 template <class List> struct typelist_size {
711  enum V { value = 1 };
712 };
713 
714 template <> struct typelist_size<T0> {
715  enum V { value = 0 };
716 };
717 template <> struct typelist_size<T1> {
718  enum V { value = 0 };
719 };
720 template <> struct typelist_size<T2> {
721  enum V { value = 0 };
722 };
723 template <> struct typelist_size<T3> {
724  enum V { value = 0 };
725 };
726 template <> struct typelist_size<T4> {
727  enum V { value = 0 };
728 };
729 template <> struct typelist_size<T5> {
730  enum V { value = 0 };
731 };
732 template <> struct typelist_size<T6> {
733  enum V { value = 0 };
734 };
735 template <> struct typelist_size<T7> {
736  enum V { value = 0 };
737 };
738 template <> struct typelist_size<T8> {
739  enum V { value = 0 };
740 };
741 template <> struct typelist_size<T9> {
742  enum V { value = 0 };
743 };
744 template <> struct typelist_size<T10> {
745  enum V { value = 0 };
746 };
747 template <> struct typelist_size<T11> {
748  enum V { value = 0 };
749 };
750 template <> struct typelist_size<T12> {
751  enum V { value = 0 };
752 };
753 template <> struct typelist_size<T13> {
754  enum V { value = 0 };
755 };
756 template <> struct typelist_size<T14> {
757  enum V { value = 0 };
758 };
759 template <> struct typelist_size<T15> {
760  enum V { value = 0 };
761 };
762 
763 template <> struct typelist_size<nulltype> {
764  enum V { value = 0 };
765 };
766 
767 template <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 
773 template <class List, class T> struct typelist_index_of;
774 
775 template <class T> struct typelist_index_of<nulltype, T> {
776  enum V { value = -1 };
777 };
778 
779 template <class Tail, class T> struct typelist_index_of<typelist<T, Tail>, T> {
780  enum V { value = 0 };
781 };
782 
783 template <class Head, class Tail, class T> struct typelist_index_of<typelist<Head, Tail>, T> {
784 private:
785  enum TV { nextVal = typelist_index_of<Tail, T>::value };
786 
787 public:
788  enum V { value = nextVal == -1 ? -1 : 1 + nextVal };
789 };
790 
791 // typelist type at index:
792 
793 template <class List, std::size_t i> struct typelist_type_at;
794 
795 template <class Head, class Tail> struct typelist_type_at<typelist<Head, Tail>, 0> { typedef Head type; };
796 
797 template <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 
803 template <class List, std::size_t CmpIndex, std::size_t LastChecked = typelist_size<List>::value> struct typelist_type_is_unique {
804 private:
805  typedef typename typelist_type_at<List, CmpIndex>::type cmp_type;
806  typedef typename typelist_type_at<List, LastChecked - 1>::type cur_type;
807 
808 public:
809  enum V {
810  value = ((CmpIndex == (LastChecked - 1)) | !std11::is_same<cmp_type, cur_type>::value) &&
812  };
813 };
814 
815 template <class List, std::size_t CmpIndex> struct typelist_type_is_unique<List, CmpIndex, 0> {
816  enum V { value = 1 };
817 };
818 
819 template <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 
833 template <class T> struct struct_t { T _; };
834 
835 union 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 
885 template <typename T> struct alignment_of;
886 
887 template <typename T> struct alignment_of_hack {
888  char c;
889  T t;
891 };
892 
893 template <size_t A, size_t S> struct alignment_logic {
894  enum V { value = A < S ? A : S };
895 };
896 
897 template <typename T> struct alignment_of {
898  enum V { value = alignment_logic<sizeof(alignment_of_hack<T>) - sizeof(T), sizeof(T)>::value };
899 };
900 
901 template <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 
906 template <size_t N> struct type_of_size<nulltype, N> { typedef variant_CONFIG_ALIGN_AS_FALLBACK type; };
907 
908 template <typename T> struct struct_t { T _; };
909 
910 #define variant_ALIGN_TYPE(type) typelist < type, typelist < struct_t<type>
911 
912 struct Unknown;
913 
914 typedef 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 
930 template <typename T> inline std::size_t hash(T const& v) { return std::hash<T>()(v); }
931 
932 inline std::size_t hash(T0 const&) { return 0; }
933 inline std::size_t hash(T1 const&) { return 0; }
934 inline std::size_t hash(T2 const&) { return 0; }
935 inline std::size_t hash(T3 const&) { return 0; }
936 inline std::size_t hash(T4 const&) { return 0; }
937 inline std::size_t hash(T5 const&) { return 0; }
938 inline std::size_t hash(T6 const&) { return 0; }
939 inline std::size_t hash(T7 const&) { return 0; }
940 inline std::size_t hash(T8 const&) { return 0; }
941 inline std::size_t hash(T9 const&) { return 0; }
942 inline std::size_t hash(T10 const&) { return 0; }
943 inline std::size_t hash(T11 const&) { return 0; }
944 inline std::size_t hash(T12 const&) { return 0; }
945 inline std::size_t hash(T13 const&) { return 0; }
946 inline std::size_t hash(T14 const&) { return 0; }
947 inline std::size_t hash(T15 const&) { return 0; }
948 
949 #endif // variant_CPP11_OR_GREATER
950 
951 template <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>
953 struct 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 
1255 template <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>
1257 class variant;
1258 
1259 // 19.7.8 Class monostate
1260 
1261 class monostate {};
1262 
1263 // 19.7.9 monostate relational operators
1264 
1265 inline variant_constexpr bool operator<(monostate, monostate) variant_noexcept { return false; }
1266 inline variant_constexpr bool operator>(monostate, monostate) variant_noexcept { return false; }
1267 inline variant_constexpr bool operator<=(monostate, monostate) variant_noexcept { return true; }
1268 inline variant_constexpr bool operator>=(monostate, monostate) variant_noexcept { return true; }
1269 inline variant_constexpr bool operator==(monostate, monostate) variant_noexcept { return true; }
1270 inline 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 
1276 template <class T> struct variant_size; /* undefined */
1277 
1278 template <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>
1280 struct 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
1285 template <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 
1294 template <std::size_t K, class T> struct variant_alternative; /* undefined */
1295 
1296 template <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>
1298 struct 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
1304 template <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
1317 variant_constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
1318 #else
1319 static 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 
1326 class bad_variant_access : public std::exception {
1327 public:
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 
1342 template <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>
1345 class variant {
1347  typedef variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) variant_types;
1348 
1349 public:
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)
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)
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 
2004 private:
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 
2133 private:
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 
2171 template <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>
2173 inline 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 
2177 template <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 
2184 template <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>
2186 inline 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 
2191 template <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>
2193 inline typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>::type&
2194 get(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>& v,
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 
2206 template <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>
2208 inline typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>::type const&
2209 get(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& v,
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 
2223 template <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>
2225 inline R&& get(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>&& v,
2226  nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2227  return std::move(v.template get<R>());
2228 }
2229 
2230 template <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>
2232 inline R const&& get(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const&& v,
2233  nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R)) {
2234  return std::move(v.template get<R>());
2235 }
2236 
2237 template <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>
2239 inline typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>::type&&
2240 get(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>&& v,
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 
2252 template <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>
2254 inline typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>::type const&&
2255 get(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const&& v,
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 
2269 template <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>
2271 inline 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)) {
2273  return (pv->index() == variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::template index_of<T>())
2274  ? &get<T>(*pv)
2275  : variant_nullptr;
2276 }
2277 
2278 template <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>
2280 inline typename std11::add_pointer<const T>::type
2281 get_if(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const* pv,
2282  nonstd_lite_in_place_type_t(T) = nonstd_lite_in_place_type(T)) {
2283  return (pv->index() == variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::template index_of<T>())
2284  ? &get<T>(*pv)
2285  : variant_nullptr;
2286 }
2287 
2288 template <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>
2290 inline typename std11::add_pointer<
2291  typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>::type>::type
2292 get_if(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>* pv,
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 
2297 template <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>
2299 inline typename std11::add_pointer<
2300  const typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>::type>::type
2301 get_if(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const* pv,
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 
2308 template <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  >
2327 inline void swap(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>& a,
2328  variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>& b)
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 
2340 namespace detail {
2341 
2342 template <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 
2346 template <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 
2353 template <typename R> struct VisitorApplicator;
2354 
2355 template <typename R, typename Visitor, typename V1> struct VisitorUnwrapper;
2356 
2357 #if variant_CPP11_OR_GREATER
2358 template <size_t NumVars, typename R, typename Visitor, typename... T>
2359 #else
2360 template <size_t NumVars, typename R, typename Visitor, typename T1, typename T2 = S0, typename T3 = S0, typename T4 = S0, typename T5 = S0>
2361 #endif
2363 
2364 template <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 
2377 template <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 
2392 template <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 
2409 template <typename R, typename Visitor, typename T2, typename T3, typename T4, typename T5>
2410 struct 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 
2429 template <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 {
2443  typedef TypedVisitorUnwrapper<3, R, Visitor, T1, T2> visitor_type;
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 
2465 template <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
2510  typedef typename variant_alternative<Idx, typename std::decay<V1>::type>::type value_type;
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
2557 template <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
2566 template <typename Visitor, typename... V>
2567 inline 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 
2573 template <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 
2577 template <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 
2581 template <typename R, typename Visitor, typename V1, typename V2, typename V3>
2582 inline 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 
2586 template <typename R, typename Visitor, typename V1, typename V2, typename V3, typename V4>
2587 inline 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 
2591 template <typename R, typename Visitor, typename V1, typename V2, typename V3, typename V4, typename V5>
2592 inline 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 
2600 namespace detail {
2601 
2602 template <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 
2686 template <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 
2698 template <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 
2705 template <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>
2707 inline 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 
2721 template <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>
2723 inline bool operator>(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& v,
2724  variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& w) {
2725  return w < v;
2726 }
2727 
2728 template <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>
2730 inline bool operator<=(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& v,
2731  variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& w) {
2732  return !(v > w);
2733 }
2734 
2735 template <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>
2737 inline bool operator>=(variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& v,
2738  variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const& w) {
2739  return !(v < w);
2740 }
2741 
2742 } // namespace variants
2743 
2744 using namespace variants;
2745 
2746 } // namespace nonstd
2747 
2748 #if variant_CPP11_OR_GREATER
2749 
2750 // 19.7.12 Hash support
2751 
2752 namespace std {
2753 
2754 template <> struct hash<nonstd::monostate> {
2755  std::size_t operator()(nonstd::monostate) const variant_noexcept { return 42; }
2756 };
2757 
2758 template <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>
2760 struct hash<nonstd::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> {
2761  std::size_t
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