31#include "../platform.h"
32#include "../utility.h"
34#include "../largest.h"
35#include "../exception.h"
36#include "../type_traits.h"
37#include "../integral_limits.h"
38#include "../static_assert.h"
39#include "../alignment.h"
40#include "../error_handler.h"
41#include "../null_type.h"
42#include "../placement_new.h"
46#if defined(ETL_COMPILER_KEIL)
47 #pragma diag_suppress 940
48 #pragma diag_suppress 111
58#if ETL_USING_CPP11 && !defined(ETL_USE_LEGACY_VARIANT)
62 namespace private_variant
89 variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
90 :
exception(reason_, file_name_, line_number_)
103 :
variant_exception(ETL_ERROR_TEXT(
"variant:unsupported type", ETL_VARIANT_FILE_ID
"A"), file_name_, line_number_)
116 :
variant_exception(ETL_ERROR_TEXT(
"variant:bad variant access", ETL_VARIANT_FILE_ID
"B"), file_name_, line_number_)
128 :
variant_exception(ETL_ERROR_TEXT(
"variant:not_a base", ETL_VARIANT_FILE_ID
"C"), file_name_, line_number_)
138 template <
typename T1,
163 template <
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6,
typename U7,
typename U8>
169 typedef typename etl::largest_type<T1, T2, T3, T4, T5, T6, T7, T8>::type largest_t;
174 static const size_t SIZE =
sizeof(largest_t);
195 template <
typename T>
196 struct Type_Id_Lookup
212 template <
typename T>
214 etl::is_same<T, T1>::value ||
215 etl::is_same<T, T2>::value ||
216 etl::is_same<T, T3>::value ||
217 etl::is_same<T, T4>::value ||
218 etl::is_same<T, T5>::value ||
219 etl::is_same<T, T6>::value ||
220 etl::is_same<T, T7>::value ||
221 etl::is_same<T, T8>::value>
244 template <
typename R1,
typename R2 = no_type2,
typename R3 = no_type3,
typename R4 = no_type4,
typename R5 = no_type5,
typename R6 = no_type6,
typename R7 = no_type7,
typename R8 = no_type8>
268 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5,
typename R6,
typename R7>
295 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5,
typename R6>
322 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5>
349 template <
typename R1,
typename R2,
typename R3,
typename R4>
376 template <
typename R1,
typename R2,
typename R3>
403 template <
typename R1,
typename R2>
430 template <
typename R1>
465 : type_id(UNSUPPORTED_TYPE_ID)
474 template <
typename T>
477 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
479 ::new (
static_cast<T*
>(data)) T(value);
480 type_id = Type_Id_Lookup<T>::type_id;
490 switch (other.type_id)
492 case 0: ::new (
static_cast<T1*
>(data)) T1(other.
get<T1>());
break;
493 case 1: ::new (
static_cast<T2*
>(data)) T2(other.
get<T2>());
break;
494 case 2: ::new (
static_cast<T3*
>(data)) T3(other.
get<T3>());
break;
495 case 3: ::new (
static_cast<T4*
>(data)) T4(other.
get<T4>());
break;
496 case 4: ::new (
static_cast<T5*
>(data)) T5(other.
get<T5>());
break;
497 case 5: ::new (
static_cast<T6*
>(data)) T6(other.
get<T6>());
break;
498 case 6: ::new (
static_cast<T7*
>(data)) T7(other.
get<T7>());
break;
499 case 7: ::new (
static_cast<T8*
>(data)) T8(other.
get<T8>());
break;
503 type_id = other.type_id;
507#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VARIANT_FORCE_CPP03_IMPLEMENTATION)
511 template <
typename T,
typename... Args>
512 T& emplace(Args&&... args)
514 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
517 ::new (
static_cast<T*
>(data)) T(etl::forward<Args>(args)...);
518 type_id = Type_Id_Lookup<T>::type_id;
520 return *
static_cast<T*
>(data);
526 template <
typename T,
typename TP1>
529 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
532 ::new (
static_cast<T*
>(data)) T(value1);
533 type_id = Type_Id_Lookup<T>::type_id;
535 return *
static_cast<T*
>(data);
541 template <
typename T,
typename TP1,
typename TP2>
542 T&
emplace(
const TP1& value1,
const TP2& value2)
544 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
547 ::new (
static_cast<T*
>(data)) T(value1, value2);
548 type_id = Type_Id_Lookup<T>::type_id;
550 return *
static_cast<T*
>(data);
556 template <
typename T,
typename TP1,
typename TP2,
typename TP3>
557 T&
emplace(
const TP1& value1,
const TP2& value2,
const TP3& value3)
559 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
562 ::new (
static_cast<T*
>(data)) T(value1, value2, value3);
563 type_id = Type_Id_Lookup<T>::type_id;
565 return *
static_cast<T*
>(data);
571 template <
typename T,
typename TP1,
typename TP2,
typename TP3,
typename TP4>
572 T&
emplace(
const TP1& value1,
const TP2& value2,
const TP3& value3,
const TP4& value4)
574 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
577 ::new (
static_cast<T*
>(data)) T(value1, value2, value3, value4);
578 type_id = Type_Id_Lookup<T>::type_id;
580 return *
static_cast<T*
>(data);
588 template <
typename T>
591 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
594 ::new (
static_cast<T*
>(data)) T(value);
595 type_id = Type_Id_Lookup<T>::type_id;
610 switch (other.type_id)
612 case 0: ::new (
static_cast<T1*
>(data)) T1(other.
get<T1>());
break;
613 case 1: ::new (
static_cast<T2*
>(data)) T2(other.
get<T2>());
break;
614 case 2: ::new (
static_cast<T3*
>(data)) T3(other.
get<T3>());
break;
615 case 3: ::new (
static_cast<T4*
>(data)) T4(other.
get<T4>());
break;
616 case 4: ::new (
static_cast<T5*
>(data)) T5(other.
get<T5>());
break;
617 case 5: ::new (
static_cast<T6*
>(data)) T6(other.
get<T6>());
break;
618 case 6: ::new (
static_cast<T7*
>(data)) T7(other.
get<T7>());
break;
619 case 7: ::new (
static_cast<T8*
>(data)) T8(other.
get<T8>());
break;
623 type_id = other.type_id;
636 return type_id == other.type_id;
644 template <
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6,
typename U7,
typename U8>
649 switch (other.type_id)
651 case 0:
is_same = (type_id == Type_Id_Lookup<U1>::type_id);
break;
652 case 1:
is_same = (type_id == Type_Id_Lookup<U2>::type_id);
break;
653 case 2:
is_same = (type_id == Type_Id_Lookup<U3>::type_id);
break;
654 case 3:
is_same = (type_id == Type_Id_Lookup<U4>::type_id);
break;
655 case 4:
is_same = (type_id == Type_Id_Lookup<U5>::type_id);
break;
656 case 5:
is_same = (type_id == Type_Id_Lookup<U6>::type_id);
break;
657 case 6:
is_same = (type_id == Type_Id_Lookup<U7>::type_id);
break;
658 case 7:
is_same = (type_id == Type_Id_Lookup<U8>::type_id);
break;
673 case 0: r.read(
static_cast<T1&
>(data));
break;
674 case 1: r.read(
static_cast<T2&
>(data));
break;
675 case 2: r.read(
static_cast<T3&
>(data));
break;
676 case 3: r.read(
static_cast<T4&
>(data));
break;
677 case 4: r.read(
static_cast<T5&
>(data));
break;
678 case 5: r.read(
static_cast<T6&
>(data));
break;
679 case 6: r.read(
static_cast<T7&
>(data));
break;
680 case 7: r.read(
static_cast<T8&
>(data));
break;
691 return type_id != UNSUPPORTED_TYPE_ID;
698 template <
typename T>
701 return type_id == Type_Id_Lookup<T>::type_id;
725 template <
typename T>
728 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
731 return static_cast<T&
>(data);
739 template <
typename T>
742 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
745 return static_cast<const T&
>(data);
752 template <
typename TBase>
757 return reinterpret_cast<TBase*
>(
static_cast<uint_least8_t*
>(data));
769 template <
typename TBase>
772 TBase* ptr = upcast_ptr<TBase>();
783 template <
typename TBase>
788 return reinterpret_cast<const TBase*
>(
static_cast<const uint_least8_t*
>(data));
800 template <
typename TBase>
803 const TBase* ptr = upcast_ptr<TBase>();
813 template <
typename TBase>
828 default: is_base =
false;
break;
837 operator T1& () {
return get<T1>(); }
838 operator T2& () {
return get<T2>(); }
839 operator T3& () {
return get<T3>(); }
840 operator T4& () {
return get<T4>(); }
841 operator T5& () {
return get<T5>(); }
842 operator T6& () {
return get<T6>(); }
843 operator T7& () {
return get<T7>(); }
844 operator T8& () {
return get<T8>(); }
850 template <
typename T>
853 return Type_Is_Supported<T>::value;
862 void destruct_current()
866 case 0: {
static_cast<T1*
>(data)->~T1();
break; }
867 case 1: {
static_cast<T2*
>(data)->~T2();
break; }
868 case 2: {
static_cast<T3*
>(data)->~T3();
break; }
869 case 3: {
static_cast<T4*
>(data)->~T4();
break; }
870 case 4: {
static_cast<T5*
>(data)->~T5();
break; }
871 case 5: {
static_cast<T6*
>(data)->~T6();
break; }
872 case 6: {
static_cast<T7*
>(data)->~T7();
break; }
873 case 7: {
static_cast<T8*
>(data)->~T8();
break; }
877 type_id = UNSUPPORTED_TYPE_ID;
893 namespace private_variant
895 template <
size_t,
typename>
897#define ETL_VARIANT_HELPER(INDEX, TYPE) \
898 template <typename T1, \
906 struct variant_alternative_helper<INDEX, variant<T1, T2, T3, T4, T5, T6, T7, T8> > \
910 ETL_VARIANT_HELPER(0, T1)
911 ETL_VARIANT_HELPER(1, T2)
912 ETL_VARIANT_HELPER(2, T3)
913 ETL_VARIANT_HELPER(3, T4)
914 ETL_VARIANT_HELPER(4, T5)
915 ETL_VARIANT_HELPER(5, T6)
916 ETL_VARIANT_HELPER(6, T7)
917 ETL_VARIANT_HELPER(7, T8)
918#undef ETL_VARIANT_HELPER
921 template <
size_t tIndex,
typename TVariant>
927 template <
size_t tIndex,
typename TVariant>
933 template <
size_t tIndex,
typename TVariant>
939 template <
size_t tIndex,
typename TVariant>
945 template <
typename T,
typename TVariant>
948 return variant.template get<T>();
951 template <
typename T,
typename TVariant>
952 inline T
const&
get(TVariant
const& variant)
954 return variant.template get<T>();
957 template <
size_t tIndex,
typename TVariant>
958 inline typename variant_alternative<tIndex, TVariant>::type&
get(TVariant& variant)
960 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
963 template <
size_t tIndex,
typename TVariant>
964 inline typename variant_alternative<tIndex, TVariant const>::type&
get(TVariant
const& variant)
966 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
969#define ETL_GEN_LEGACY_VISIT(VISITQUAL, VARIANTQUAL) \
970 template <typename TReturn, typename TVisitor, typename TVariant> \
971 static TReturn visit(TVisitor VISITQUAL visitor, TVariant VARIANTQUAL variant) \
973 switch (variant.index()) \
975 case 0: return static_cast<TReturn>(visitor(get<0>(variant))); \
976 case 1: return static_cast<TReturn>(visitor(get<1>(variant))); \
977 case 2: return static_cast<TReturn>(visitor(get<2>(variant))); \
978 case 3: return static_cast<TReturn>(visitor(get<3>(variant))); \
979 case 4: return static_cast<TReturn>(visitor(get<4>(variant))); \
980 case 5: return static_cast<TReturn>(visitor(get<5>(variant))); \
981 case 6: return static_cast<TReturn>(visitor(get<6>(variant))); \
982 case 7: return static_cast<TReturn>(visitor(get<7>(variant))); \
983 default: ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(bad_variant_access), TReturn()); \
987 ETL_GEN_LEGACY_VISIT(&, &)
988 ETL_GEN_LEGACY_VISIT(const&, &)
989 ETL_GEN_LEGACY_VISIT(&, const&)
990 ETL_GEN_LEGACY_VISIT(const&, const&)
992#undef ETL_GEN_LEGACY_VISIT
994#if ETL_USING_CPP11 && !defined(ETL_USE_LEGACY_VARIANT)
Definition: null_type.h:40
Definition: variant_legacy.h:246
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
Definition: exception.h:47
Definition: integral_limits.h:468
Definition: largest.h:227
integral_constant
Definition: type_traits_generator.h:832
is_base_of
Definition: type_traits_generator.h:1252
is_same
Definition: type_traits_generator.h:1041
variant(const T &value)
Definition: variant_legacy.h:475
bool is_same_type(const variant< U1, U2, U3, U4, U5, U6, U7, U8 > &other) const
Definition: variant_legacy.h:645
static bool is_supported_type()
Definition: variant_legacy.h:851
const T & get() const
Definition: variant_legacy.h:740
~variant()
Destructor.
Definition: variant_legacy.h:230
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3, const TP4 &value4)
Emplace with four constructor parameters.
Definition: variant_legacy.h:572
variant()
Definition: variant_legacy.h:464
bool is_same_type(const variant &other) const
Definition: variant_legacy.h:634
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3)
Emplace with three constructor parameters.
Definition: variant_legacy.h:557
void call(reader &r)
Definition: variant_legacy.h:669
T & get()
Definition: variant_legacy.h:726
bool is_base_of() const
Check that TBase is a base class of the current variant value.
Definition: variant_legacy.h:814
uint_least8_t type_id_t
The type used for ids.
Definition: variant_legacy.h:153
T & emplace(const TP1 &value1)
Emplace with one constructor parameter.
Definition: variant_legacy.h:527
const TBase * upcast_ptr() const
Definition: variant_legacy.h:784
reader_type< T1, T2, T3, T4, T5, T6, T7, T8 > reader
The base type for derived readers.
Definition: variant_legacy.h:457
bool is_type() const
Definition: variant_legacy.h:699
void clear()
Clears the value to 'no valid stored value'.
Definition: variant_legacy.h:715
T & emplace(const TP1 &value1, const TP2 &value2)
Emplace with two constructor parameters.
Definition: variant_legacy.h:542
TBase * upcast_ptr()
Definition: variant_legacy.h:753
size_t index() const
Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID.
Definition: variant_legacy.h:707
TBase & upcast()
Definition: variant_legacy.h:770
variant(const variant &other)
Definition: variant_legacy.h:488
const TBase & upcast() const
Definition: variant_legacy.h:801
bool is_valid() const
Definition: variant_legacy.h:689
Definition: variant_legacy.h:113
Definition: variant_legacy.h:147
Definition: variant_legacy.h:87
Definition: variant_legacy.h:100
Definition: variant_legacy.h:125
Definition: variant_legacy.h:79
bitset_ext
Definition: absolute.h:38
T & get(array< T, MAXN > &a)
Definition: array.h:710
etl::optional< T > read(etl::bit_stream_reader &stream)
Read a checked type from a stream.
Definition: bit_stream.h:1348
Definition: alignment.h:223
etl::conditional< etl::is_fundamental< T >::value||etl::is_pointer< T >::value, T, constT & >::type type
By default fundamental and pointer types are passed by value.
Definition: parameter_type.h:48
Definition: variant_legacy.h:70
Definition: variant_legacy.h:896
Definition: variant_legacy.h:923