10 #ifndef NONSTD_VARIANT_LITE_HPP 11 #define NONSTD_VARIANT_LITE_HPP 13 #define variant_lite_VERSION "1.0.0" 17 #ifndef variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO 18 # define variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO 0
21 #ifndef variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO 22 # define variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO 0
28 # define variant_MSVC_LANG _MSVC_LANG
30 # define variant_MSVC_LANG 0
39 #if defined( __has_include
) 40 # define variant_HAS_INCLUDE( arg ) __has_include( arg ) 42 # define variant_HAS_INCLUDE( arg ) 0
47 #define variant_HAVE_STD_VARIANT 1
51 #if ! variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO 52 # define variant_size_V(T) nonstd::variant_size<T>::value 55 #if ! variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO 56 # define variant_alternative_T(I,T) typename nonstd::variant_alternative<I,T >::type 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;
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;
78 using std::holds_alternative;
81 using std::operator==;
82 using std::operator!=;
84 using std::operator<=;
86 using std::operator>=;
89 constexpr auto variant_npos = std::variant_npos;
103 #ifndef variant_CONFIG_MAX_ALIGN_HACK 104 # define variant_CONFIG_MAX_ALIGN_HACK 0
107 #ifndef variant_CONFIG_ALIGN_AS 111 #ifndef variant_CONFIG_ALIGN_AS_FALLBACK 112 # define variant_CONFIG_ALIGN_AS_FALLBACK double 116 #define variant_BETWEEN( v, lo, hi ) ( lo <= v && v < hi ) 118 #if defined(_MSC_VER
) && !defined(__clang__
) 119 # define variant_COMPILER_MSVC_VERSION (_MSC_VER / 100
- 5
- (_MSC_VER < 1900
)) 121 # define variant_COMPILER_MSVC_VERSION 0
125 # define variant_COMPILER_GNUC_VERSION __GNUC__ 127 # define variant_COMPILER_GNUC_VERSION 0
131 # pragma warning( push ) 132 # pragma warning( disable: 4345
) 138 # define variant_HAVE_AUTO 1
139 # define variant_HAVE_NULLPTR 1
140 # define variant_HAVE_STATIC_ASSERT 1
144 # define variant_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1
145 # define variant_HAVE_INITIALIZER_LIST 1
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
162 # define variant_HAVE_CONSTEXPR_14 1
168 # define variant_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE 1
174 # define variant_HAVE_TR1_TYPE_TRAITS 1
175 # define variant_HAVE_TR1_ADD_POINTER 1
179 # define variant_HAVE_TYPE_TRAITS 1
180 # define variant_HAVE_STD_ADD_POINTER 1
184 # define variant_HAVE_ARRAY 1
188 # define variant_HAVE_CONDITIONAL 1
192 # define variant_HAVE_CONTAINER_DATA_METHOD 1
196 # define variant_HAVE_REMOVE_CV 1
200 # define variant_HAVE_SIZED_TYPES 1
206 # undef variant_CPP11_OR_GREATER 207 # define variant_CPP11_OR_GREATER 1
212 #if variant_HAVE_CONSTEXPR_11
213 # define variant_constexpr constexpr 215 # define variant_constexpr 218 #if variant_HAVE_CONSTEXPR_14
219 # define variant_constexpr14 constexpr 221 # define variant_constexpr14 224 #if variant_HAVE_NOEXCEPT
225 # define variant_noexcept noexcept 227 # define variant_noexcept 230 #if variant_HAVE_NULLPTR
231 # define variant_nullptr nullptr 233 # define variant_nullptr NULL 236 #if variant_HAVE_OVERRIDE
237 # define variant_override override 239 # define variant_override 244 #if variant_HAVE_INITIALIZER_LIST
245 # include <initializer_list> 248 #if variant_HAVE_TYPE_TRAITS
249 # include <type_traits> 250 #elif variant_HAVE_TR1_TYPE_TRAITS 251 # include <tr1/type_traits> 258 #if ! nonstd_lite_HAVE_IN_PLACE_TYPES 267 template< std::size_t I >
280 template< std::size_t I >
292 template< std::size_t I >
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> ) 303 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
319 #if variant_HAVE_STD_ADD_POINTER
323 #elif variant_HAVE_TR1_ADD_POINTER 339 #if variant_HAVE_REMOVE_CV
359 #if variant_HAVE_CONDITIONAL
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 ) > 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>(); }
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>(); }
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>(); }
409 inline bool operator==( T
const & )
const {
return false; }
410 inline bool operator< ( T
const & )
const {
return false; }
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>(); }
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>(); }
430 template<
class Head,
class Tail >
439 template<
class List >
449 template<
class Head,
class Tail >
458 enum {
value = (
sizeof( Head ) > tail_value) ?
sizeof( Head ) : std::size_t( tail_value ) } ;
460 typedef typename conditional< (
sizeof( Head ) > tail_value), Head, tail_type>::type type;
467 template<
class List >
468 struct typelist_max_alignof;
471 struct typelist_max_alignof<
nulltype >
476 template<
class Head,
class Tail >
477 struct typelist_max_alignof<
typelist<Head, Tail> >
480 enum { tail_value = size_t( typelist_max_alignof<Tail>::value ) };
483 enum { value = (
alignof( Head ) > tail_value) ?
alignof( Head ) : std::size_t( tail_value ) };
490 template<
class List >
506 template<
class Head,
class Tail >
514 template<
class List,
class T >
515 struct typelist_index_of;
523 template<
class Tail,
class T >
529 template<
class Head,
class Tail,
class T >
530 struct typelist_index_of<
typelist<Head, Tail>, T >
533 enum {
nextVal = typelist_index_of<Tail, T>::value };
540 template<
class List, std::size_t i>
541 struct typelist_type_at;
543 template<
class Head,
class Tail >
549 template<
class Head,
class Tail, std::size_t i >
552 typedef typename typelist_type_at<Tail, i - 1>::
type type;
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 563 #define variant_ALIGN_TYPE( type ) 564 type variant_UNIQUE( _t ); struct_t< type > variant_UNIQUE( _st ) 587 #ifdef HAVE_LONG_LONG 602 #undef variant_UNIQUE 603 #undef variant_UNIQUE2 604 #undef variant_UNIQUE3 606 #undef variant_ALIGN_TYPE 608 #elif defined( variant_CONFIG_ALIGN_AS ) 612 #define variant_ALIGN_AS( unused ) 613 variant_CONFIG_ALIGN_AS 619 #define variant_ALIGN_AS( to_align ) 620 typename detail::type_of_size< detail::alignment_types, detail::alignment_of< to_align >::value >::type 622 template <
typename T>
625 template <
typename T>
633 template <
unsigned A,
unsigned S>
636 enum { value = A < S ? A : S };
639 template<
typename T >
646 template<
typename List, size_t N >
649 typedef typename conditional<
661 template<
typename T>
664 #define variant_ALIGN_TYPE( type ) 665 typelist< type , typelist< struct_t< type > 691 > > > > > > > > > > > > > >
692 > > > > > > > > > > > > > >
696 #undef variant_ALIGN_TYPE 700 template<
typename T>
704 unsigned const int a = 54059;
705 unsigned const int b = 76963;
706 unsigned const int h0 = 37;
709 unsigned char const *
s =
reinterpret_cast<
unsigned char const *>( &
v );
713 h = (
h *
a) ^ (*
s *
b);
718 template<
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
722 typedef variant_TL7( T0, T1, T2, T3, T4, T5, T6 ) variant_types;
725 static U *
as(
void * data )
727 return reinterpret_cast<
U*>(
data );
731 static U
const *
as(
void const * data )
733 return reinterpret_cast<
const U*>(
data );
741 static void destroy( std::size_t index,
void * data )
756 template<
class T,
class... Args >
757 static type_index_t construct_t(
void * data, Args&&... args )
764 template< std::size_t I,
class... Args >
765 static type_index_t construct_i(
void * data, Args&&... args )
774 static type_index_t move( std::size_t
const from_index,
void * from_value,
void * to_value )
812 template<
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
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> >
841 # define variant_size_V(T) nonstd::variant_size<T>::value 846 template< std::size_t I,
class T >
847 struct variant_alternative;
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> >
856 template< std::size_t I,
class T >
857 using variant_alternative_t =
typename variant_alternative<I, T>::type;
861 # define variant_alternative_T(I,T) typename nonstd::variant_alternative<I,T >::type 881 virtual const char*
what()
const throw()
884 return "bad variant access";
900 typedef variant_TL7( T0, T1, T2, T3, T4, T5, T6 ) variant_types;
937 template< std::size_t I >
938 using type_at_t =
typename detail::typelist_type_at< variant_types, I >::type;
940 template<
class T,
class...
Args,
948 template<
class T,
class U,
class...
Args,
1019 template<
class T,
class...
Args,
1028 template<
class T,
class U,
class...
Args,
1104 return *
as<
const T>();
1137 return reinterpret_cast<
U*>(
ptr() );
1143 return reinterpret_cast<
U const *>(
ptr() );
1153 return static_cast<type_index_t>( -1 );
1213 template<
class T, std::size_t I >
1214 variant & move_assign_value( T && value )
1269 enum { data_align =
detail::typelist_max_alignof< variant_types >::value };
1272 aligned_storage_t data;
1274 #elif variant_CONFIG_MAX_ALIGN_HACK 1296 template <
class T,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1302 template<
class R,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1305 return v.
template get<
R>();
1308 template<
class R,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1311 return v.
template get<
R>();
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 &
1323 return v.
template get<
I>();
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 &
1335 return v.
template get<
I>();
1338 template<
class T,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1345 template<
class T,
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1366 template<
class T0,
class T1,
class T2,
class T3,
class T4,
class T5 >
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 ) );
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;
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;
1439 template<
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1449 template<
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1454 return ! (
v ==
w );
1457 template<
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1469 template<
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1477 template<
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1485 template<
class T0,
class T1,
class T2,
class T3,
class T4,
class T5,
class T6 >
1506 struct hash< nonstd::monostate >
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> >
1517 std::size_t operator()( nonstd::variant<T0, T1, T2, T3, T4, T5, T6>
const & v )
const variant_noexcept 1519 return nonstd::variants::detail::hash( v );
1528 # pragma warning( pop )
#define variant_CPP11_OR_GREATER
void swap_value(std::size_t index, variant &rhs)
#define variant_TL2(T1, T2)
R const & get(variant< T0, T1, T2, T3, T4, T5, T6 > const &v, nonstd_lite_in_place_type_t(R)=in_place< R >)
static type_index_t to_index_t(std::size_t index)
in_place_t in_place_index(detail::in_place_index_tag< I >=detail::in_place_index_tag< I >())
bool operator<(T const &) const
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 >)
variant_constexpr bool operator>=(monostate, monostate) variant_noexcept
TX< T > operator-(U const &) const
variant_constexpr type_index_t variant_npos_internal() const variant_noexcept
bool holds_alternative(variant< T0, T1, T2, T3, T4, T5, T6 > const &v) variant_noexcept
TX< T > operator &&(U const &) const
#define variant_TL5(T1, T2, T3, T4, T5)
TX< T > operator/(U const &) const
TX< T > operator+(U const &) const
#define variant_HAS_INCLUDE(arg)
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_constexpr bool operator<(monostate, monostate) variant_noexcept
typedef variant_ALIGN_AS(max_type) align_as_type
TX< T > operator-() const
detail::helper< T0, T1, T2, T3, T4, T5, T6 > helper_type
TX< T > operator>>(U const &) const
TX< T > * operator &() const
#define variant_TL3(T1, T2, T3)
TX< T > operator||(U const &) const
#define variant_BETWEEN(v, lo, hi)
std::size_t hash(T const &v)
#define variant_COMPILER_GNUC_VERSION
variant_constexpr bool operator>(monostate, monostate) variant_noexcept
void const * ptr() const variant_noexcept
#define variant_TL4(T1, T2, T3, T4)
TX< T > operator+() const
variant_CONFIG_ALIGN_AS_FALLBACK type
typelist_type_at< Tail, i - 1 >::type type
#define variant_CONFIG_ALIGN_AS_FALLBACK
variant_constexpr std::size_t max_index() const variant_noexcept
detail::typelist_type_at< variant_TL7(T0, T1, T2, T3, T4, T5, T6), I >::type type
TX< T > operator%(U const &) const
#define variant_CPP17_OR_GREATER
#define nonstd_lite_in_place_type_t(T)
#define variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
bool operator>=(variant< T0, T1, T2, T3, T4, T5, T6 > const &v, variant< T0, T1, T2, T3, T4, T5, T6 > const &w)
#define variant_TL6(T1, T2, T3, T4, T5, T6)
#define nonstd_lite_in_place_index_t(T)
variant_constexpr bool operator<=(monostate, monostate) variant_noexcept
static U const * as(void const *data)
TX< T > operator*(U const &) const
#define variant_constexpr
TX< T > operator!() const
R & get(variant< T0, T1, T2, T3, T4, T5, T6 > &v, nonstd_lite_in_place_type_t(R)=in_place< R >)
variant_constexpr bool operator==(monostate, monostate) variant_noexcept
static type_index_t copy(std::size_t const from_index, const void *from_value, void *to_value)
TX< T > operator^(U const &) const
#define variant_TL7(T1, T2, T3, T4, T5, T6, T7)
void * ptr() variant_noexcept
in_place_t in_place_type(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
variant_constexpr bool operator!=(monostate, monostate) variant_noexcept
#define variant_MSVC_LANG
#define variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
in_place_t in_place(detail::in_place_index_tag< I >=detail::in_place_index_tag< I >())
#define variant_CONFIG_MAX_ALIGN_HACK
variant(variant const &rhs)
virtual const char * what() const
TX< T > operator &(U const &) const
variant & copy_assign(variant const &rhs)
bool operator==(T const &) const
static void destroy(std::size_t index, void *data)
typelist_max< Tail >::type tail_type
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 >)
#define variant_ALIGN_TYPE(type)
#define variant_CPP14_OR_GREATER
TX< T > operator~() const
#define variant_COMPILER_MSVC_VERSION
in_place_t in_place(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
static U * as(void *data)