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