RESTinio
variant.hpp
Go to the documentation of this file.
1 // Copyright 2016-2018 by Martin Moene
2 //
3 // https://github.com/martinmoene/variant-lite
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #pragma once
9 
10 #ifndef NONSTD_VARIANT_LITE_HPP
11 #define NONSTD_VARIANT_LITE_HPP
12 
13 #define variant_lite_VERSION "1.0.0"
14 
15 // variant-lite configuration:
16 
17 #ifndef variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
18 # define variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO 0
19 #endif
20 
21 #ifndef variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
22 # define variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO 0
23 #endif
24 
25 // Compiler detection:
26 
27 #ifdef _MSVC_LANG
28 # define variant_MSVC_LANG _MSVC_LANG
29 #else
30 # define variant_MSVC_LANG 0
31 #endif
32 
33 #define variant_CPP11_OR_GREATER ( __cplusplus >= 201103L || variant_MSVC_LANG >= 201103L )
34 #define variant_CPP14_OR_GREATER ( __cplusplus >= 201402L || variant_MSVC_LANG >= 201703L )
35 #define variant_CPP17_OR_GREATER ( __cplusplus >= 201703L || variant_MSVC_LANG >= 201703L )
36 
37 // use C++17 std::variant if available:
38 
39 #if defined( __has_include )
40 # define variant_HAS_INCLUDE( arg ) __has_include( arg )
41 #else
42 # define variant_HAS_INCLUDE( arg ) 0
43 #endif
44 
46 
47 #define variant_HAVE_STD_VARIANT 1
48 
49 #include <variant>
50 
51 #if ! variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
52 # define variant_size_V(T) nonstd::variant_size<T>::value
53 #endif
54 
55 #if ! variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
56 # define variant_alternative_T(I,T) typename nonstd::variant_alternative<I,T >::type
57 #endif
58 
59 namespace nonstd {
60 
61  using std::variant;
62  using std::monostate;
63  using std::bad_variant_access;
64  using std::variant_size;
65  using std::variant_size_v;
66  using std::variant_alternative;
67  using std::variant_alternative_t;
68  using std::hash;
69 
70  using std::in_place;
71  using std::in_place_type;
72  using std::in_place_index;
73  using std::in_place_t;
74  using std::in_place_type_t;
75  using std::in_place_index_t;
76 
77  using std::visit;
78  using std::holds_alternative;
79  using std::get;
80  using std::get_if;
81  using std::operator==;
82  using std::operator!=;
83  using std::operator<;
84  using std::operator<=;
85  using std::operator>;
86  using std::operator>=;
87  using std::swap;
88 
89  constexpr auto variant_npos = std::variant_npos;
90 
91 }
92 
93 #else // C++17 std::variant
94 
95 #include <cstddef>
96 #include <limits>
97 #include <new>
98 #include <stdexcept>
99 #include <utility>
100 
101 // variant-lite alignment configuration:
102 
103 #ifndef variant_CONFIG_MAX_ALIGN_HACK
104 # define variant_CONFIG_MAX_ALIGN_HACK 0
105 #endif
106 
107 #ifndef variant_CONFIG_ALIGN_AS
108 // no default, used in #if defined()
109 #endif
110 
111 #ifndef variant_CONFIG_ALIGN_AS_FALLBACK
112 # define variant_CONFIG_ALIGN_AS_FALLBACK double
113 #endif
114 
115 // half-open range [lo..hi):
116 #define variant_BETWEEN( v, lo, hi ) ( lo <= v && v < hi )
117 
118 #if defined(_MSC_VER) && !defined(__clang__)
119 # define variant_COMPILER_MSVC_VERSION (_MSC_VER / 100 - 5 - (_MSC_VER < 1900))
120 #else
121 # define variant_COMPILER_MSVC_VERSION 0
122 #endif
123 
124 #if defined __GNUC__
125 # define variant_COMPILER_GNUC_VERSION __GNUC__
126 #else
127 # define variant_COMPILER_GNUC_VERSION 0
128 #endif
129 
131 # pragma warning( push )
132 # pragma warning( disable: 4345 ) // initialization behavior changed
133 #endif
134 
135 // Presence of C++11 language features:
136 
138 # define variant_HAVE_AUTO 1
139 # define variant_HAVE_NULLPTR 1
140 # define variant_HAVE_STATIC_ASSERT 1
141 #endif
142 
144 # define variant_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1
145 # define variant_HAVE_INITIALIZER_LIST 1
146 #endif
147 
149 # define variant_HAVE_ALIAS_TEMPLATE 1
150 # define variant_HAVE_CONSTEXPR_11 1
151 # define variant_HAVE_ENUM_CLASS 1
152 # define variant_HAVE_EXPLICIT_CONVERSION 1
153 # define variant_HAVE_IS_DEFAULT 1
154 # define variant_HAVE_IS_DELETE 1
155 # define variant_HAVE_NOEXCEPT 1
156 # define variant_HAVE_OVERRIDE 1
157 #endif
158 
159 // Presence of C++14 language features:
160 
162 # define variant_HAVE_CONSTEXPR_14 1
163 #endif
164 
165 // Presence of C++17 language features:
166 
168 # define variant_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE 1
169 #endif
170 
171 // Presence of C++ library features:
172 
174 # define variant_HAVE_TR1_TYPE_TRAITS 1
175 # define variant_HAVE_TR1_ADD_POINTER 1
176 #endif
177 
179 # define variant_HAVE_TYPE_TRAITS 1
180 # define variant_HAVE_STD_ADD_POINTER 1
181 #endif
182 
184 # define variant_HAVE_ARRAY 1
185 #endif
186 
188 # define variant_HAVE_CONDITIONAL 1
189 #endif
190 
192 # define variant_HAVE_CONTAINER_DATA_METHOD 1
193 #endif
194 
196 # define variant_HAVE_REMOVE_CV 1
197 #endif
198 
200 # define variant_HAVE_SIZED_TYPES 1
201 #endif
202 
203 // For the rest, consider VC14 as C++11 for variant-lite:
204 
206 # undef variant_CPP11_OR_GREATER
207 # define variant_CPP11_OR_GREATER 1
208 #endif
209 
210 // C++ feature usage:
211 
212 #if variant_HAVE_CONSTEXPR_11
213 # define variant_constexpr constexpr
214 #else
215 # define variant_constexpr /*constexpr*/
216 #endif
217 
218 #if variant_HAVE_CONSTEXPR_14
219 # define variant_constexpr14 constexpr
220 #else
221 # define variant_constexpr14 /*constexpr*/
222 #endif
223 
224 #if variant_HAVE_NOEXCEPT
225 # define variant_noexcept noexcept
226 #else
227 # define variant_noexcept /*noexcept*/
228 #endif
229 
230 #if variant_HAVE_NULLPTR
231 # define variant_nullptr nullptr
232 #else
233 # define variant_nullptr NULL
234 #endif
235 
236 #if variant_HAVE_OVERRIDE
237 # define variant_override override
238 #else
239 # define variant_override /*override*/
240 #endif
241 
242 // additional includes:
243 
244 #if variant_HAVE_INITIALIZER_LIST
245 # include <initializer_list>
246 #endif
247 
248 #if variant_HAVE_TYPE_TRAITS
249 # include <type_traits>
250 #elif variant_HAVE_TR1_TYPE_TRAITS
251 # include <tr1/type_traits>
252 #endif
253 
254 //
255 // in_place: code duplicated in any-lite, optional-lite, variant-lite:
256 //
257 
258 #if ! nonstd_lite_HAVE_IN_PLACE_TYPES
259 
260 namespace nonstd {
261 
262 namespace detail {
263 
264 template< class T >
265 struct in_place_type_tag {};
266 
267 template< std::size_t I >
268 struct in_place_index_tag {};
269 
270 } // namespace detail
271 
272 struct in_place_t {};
273 
274 template< class T >
276 {
277  return in_place_t();
278 }
279 
280 template< std::size_t I >
282 {
283  return in_place_t();
284 }
285 
286 template< class T >
288 {
289  return in_place_t();
290 }
291 
292 template< std::size_t I >
294 {
295  return in_place_t();
296 }
297 
298 // mimic templated typedef:
299 
300 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
301 #define nonstd_lite_in_place_index_t(T) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<I> )
302 
303 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
304 
305 } // namespace nonstd
306 
307 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
308 
309 //
310 // variant:
311 //
312 
313 namespace nonstd { namespace variants {
314 
315 namespace detail {
316 
317 // C++11 emulation:
318 
319 #if variant_HAVE_STD_ADD_POINTER
320 
321 using std::add_pointer;
322 
323 #elif variant_HAVE_TR1_ADD_POINTER
324 
325 using std::tr1::add_pointer;
326 
327 #else
328 
329 template< class T > struct remove_reference { typedef T type; };
330 template< class T > struct remove_reference<T&> { typedef T type; };
331 
332 template< class T > struct add_pointer
333 {
334  typedef typename remove_reference<T>::type * type;
335 };
336 
337 #endif // variant_HAVE_STD_ADD_POINTER
338 
339 #if variant_HAVE_REMOVE_CV
340 
341 using std::remove_cv;
342 
343 #else
344 
345 template< class T > struct remove_const { typedef T type; };
346 template< class T > struct remove_const<const T> { typedef T type; };
347 
348 template< class T > struct remove_volatile { typedef T type; };
349 template< class T > struct remove_volatile<volatile T> { typedef T type; };
350 
351 template< class T >
352 struct remove_cv
353 {
354  typedef typename remove_volatile<typename remove_const<T>::type>::type type;
355 };
356 
357 #endif // variant_HAVE_REMOVE_CV
358 
359 #if variant_HAVE_CONDITIONAL
360 
361 using std::conditional;
362 
363 #else
364 
365 template< bool Cond, class Then, class Else >
366 struct conditional;
367 
368 template< class Then, class Else >
369 struct conditional< true , Then, Else > { typedef Then type; };
370 
371 template< class Then, class Else >
372 struct conditional< false, Then, Else > { typedef Else type; };
373 
374 #endif // variant_HAVE_CONDITIONAL
375 
376 // typelist:
377 
378 #define variant_TL1( T1 ) detail::typelist< T1, detail::nulltype >
379 #define variant_TL2( T1, T2 ) detail::typelist< T1, variant_TL1( T2) >
380 #define variant_TL3( T1, T2, T3 ) detail::typelist< T1, variant_TL2( T2, T3 ) >
381 #define variant_TL4( T1, T2, T3, T4 ) detail::typelist< T1, variant_TL3( T2, T3, T4 ) >
382 #define variant_TL5( T1, T2, T3, T4, T5 ) detail::typelist< T1, variant_TL4( T2, T3, T4, T5 ) >
383 #define variant_TL6( T1, T2, T3, T4, T5, T6 ) detail::typelist< T1, variant_TL5( T2, T3, T4, T5, T6 ) >
384 #define variant_TL7( T1, T2, T3, T4, T5, T6, T7 ) detail::typelist< T1, variant_TL6( T2, T3, T4, T5, T6, T7 ) >
385 
386 // variant parameter unused type tags:
387 
388 template< class T >
389 struct TX : T
390 {
391  inline TX<T> operator+ ( ) const { return TX<T>(); }
392  inline TX<T> operator- ( ) const { return TX<T>(); }
393 
394  inline TX<T> operator! ( ) const { return TX<T>(); }
395  inline TX<T> operator~ ( ) const { return TX<T>(); }
396 
397  inline TX<T>*operator& ( ) const { return variant_nullptr; }
398 
399  template< class U > inline TX<T> operator* ( U const & ) const { return TX<T>(); }
400  template< class U > inline TX<T> operator/ ( U const & ) const { return TX<T>(); }
401 
402  template< class U > inline TX<T> operator% ( U const & ) const { return TX<T>(); }
403  template< class U > inline TX<T> operator+ ( U const & ) const { return TX<T>(); }
404  template< class U > inline TX<T> operator- ( U const & ) const { return TX<T>(); }
405 
406  template< class U > inline TX<T> operator<<( U const & ) const { return TX<T>(); }
407  template< class U > inline TX<T> operator>>( U const & ) const { return TX<T>(); }
408 
409  inline bool operator==( T const & ) const { return false; }
410  inline bool operator< ( T const & ) const { return false; }
411 
412  template< class U > inline TX<T> operator& ( U const & ) const { return TX<T>(); }
413  template< class U > inline TX<T> operator| ( U const & ) const { return TX<T>(); }
414  template< class U > inline TX<T> operator^ ( U const & ) const { return TX<T>(); }
415 
416  template< class U > inline TX<T> operator&&( U const & ) const { return TX<T>(); }
417  template< class U > inline TX<T> operator||( U const & ) const { return TX<T>(); }
418 };
419 
420 struct S0{}; typedef TX<S0> T0;
421 struct S1{}; typedef TX<S1> T1;
422 struct S2{}; typedef TX<S2> T2;
423 struct S3{}; typedef TX<S3> T3;
424 struct S4{}; typedef TX<S4> T4;
425 struct S5{}; typedef TX<S5> T5;
426 struct S6{}; typedef TX<S6> T6;
427 
428 struct nulltype{};
429 
430 template< class Head, class Tail >
431 struct typelist
432 {
433  typedef Head head;
434  typedef Tail tail;
435 };
436 
437 // typelist max element size:
438 
439 template< class List >
440 struct typelist_max;
441 
442 template <>
443 struct typelist_max< nulltype >
444 {
445  enum { value = 0 } ;
446  typedef void type;
447 };
448 
449 template< class Head, class Tail >
450 struct typelist_max< typelist<Head, Tail> >
451 {
452 private:
453  enum { tail_value = size_t( typelist_max<Tail>::value ) };
454 
455  typedef typename typelist_max<Tail>::type tail_type;
456 
457 public:
458  enum { value = (sizeof( Head ) > tail_value) ? sizeof( Head ) : std::size_t( tail_value ) } ;
459 
460  typedef typename conditional< (sizeof( Head ) > tail_value), Head, tail_type>::type type;
461 };
462 
464 
465 // typelist max alignof element type:
466 
467 template< class List >
468 struct typelist_max_alignof;
469 
470 template <>
471 struct typelist_max_alignof< nulltype >
472 {
473  enum { value = 0 } ;
474 };
475 
476 template< class Head, class Tail >
477 struct typelist_max_alignof< typelist<Head, Tail> >
478 {
479 private:
480  enum { tail_value = size_t( typelist_max_alignof<Tail>::value ) };
481 
482 public:
483  enum { value = (alignof( Head ) > tail_value) ? alignof( Head ) : std::size_t( tail_value ) };
484 };
485 
486 #endif
487 
488 // typelist size (length):
489 
490 template< class List >
492 {
493  enum { value = 1 };
494 };
495 
496 template<> struct typelist_size< T0 > { enum { value = 0 }; };
497 template<> struct typelist_size< T1 > { enum { value = 0 }; };
498 template<> struct typelist_size< T2 > { enum { value = 0 }; };
499 template<> struct typelist_size< T3 > { enum { value = 0 }; };
500 template<> struct typelist_size< T4 > { enum { value = 0 }; };
501 template<> struct typelist_size< T5 > { enum { value = 0 }; };
502 template<> struct typelist_size< T6 > { enum { value = 0 }; };
503 
504 template<> struct typelist_size< nulltype > { enum { value = 0 } ; };
505 
506 template< class Head, class Tail >
507 struct typelist_size< typelist<Head, Tail> >
508 {
509  enum { value = typelist_size<Head>::value + typelist_size<Tail>::value };
510 };
511 
512 // typelist index of type:
513 
514 template< class List, class T >
515 struct typelist_index_of;
516 
517 template< class T >
518 struct typelist_index_of< nulltype, T >
519 {
520  enum { value = -1 };
521 };
522 
523 template< class Tail, class T >
524 struct typelist_index_of< typelist<T, Tail>, T >
525 {
526  enum { value = 0 };
527 };
528 
529 template< class Head, class Tail, class T >
530 struct typelist_index_of< typelist<Head, Tail>, T >
531 {
532 private:
533  enum { nextVal = typelist_index_of<Tail, T>::value };
534 public:
535  enum { value = nextVal == -1 ? -1 : 1 + nextVal } ;
536 };
537 
538 // typelist type at index:
539 
540 template< class List, std::size_t i>
541 struct typelist_type_at;
542 
543 template< class Head, class Tail >
544 struct typelist_type_at< typelist<Head, Tail>, 0 >
545 {
546  typedef Head type;
547 };
548 
549 template< class Head, class Tail, std::size_t i >
550 struct typelist_type_at< typelist<Head, Tail>, i >
551 {
552  typedef typename typelist_type_at<Tail, i - 1>::type type;
553 };
554 
556 
557 // Max align, use most restricted type for alignment:
558 
559 #define variant_UNIQUE( name ) variant_UNIQUE2( name, __LINE__ )
560 #define variant_UNIQUE2( name, line ) variant_UNIQUE3( name, line )
561 #define variant_UNIQUE3( name, line ) name ## line
562 
563 #define variant_ALIGN_TYPE( type )
564  type variant_UNIQUE( _t ); struct_t< type > variant_UNIQUE( _st )
565 
566 template< class T >
567 struct struct_t { T _; };
568 
569 union max_align_t
570 {
571  variant_ALIGN_TYPE( char );
572  variant_ALIGN_TYPE( short int );
573  variant_ALIGN_TYPE( int );
574  variant_ALIGN_TYPE( long int );
575  variant_ALIGN_TYPE( float );
576  variant_ALIGN_TYPE( double );
577  variant_ALIGN_TYPE( long double );
578  variant_ALIGN_TYPE( char * );
579  variant_ALIGN_TYPE( short int * );
580  variant_ALIGN_TYPE( int * );
581  variant_ALIGN_TYPE( long int * );
582  variant_ALIGN_TYPE( float * );
583  variant_ALIGN_TYPE( double * );
584  variant_ALIGN_TYPE( long double * );
585  variant_ALIGN_TYPE( void * );
586 
587 #ifdef HAVE_LONG_LONG
588  variant_ALIGN_TYPE( long long );
589 #endif
590 
591  struct Unknown;
592 
593  Unknown ( * variant_UNIQUE(_) )( Unknown );
596 
600 };
601 
602 #undef variant_UNIQUE
603 #undef variant_UNIQUE2
604 #undef variant_UNIQUE3
605 
606 #undef variant_ALIGN_TYPE
607 
608 #elif defined( variant_CONFIG_ALIGN_AS ) // variant_CONFIG_MAX_ALIGN_HACK
609 
610 // Use user-specified type for alignment:
611 
612 #define variant_ALIGN_AS( unused )
613  variant_CONFIG_ALIGN_AS
614 
615 #else // variant_CONFIG_MAX_ALIGN_HACK
616 
617 // Determine POD type to use for alignment:
618 
619 #define variant_ALIGN_AS( to_align )
620  typename detail::type_of_size< detail::alignment_types, detail::alignment_of< to_align >::value >::type
621 
622 template <typename T>
623 struct alignment_of;
624 
625 template <typename T>
627 {
628  char c;
629  T t;
631 };
632 
633 template <unsigned A, unsigned S>
635 {
636  enum { value = A < S ? A : S };
637 };
638 
639 template< typename T >
640 struct alignment_of
641 {
643  sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value, };
644 };
645 
646 template< typename List, size_t N >
648 {
649  typedef typename conditional<
650  N == sizeof( typename List::head ),
651  typename List::head,
652  typename type_of_size<typename List::tail, N >::type >::type type;
653 };
654 
655 template< size_t N >
656 struct type_of_size< nulltype, N >
657 {
659 };
660 
661 template< typename T>
662 struct struct_t { T _; };
663 
664 #define variant_ALIGN_TYPE( type )
665  typelist< type , typelist< struct_t< type >
666 
667 struct Unknown;
668 
669 typedef
670  variant_ALIGN_TYPE( char ),
671  variant_ALIGN_TYPE( short ),
672  variant_ALIGN_TYPE( int ),
673  variant_ALIGN_TYPE( long ),
674  variant_ALIGN_TYPE( float ),
675  variant_ALIGN_TYPE( double ),
676  variant_ALIGN_TYPE( long double ),
677 
678  variant_ALIGN_TYPE( char *),
679  variant_ALIGN_TYPE( short * ),
680  variant_ALIGN_TYPE( int * ),
681  variant_ALIGN_TYPE( long * ),
682  variant_ALIGN_TYPE( float * ),
683  variant_ALIGN_TYPE( double * ),
684  variant_ALIGN_TYPE( long double * ),
685 
686  variant_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
687  variant_ALIGN_TYPE( Unknown * Unknown::* ),
688  variant_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
689 
690  nulltype
691  > > > > > > > > > > > > > >
692  > > > > > > > > > > > > > >
693  > > > > > >
695 
696 #undef variant_ALIGN_TYPE
697 
698 #endif // variant_CONFIG_MAX_ALIGN_HACK
699 
700 template< typename T>
701 inline std::size_t hash( T const & v )
702 {
703  // primes:
704  unsigned const int a = 54059;
705  unsigned const int b = 76963;
706  unsigned const int h0 = 37;
707 
708  unsigned int h = h0;
709  unsigned char const * s = reinterpret_cast<unsigned char const *>( &v );
710 
711  for ( std::size_t i = 0; i < sizeof(v); ++i, ++s )
712  {
713  h = (h * a) ^ (*s * b);
714  }
715  return h;
716 }
717 
718 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
719 struct helper
720 {
721  typedef signed char type_index_t;
722  typedef variant_TL7( T0, T1, T2, T3, T4, T5, T6 ) variant_types;
723 
724  template< class U >
725  static U * as( void * data )
726  {
727  return reinterpret_cast<U*>( data );
728  }
729 
730  template< class U >
731  static U const * as( void const * data )
732  {
733  return reinterpret_cast<const U*>( data );
734  }
735 
736  static type_index_t to_index_t( std::size_t index )
737  {
738  return static_cast<type_index_t>( index );
739  }
740 
741  static void destroy( std::size_t index, void * data )
742  {
743  switch ( index )
744  {
745  case 0: as<T0>( data )->~T0(); break;
746  case 1: as<T1>( data )->~T1(); break;
747  case 2: as<T2>( data )->~T2(); break;
748  case 3: as<T3>( data )->~T3(); break;
749  case 4: as<T4>( data )->~T4(); break;
750  case 5: as<T5>( data )->~T5(); break;
751  case 6: as<T6>( data )->~T6(); break;
752  }
753  }
754 
756  template< class T, class... Args >
757  static type_index_t construct_t( void * data, Args&&... args )
758  {
759  new( data ) T( std::forward<Args>(args)... );
760 
762  }
763 
764  template< std::size_t I, class... Args >
765  static type_index_t construct_i( void * data, Args&&... args )
766  {
767  using type = typename detail::typelist_type_at< variant_types, I >::type;
768 
769  construct_t< type >( data, std::forward<Args>(args)... );
770 
771  return to_index_t( I );
772  }
773 
774  static type_index_t move( std::size_t const from_index, void * from_value, void * to_value )
775  {
776  switch ( from_index )
777  {
778  case 0: new( to_value ) T0( std::forward<T0>( *as<T0>( from_value ) ) ); break;
779  case 1: new( to_value ) T1( std::forward<T1>( *as<T1>( from_value ) ) ); break;
780  case 2: new( to_value ) T2( std::forward<T2>( *as<T2>( from_value ) ) ); break;
781  case 3: new( to_value ) T3( std::forward<T3>( *as<T3>( from_value ) ) ); break;
782  case 4: new( to_value ) T4( std::forward<T4>( *as<T4>( from_value ) ) ); break;
783  case 5: new( to_value ) T5( std::forward<T5>( *as<T5>( from_value ) ) ); break;
784  case 6: new( to_value ) T6( std::forward<T6>( *as<T6>( from_value ) ) ); break;
785  }
786  return to_index_t( from_index );
787  }
788 #endif
789 
790  static type_index_t copy( std::size_t const from_index, const void * from_value, void * to_value )
791  {
792  switch ( from_index )
793  {
794  case 0: new( to_value ) T0( *as<T0>( from_value ) ); break;
795  case 1: new( to_value ) T1( *as<T1>( from_value ) ); break;
796  case 2: new( to_value ) T2( *as<T2>( from_value ) ); break;
797  case 3: new( to_value ) T3( *as<T3>( from_value ) ); break;
798  case 4: new( to_value ) T4( *as<T4>( from_value ) ); break;
799  case 5: new( to_value ) T5( *as<T5>( from_value ) ); break;
800  case 6: new( to_value ) T6( *as<T6>( from_value ) ); break;
801  }
802  return to_index_t( from_index );
803  }
804 };
805 
806 } // namespace detail
807 
808 //
809 // Variant:
810 //
811 
812 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
813 class variant;
814 
815 class monostate{};
816 
817 inline variant_constexpr bool operator< ( monostate, monostate ) variant_noexcept { return false; }
818 inline variant_constexpr bool operator> ( monostate, monostate ) variant_noexcept { return false; }
822 inline variant_constexpr bool operator!=( monostate, monostate ) variant_noexcept { return false; }
823 
824 // obtain the size of the variant's list of alternatives at compile time
825 
826 template< class T >
827 struct variant_size; /* undefined */
828 
829 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
830 struct variant_size< variant<T0, T1, T2, T3, T4, T5, T6> >
831 {
832  enum _ { value = detail::typelist_size< variant_TL7(T0, T1, T2, T3, T4, T5, T6) >::value };
833 };
834 
836 template< class T >
837 constexpr std::size_t variant_size_v = variant_size<T>::value;
838 #endif
839 
841 # define variant_size_V(T) nonstd::variant_size<T>::value
842 #endif
843 
844 // obtain the type of the alternative specified by its index, at compile time:
845 
846 template< std::size_t I, class T >
847 struct variant_alternative; /* undefined */
848 
849 template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
850 struct variant_alternative< I, variant<T0, T1, T2, T3, T4, T5, T6> >
851 {
852  typedef typename detail::typelist_type_at<variant_TL7(T0, T1, T2, T3, T4, T5, T6), I>::type type;
853 };
854 
856 template< std::size_t I, class T >
857 using variant_alternative_t = typename variant_alternative<I, T>::type;
858 #endif
859 
861 # define variant_alternative_T(I,T) typename nonstd::variant_alternative<I,T >::type
862 #endif
863 
864 // NTS:implement specializes the std::uses_allocator type trait
865 // std::uses_allocator<nonstd::variant>
866 
867 // index of the variant in the invalid state (constant)
868 
870 variant_constexpr std::size_t variant_npos = static_cast<std::size_t>( -1 );
871 #else
872 static const std::size_t variant_npos = static_cast<std::size_t>( -1 );
873 #endif
874 
876 {
877 public:
879  virtual const char* what() const variant_noexcept variant_override
880 #else
881  virtual const char* what() const throw()
882 #endif
883  {
884  return "bad variant access";
885  }
886 };
887 
888 template<
889  class T0,
890  class T1 = detail::T1,
891  class T2 = detail::T2,
892  class T3 = detail::T3,
893  class T4 = detail::T4,
894  class T5 = detail::T5,
895  class T6 = detail::T6
896 >
897 class variant
898 {
899  typedef detail::helper< T0, T1, T2, T3, T4, T5, T6 > helper_type;
900  typedef variant_TL7( T0, T1, T2, T3, T4, T5, T6 ) variant_types;
901 
902 public:
903  variant() : type_index( 0 ) { new( ptr() ) T0(); }
904 
905  variant( T0 const & t0 ) : type_index( 0 ) { new( ptr() ) T0( t0 ); }
906  variant( T1 const & t1 ) : type_index( 1 ) { new( ptr() ) T1( t1 ); }
907  variant( T2 const & t2 ) : type_index( 2 ) { new( ptr() ) T2( t2 ); }
908  variant( T3 const & t3 ) : type_index( 3 ) { new( ptr() ) T3( t3 ); }
909  variant( T4 const & t4 ) : type_index( 4 ) { new( ptr() ) T4( t4 ); }
910  variant( T5 const & t5 ) : type_index( 5 ) { new( ptr() ) T5( t5 ); }
911  variant( T6 const & t6 ) : type_index( 6 ) { new( ptr() ) T6( t6 ); }
912 
914  variant( T0 && t0 ) : type_index( 0 ) { new( ptr() ) T0( std::move( t0 ) ); }
915  variant( T1 && t1 ) : type_index( 1 ) { new( ptr() ) T1( std::move( t1 ) ); }
916  variant( T2 && t2 ) : type_index( 2 ) { new( ptr() ) T2( std::move( t2 ) ); }
917  variant( T3 && t3 ) : type_index( 3 ) { new( ptr() ) T3( std::move( t3 ) ); }
918  variant( T4 && t4 ) : type_index( 4 ) { new( ptr() ) T4( std::move( t4 ) ); }
919  variant( T5 && t5 ) : type_index( 5 ) { new( ptr() ) T5( std::move( t5 ) ); }
920  variant( T6 && t6 ) : type_index( 6 ) { new( ptr() ) T6( std::move( t6 ) ); }
921 #endif
922 
923  variant(variant const & rhs)
925  {
926  (void) helper_type::copy( rhs.type_index, rhs.ptr(), ptr() );
927  }
928 
930 
931  variant( variant && rhs )
933  {
934  (void) helper_type::move( rhs.type_index, rhs.ptr(), ptr() );
935  }
936 
937  template< std::size_t I >
938  using type_at_t = typename detail::typelist_type_at< variant_types, I >::type;
939 
940  template< class T, class... Args,
941  typename = typename std::enable_if< std::is_constructible< T, Args...>::value>::type >
942  explicit variant( nonstd_lite_in_place_type_t(T), Args&&... args)
943  {
945  type_index = helper_type::template construct_t<T>( ptr(), std::forward<Args>(args)... );
946  }
947 
948  template< class T, class U, class... Args,
949  typename = typename std::enable_if< std::is_constructible< T, std::initializer_list<U>&, Args...>::value>::type >
951  {
953  type_index = helper_type::template construct_t<T>( ptr(), il, std::forward<Args>(args)... );
954  }
955 
956  template< std::size_t I, class... Args,
957  typename = typename std::enable_if< std::is_constructible< type_at_t<I>, Args...>::value>::type >
958  explicit variant( nonstd_lite_in_place_index_t(I), Args&&... args )
959  {
961  type_index = helper_type::template construct_i<I>( ptr(), std::forward<Args>(args)... );
962  }
963 
964  template <size_t I, class U, class... Args,
965  typename = typename std::enable_if< std::is_constructible< type_at_t<I>, std::initializer_list<U>&, Args...>::value >::type >
967  {
969  type_index = helper_type::template construct_i<I>( ptr(), il, std::forward<Args>(args)... );
970  }
971 
972 #endif // variant_CPP11_OR_GREATER
973 
975  {
976  helper_type::destroy( index(), ptr() );
977  }
978 
979  variant & operator=( variant const & rhs )
980  {
981  return copy_assign( rhs );
982  }
983 
985 
986  variant & operator=( variant && rhs )
987  {
988  return move_assign( std::forward<variant>( rhs ) );
989  }
990 
991  variant & operator=( T0 && t0 ) { return move_assign_value<T0,0>( std::forward<T0>( t0 ) ); }
992  variant & operator=( T1 && t1 ) { return move_assign_value<T1,1>( std::forward<T1>( t1 ) ); }
993  variant & operator=( T2 && t2 ) { return move_assign_value<T2,2>( std::forward<T2>( t2 ) ); }
994  variant & operator=( T3 && t3 ) { return move_assign_value<T3,3>( std::forward<T3>( t3 ) ); }
995  variant & operator=( T4 && t4 ) { return move_assign_value<T4,4>( std::forward<T4>( t4 ) ); }
996  variant & operator=( T5 && t5 ) { return move_assign_value<T5,5>( std::forward<T5>( t5 ) ); }
997  variant & operator=( T6 && t6 ) { return move_assign_value<T6,6>( std::forward<T6>( t6 ) ); }
998 #else
999  variant & operator=( T0 const & t0 ) { return copy_assign_value<T0,0>( t0 ); }
1000  variant & operator=( T1 const & t1 ) { return copy_assign_value<T1,1>( t1 ); }
1001  variant & operator=( T2 const & t2 ) { return copy_assign_value<T2,2>( t2 ); }
1002  variant & operator=( T3 const & t3 ) { return copy_assign_value<T3,3>( t3 ); }
1003  variant & operator=( T4 const & t4 ) { return copy_assign_value<T4,4>( t4 ); }
1004  variant & operator=( T5 const & t5 ) { return copy_assign_value<T5,5>( t5 ); }
1005  variant & operator=( T6 const & t6 ) { return copy_assign_value<T6,6>( t6 ); }
1006 #endif
1007 
1008  std::size_t index() const
1009  {
1011  }
1012 
1014  {
1015  return type_index == variant_npos_internal();
1016  }
1017 
1019  template< class T, class... Args,
1020  typename = typename std::enable_if< std::is_constructible< T, Args...>::value>::type >
1021  void emplace( Args&&... args )
1022  {
1025  type_index = helper_type::template construct_t<T>( ptr(), std::forward<Args>(args)... );
1026  }
1027 
1028  template< class T, class U, class... Args,
1029  typename = typename std::enable_if< std::is_constructible< T, std::initializer_list<U>&, Args...>::value>::type >
1030  void emplace( std::initializer_list<U> il, Args&&... args )
1031  {
1034  type_index = helper_type::template construct_t<T>( ptr(), il, std::forward<Args>(args)... );
1035  }
1036 
1037  template< size_t I, class... Args,
1038  typename = typename std::enable_if< std::is_constructible< type_at_t<I>, Args...>::value>::type >
1039  void emplace( Args&&... args )
1040  {
1041  this->template emplace< type_at_t<I> >( std::forward<Args>(args)... );
1042  }
1043 
1044  template< size_t I, class U, class... Args,
1045  typename = typename std::enable_if< std::is_constructible< type_at_t<I>, std::initializer_list<U>&, Args...>::value >::type >
1046  void emplace( std::initializer_list<U> il, Args&&... args )
1047  {
1048  this->template emplace< type_at_t<I> >( il, std::forward<Args>(args)... );
1049  }
1050 
1051 #endif // variant_CPP11_OR_GREATER
1052 
1054  {
1056  {
1057  // no effect
1058  }
1059  else if ( index() == rhs.index() )
1060  {
1061  this->swap_value( index(), rhs );
1062  }
1063  else
1064  {
1065  variant tmp( *this );
1066  *this = rhs;
1067  rhs = tmp;
1068  }
1069  }
1070 
1071  //
1072  // non-standard:
1073  //
1074 
1075  template< class T >
1077  {
1079  }
1080 
1081  template< class T >
1082  T & get()
1083  {
1084  const std::size_t i = index_of<T>();
1085 
1086  if ( i != index() || i == max_index() )
1087  {
1088  throw bad_variant_access();
1089  }
1090 
1091  return *as<T>();
1092  }
1093 
1094  template< class T >
1095  T const & get() const
1096  {
1097  const std::size_t i = index_of<T>();
1098 
1099  if ( i != index() || i == max_index() )
1100  {
1101  throw bad_variant_access();
1102  }
1103 
1104  return *as<const T>();
1105  }
1106 
1107  template< std::size_t I >
1108  typename variant_alternative< I, variant >::type &
1110  {
1111  return this->template get< typename detail::typelist_type_at< variant_types, I >::type >();
1112  }
1113 
1114  template< std::size_t I >
1115  typename variant_alternative< I, variant >::type const &
1116  get() const
1117  {
1118  return this->template get< typename detail::typelist_type_at< variant_types, I >::type >();
1119  }
1120 
1121 private:
1123 
1125  {
1126  return &data;
1127  }
1128 
1129  void const * ptr() const variant_noexcept
1130  {
1131  return &data;
1132  }
1133 
1134  template< class U >
1135  U * as()
1136  {
1137  return reinterpret_cast<U*>( ptr() );
1138  }
1139 
1140  template< class U >
1141  U const * as() const
1142  {
1143  return reinterpret_cast<U const *>( ptr() );
1144  }
1145 
1147  {
1148  return data_size;
1149  }
1150 
1152  {
1153  return static_cast<type_index_t>( -1 );
1154  }
1155 
1156  variant & copy_assign( variant const & rhs )
1157  {
1159  {
1160  // no effect
1161  }
1163  {
1166  }
1167  else if ( index() == rhs.index() )
1168  {
1170  }
1171  else
1172  {
1173  // alas exception safety with pre-C++11 needs an extra copy:
1174 
1175  variant tmp( rhs );
1180 #else
1182 #endif
1183  }
1184  return *this;
1185  }
1186 
1188 
1189  variant & move_assign( variant && rhs )
1190  {
1192  {
1193  // no effect
1194  }
1196  {
1199  }
1200  else if ( index() == rhs.index() )
1201  {
1203  }
1204  else
1205  {
1209  }
1210  return *this;
1211  }
1212 
1213  template< class T, std::size_t I >
1214  variant & move_assign_value( T && value )
1215  {
1216  if( index() == I )
1217  {
1218  *as<T>() = std::forward<T>( value );
1219  }
1220  else
1221  {
1224  new( ptr() ) T( std::forward<T>( value ) );
1225  type_index = I;
1226  }
1227  return *this;
1228  }
1229 #else
1230  template< class T, std::size_t I >
1232  {
1233  if( index() == I )
1234  {
1235  *as<T>() = value;
1236  }
1237  else
1238  {
1241  new( ptr() ) T( value );
1242  type_index = I;
1243  }
1244  return *this;
1245  }
1246 
1247 #endif // variant_CPP11_OR_GREATER
1248 
1249  void swap_value( std::size_t index, variant & rhs )
1250  {
1251  using std::swap;
1252  switch( index )
1253  {
1254  case 0: swap( this->get<0>(), rhs.get<0>() ); break;
1255  case 1: swap( this->get<1>(), rhs.get<1>() ); break;
1256  case 2: swap( this->get<2>(), rhs.get<2>() ); break;
1257  case 3: swap( this->get<3>(), rhs.get<3>() ); break;
1258  case 4: swap( this->get<4>(), rhs.get<4>() ); break;
1259  case 5: swap( this->get<5>(), rhs.get<5>() ); break;
1260  case 6: swap( this->get<6>(), rhs.get<6>() ); break;
1261  }
1262  }
1263 
1264 private:
1265  enum { data_size = detail::typelist_max< variant_types >::value };
1266 
1268 
1269  enum { data_align = detail::typelist_max_alignof< variant_types >::value };
1270 
1272  aligned_storage_t data;
1273 
1274 #elif variant_CONFIG_MAX_ALIGN_HACK
1275 
1276  typedef union { unsigned char data[ data_size ]; } aligned_storage_t;
1277 
1280 
1281 #else
1283 
1285 
1286  typedef union { align_as_type data[ 1 + ( data_size - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
1288 
1289 // # undef variant_ALIGN_AS
1290 
1291 #endif // variant_CONFIG_MAX_ALIGN_HACK
1292 
1294 };
1295 
1296 template <class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1297 inline bool holds_alternative( variant<T0, T1, T2, T3, T4, T5, T6> const & v ) variant_noexcept
1298 {
1299  return v.index() == v.template index_of<T>();
1300 }
1301 
1302 template< class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1303 inline R & get( variant<T0, T1, T2, T3, T4, T5, T6> & v, nonstd_lite_in_place_type_t(R) = in_place<R> )
1304 {
1305  return v.template get<R>();
1306 }
1307 
1308 template< class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1309 inline R const & get( variant<T0, T1, T2, T3, T4, T5, T6> const & v, nonstd_lite_in_place_type_t(R) = in_place<R> )
1310 {
1311  return v.template get<R>();
1312 }
1313 
1314 template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1315 inline typename variant_alternative< I, variant<T0, T1, T2, T3, T4, T5, T6> >::type &
1316 get( variant<T0, T1, T2, T3, T4, T5, T6> & v, nonstd_lite_in_place_index_t(I) = in_place<I> )
1317 {
1318  if ( I != v.index() )
1319  {
1320  throw bad_variant_access();
1321  }
1322 
1323  return v.template get<I>();
1324 }
1325 
1326 template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1327 inline typename variant_alternative< I, variant<T0, T1, T2, T3, T4, T5, T6> >::type const &
1328 get( variant<T0, T1, T2, T3, T4, T5, T6> const & v, nonstd_lite_in_place_index_t(I) = in_place<I> )
1329 {
1330  if ( I != v.index() )
1331  {
1332  throw bad_variant_access();
1333  }
1334 
1335  return v.template get<I>();
1336 }
1337 
1338 template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1339 inline typename detail::add_pointer<T>::type
1341 {
1342  return ( pv->index() == pv->template index_of<T>() ) ? &get<T>( *pv ) : variant_nullptr;
1343 }
1344 
1345 template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1346 inline typename detail::add_pointer<const T>::type
1348 {
1349  return ( pv->index() == pv->template index_of<T>() ) ? &get<T>( *pv ) : variant_nullptr;
1350 }
1351 
1352 template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1353 inline typename detail::add_pointer< typename variant_alternative<I, variant<T0, T1, T2, T3, T4, T5, T6> >::type >::type
1355 {
1356  return ( pv->index() == I ) ? &get<I>( *pv ) : variant_nullptr;
1357 }
1358 
1359 template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1360 inline typename detail::add_pointer< const typename variant_alternative<I, variant<T0, T1, T2, T3, T4, T5, T6> >::type >::type
1362 {
1363  return ( pv->index() == I ) ? &get<I>( *pv ) : variant_nullptr;
1364 }
1365 
1366 template< class T0, class T1, class T2, class T3, class T4, class T5 >
1367 inline void swap(
1368  variant<T0, T1, T2, T3, T4, T5> & a,
1369  variant<T0, T1, T2, T3, T4, T5> & b ) variant_noexcept
1370 {
1371  a.swap( b );
1372 }
1373 
1374 // template <class Visitor, class... Variants>
1375 // visit( Visitor&& vis, Variants&&... vars );
1376 
1377 // The following visit is restricted with respect to the standard.
1378 // It uses the common idiom is to return anrhs variant:
1379 
1380 template< class Visitor, class Variant >
1381 inline Variant visit( Visitor const & vis, Variant const & v )
1382 {
1383  if ( v.valueless_by_exception() )
1384  {
1385  throw bad_variant_access();
1386  }
1387 
1388  switch( v.index() )
1389  {
1390  case 0: return vis( get<0>( v ) );
1391  case 1: return vis( get<1>( v ) );
1392  case 2: return vis( get<2>( v ) );
1393  case 3: return vis( get<3>( v ) );
1394  case 4: return vis( get<4>( v ) );
1395  case 5: return vis( get<5>( v ) );
1396  case 6: return vis( get<6>( v ) );
1397  default: return Variant();
1398  }
1399 }
1400 
1401 namespace detail {
1402 
1403 template< class Variant >
1405 {
1406  static inline bool equal( Variant const & v, Variant const & w )
1407  {
1408  switch( v.index() )
1409  {
1410  case 0: return get<0>( v ) == get<0>( w );
1411  case 1: return get<1>( v ) == get<1>( w );
1412  case 2: return get<2>( v ) == get<2>( w );
1413  case 3: return get<3>( v ) == get<3>( w );
1414  case 4: return get<4>( v ) == get<4>( w );
1415  case 5: return get<5>( v ) == get<5>( w );
1416  case 6: return get<6>( v ) == get<6>( w );
1417  default: return false;
1418  }
1419  }
1420 
1421  static inline bool less_than( Variant const & v, Variant const & w )
1422  {
1423  switch( v.index() )
1424  {
1425  case 0: return get<0>( v ) < get<0>( w );
1426  case 1: return get<1>( v ) < get<1>( w );
1427  case 2: return get<2>( v ) < get<2>( w );
1428  case 3: return get<3>( v ) < get<3>( w );
1429  case 4: return get<4>( v ) < get<4>( w );
1430  case 5: return get<5>( v ) < get<5>( w );
1431  case 6: return get<6>( v ) < get<6>( w );
1432  default: return false;
1433  }
1434  }
1435 };
1436 
1437 } //namespace detail
1438 
1439 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1440 inline bool operator==(
1441  variant<T0, T1, T2, T3, T4, T5, T6> const & v,
1442  variant<T0, T1, T2, T3, T4, T5, T6> const & w )
1443 {
1444  if ( v.index() != w.index() ) return false;
1445  else if ( v.valueless_by_exception() ) return true;
1446  else return detail::Comparator< variant<T0, T1, T2, T3, T4, T5, T6> >::equal( v, w );
1447 }
1448 
1449 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1450 inline bool operator!=(
1451  variant<T0, T1, T2, T3, T4, T5, T6> const & v,
1452  variant<T0, T1, T2, T3, T4, T5, T6> const & w )
1453 {
1454  return ! ( v == w );
1455 }
1456 
1457 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1458 inline bool operator<(
1459  variant<T0, T1, T2, T3, T4, T5, T6> const & v,
1460  variant<T0, T1, T2, T3, T4, T5, T6> const & w )
1461 {
1462  if ( w.valueless_by_exception() ) return false;
1463  else if ( v.valueless_by_exception() ) return true;
1464  else if ( v.index() < w.index() ) return true;
1465  else if ( v.index() > w.index() ) return false;
1466  else return detail::Comparator< variant<T0, T1, T2, T3, T4, T5, T6> >::less_than( v, w );
1467 }
1468 
1469 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1470 inline bool operator>(
1471  variant<T0, T1, T2, T3, T4, T5, T6> const & v,
1472  variant<T0, T1, T2, T3, T4, T5, T6> const & w )
1473 {
1474  return w < v;
1475 }
1476 
1477 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1478 inline bool operator<=(
1479  variant<T0, T1, T2, T3, T4, T5, T6> const & v,
1480  variant<T0, T1, T2, T3, T4, T5, T6> const & w )
1481 {
1482  return ! ( v > w );
1483 }
1484 
1485 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1486 inline bool operator>=(
1487  variant<T0, T1, T2, T3, T4, T5, T6> const & v,
1488  variant<T0, T1, T2, T3, T4, T5, T6> const & w )
1489 {
1490  return ! ( v < w );
1491 }
1492 
1493 } // namespace variants
1494 
1495 using namespace variants;
1496 
1497 } // namespace nonstd
1498 
1500 
1501 // specialize the std::hash algorithm:
1502 
1503 namespace std {
1504 
1505 template<>
1506 struct hash< nonstd::monostate >
1507 {
1508  std::size_t operator()( nonstd::monostate ) const variant_noexcept
1509  {
1510  return 42;
1511  }
1512 };
1513 
1514 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
1515 struct hash< nonstd::variant<T0, T1, T2, T3, T4, T5, T6> >
1516 {
1517  std::size_t operator()( nonstd::variant<T0, T1, T2, T3, T4, T5, T6> const & v ) const variant_noexcept
1518  {
1519  return nonstd::variants::detail::hash( v );
1520  }
1521 };
1522 
1523 } //namespace std
1524 
1525 #endif // variant_CPP11_OR_GREATER
1526 
1528 # pragma warning( pop )
1529 #endif
1530 
1531 #endif // have C++17 std::variant
1532 
1533 #endif // NONSTD_VARIANT_LITE_HPP
#define variant_CPP11_OR_GREATER
Definition: variant.hpp:33
variant(T4 const &t4)
Definition: variant.hpp:909
void swap_value(std::size_t index, variant &rhs)
Definition: variant.hpp:1249
#define variant_TL2(T1, T2)
Definition: variant.hpp:379
R const & get(variant< T0, T1, T2, T3, T4, T5, T6 > const &v, nonstd_lite_in_place_type_t(R)=in_place< R >)
Definition: variant.hpp:1309
static type_index_t to_index_t(std::size_t index)
Definition: variant.hpp:736
in_place_t in_place_index(detail::in_place_index_tag< I >=detail::in_place_index_tag< I >())
Definition: optional.hpp:320
bool operator<(T const &) const
Definition: variant.hpp:410
#define variant_TL1(T1)
Definition: variant.hpp:378
variant_alternative< I, variant< T0, T1, T2, T3, T4, T5, T6 > >::type & get(variant< T0, T1, T2, T3, T4, T5, T6 > &v, nonstd_lite_in_place_index_t(I)=in_place< I >)
Definition: variant.hpp:1316
variant(T3 const &t3)
Definition: variant.hpp:908
variant_constexpr bool operator>=(monostate, monostate) variant_noexcept
Definition: variant.hpp:820
TX< T > operator-(U const &) const
Definition: variant.hpp:404
variant_constexpr type_index_t variant_npos_internal() const variant_noexcept
Definition: variant.hpp:1151
bool holds_alternative(variant< T0, T1, T2, T3, T4, T5, T6 > const &v) variant_noexcept
Definition: variant.hpp:1297
TX< T > operator &&(U const &) const
Definition: variant.hpp:416
#define variant_TL5(T1, T2, T3, T4, T5)
Definition: variant.hpp:382
TX< T > operator/(U const &) const
Definition: variant.hpp:400
TX< T > operator+(U const &) const
Definition: variant.hpp:403
#define variant_HAS_INCLUDE(arg)
Definition: variant.hpp:42
conditional< N==sizeof(typename List::head), typename List::head, typename type_of_size< typename List::tail, N >::type >::type type
Definition: variant.hpp:652
TX< T > operator|(U const &) const
Definition: variant.hpp:413
variant_constexpr bool operator<(monostate, monostate) variant_noexcept
Definition: variant.hpp:817
typedef variant_ALIGN_AS(max_type) align_as_type
#define variant_override
Definition: variant.hpp:239
TX< T > operator-() const
Definition: variant.hpp:392
detail::helper< T0, T1, T2, T3, T4, T5, T6 > helper_type
Definition: variant.hpp:899
TX< T > operator>>(U const &) const
Definition: variant.hpp:407
TX< T > * operator &() const
Definition: variant.hpp:397
#define variant_TL3(T1, T2, T3)
Definition: variant.hpp:380
TX< T > operator||(U const &) const
Definition: variant.hpp:417
#define variant_BETWEEN(v, lo, hi)
Definition: variant.hpp:116
std::size_t hash(T const &v)
Definition: variant.hpp:701
#define variant_COMPILER_GNUC_VERSION
Definition: variant.hpp:127
variant_constexpr bool operator>(monostate, monostate) variant_noexcept
Definition: variant.hpp:818
void const * ptr() const variant_noexcept
Definition: variant.hpp:1129
#define variant_TL4(T1, T2, T3, T4)
Definition: variant.hpp:381
TX< T > operator+() const
Definition: variant.hpp:391
#define variant_CONFIG_ALIGN_AS_FALLBACK
Definition: variant.hpp:112
variant_constexpr std::size_t max_index() const variant_noexcept
Definition: variant.hpp:1146
detail::typelist_type_at< variant_TL7(T0, T1, T2, T3, T4, T5, T6), I >::type type
Definition: variant.hpp:852
TX< T > operator%(U const &) const
Definition: variant.hpp:402
#define variant_CPP17_OR_GREATER
Definition: variant.hpp:35
#define nonstd_lite_in_place_type_t(T)
Definition: optional.hpp:327
#define variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
Definition: variant.hpp:22
bool operator>=(variant< T0, T1, T2, T3, T4, T5, T6 > const &v, variant< T0, T1, T2, T3, T4, T5, T6 > const &w)
Definition: variant.hpp:1486
#define variant_TL6(T1, T2, T3, T4, T5, T6)
Definition: variant.hpp:383
#define nonstd_lite_in_place_index_t(T)
Definition: optional.hpp:328
variant_constexpr bool operator<=(monostate, monostate) variant_noexcept
Definition: variant.hpp:819
static U const * as(void const *data)
Definition: variant.hpp:731
TX< T > operator*(U const &) const
Definition: variant.hpp:399
#define variant_constexpr
Definition: variant.hpp:215
TX< T > operator!() const
Definition: variant.hpp:394
R & get(variant< T0, T1, T2, T3, T4, T5, T6 > &v, nonstd_lite_in_place_type_t(R)=in_place< R >)
Definition: variant.hpp:1303
variant_constexpr bool operator==(monostate, monostate) variant_noexcept
Definition: variant.hpp:821
static type_index_t copy(std::size_t const from_index, const void *from_value, void *to_value)
Definition: variant.hpp:790
variant(T1 const &t1)
Definition: variant.hpp:906
TX< T > operator^(U const &) const
Definition: variant.hpp:414
#define variant_TL7(T1, T2, T3, T4, T5, T6, T7)
Definition: variant.hpp:384
U const * as() const
Definition: variant.hpp:1141
variant(T5 const &t5)
Definition: variant.hpp:910
void * ptr() variant_noexcept
Definition: variant.hpp:1124
in_place_t in_place_type(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition: optional.hpp:314
variant_constexpr bool operator!=(monostate, monostate) variant_noexcept
Definition: variant.hpp:822
variant(T0 const &t0)
Definition: variant.hpp:905
#define variant_MSVC_LANG
Definition: variant.hpp:30
#define variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
Definition: variant.hpp:18
in_place_t in_place(detail::in_place_index_tag< I >=detail::in_place_index_tag< I >())
Definition: optional.hpp:308
#define variant_CONFIG_MAX_ALIGN_HACK
Definition: variant.hpp:104
variant(variant const &rhs)
Definition: variant.hpp:923
virtual const char * what() const
Definition: variant.hpp:881
TX< T > operator &(U const &) const
Definition: variant.hpp:412
variant & copy_assign(variant const &rhs)
Definition: variant.hpp:1156
bool operator==(T const &) const
Definition: variant.hpp:409
variant(T2 const &t2)
Definition: variant.hpp:907
static void destroy(std::size_t index, void *data)
Definition: variant.hpp:741
variant(T6 const &t6)
Definition: variant.hpp:911
variant_alternative< I, variant< T0, T1, T2, T3, T4, T5, T6 > >::type const & get(variant< T0, T1, T2, T3, T4, T5, T6 > const &v, nonstd_lite_in_place_index_t(I)=in_place< I >)
Definition: variant.hpp:1328
#define variant_ALIGN_TYPE(type)
Definition: variant.hpp:664
#define variant_CPP14_OR_GREATER
Definition: variant.hpp:34
TX< T > operator~() const
Definition: variant.hpp:395
#define variant_COMPILER_MSVC_VERSION
Definition: variant.hpp:121
in_place_t in_place(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition: optional.hpp:302
static U * as(void *data)
Definition: variant.hpp:725
#define variant_noexcept
Definition: variant.hpp:227
#define variant_nullptr
Definition: variant.hpp:233