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