31 #ifndef ETL_VARIANT_INCLUDED
32 #define ETL_VARIANT_INCLUDED
43 #include "static_assert.h"
46 #include "null_type.h"
49 #if defined(ETL_COMPILER_KEIL)
50 #pragma diag_suppress 940
51 #pragma diag_suppress 111
65 namespace private_variant
71 template <const
size_t ID>
84 variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
85 :
exception(reason_, file_name_, line_number_)
98 :
variant_exception(ETL_ERROR_TEXT(
"variant: unsupported type", ETL_FILE
"A"), file_name_, line_number_)
108 template <
typename T1,
133 template <
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6,
typename U7,
typename U8>
139 typedef typename largest_type<T1, T2, T3, T4, T5, T6, T7, T8>::type largest_t;
144 static const size_t SIZE =
sizeof(largest_t);
165 template <
typename T>
166 struct Type_Id_Lookup
182 template <
typename T>
184 is_same<T, T1>::value ||
185 is_same<T, T2>::value ||
186 is_same<T, T3>::value ||
187 is_same<T, T4>::value ||
188 is_same<T, T5>::value ||
189 is_same<T, T6>::value ||
190 is_same<T, T7>::value ||
191 is_same<T, T8>::value>
214 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>
234 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5,
typename R6,
typename R7>
257 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5,
typename R6>
280 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5>
303 template <
typename R1,
typename R2,
typename R3,
typename R4>
326 template <
typename R1,
typename R2,
typename R3>
349 template <
typename R1,
typename R2>
372 template <
typename R1>
410 template <
typename T>
413 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
415 ::new (
static_cast<T*
>(data)) T(value);
416 type_id = Type_Id_Lookup<T>::type_id;
425 switch (other.type_id)
427 case 0: ::new (
static_cast<T1*
>(data)) T1(other.
get<T1>());
break;
428 case 1: ::new (
static_cast<T2*
>(data)) T2(other.
get<T2>());
break;
429 case 2: ::new (
static_cast<T3*
>(data)) T3(other.
get<T3>());
break;
430 case 3: ::new (
static_cast<T4*
>(data)) T4(other.
get<T4>());
break;
431 case 4: ::new (
static_cast<T5*
>(data)) T5(other.
get<T5>());
break;
432 case 5: ::new (
static_cast<T6*
>(data)) T6(other.
get<T6>());
break;
433 case 6: ::new (
static_cast<T7*
>(data)) T7(other.
get<T7>());
break;
434 case 7: ::new (
static_cast<T8*
>(data)) T8(other.
get<T8>());
break;
438 type_id = other.type_id;
441 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && !defined(ETL_VARIANT_FORCE_CPP03)
445 template <
typename T,
typename... Args>
448 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
451 ::new (
static_cast<T*
>(data)) T(etl::forward<Args>(args)...);
452 type_id = Type_Id_Lookup<T>::type_id;
454 return *
static_cast<T*
>(data);
460 template <
typename T,
typename TP1>
463 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
466 ::new (
static_cast<T*
>(data)) T(value1);
467 type_id = Type_Id_Lookup<T>::type_id;
469 return *
static_cast<T*
>(data);
475 template <
typename T,
typename TP1,
typename TP2>
476 T&
emplace(
const TP1& value1,
const TP2& value2)
478 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
481 ::new (
static_cast<T*
>(data)) T(value1, value2);
482 type_id = Type_Id_Lookup<T>::type_id;
484 return *
static_cast<T*
>(data);
490 template <
typename T,
typename TP1,
typename TP2,
typename TP3>
491 T&
emplace(
const TP1& value1,
const TP2& value2,
const TP3& value3)
493 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
496 ::new (
static_cast<T*
>(data)) T(value1, value2, value3);
497 type_id = Type_Id_Lookup<T>::type_id;
499 return *
static_cast<T*
>(data);
505 template <
typename T,
typename TP1,
typename TP2,
typename TP3,
typename TP4>
506 T&
emplace(
const TP1& value1,
const TP2& value2,
const TP3& value3,
const TP4& value4)
508 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
511 ::new (
static_cast<T*
>(data)) T(value1, value2, value3, value4);
512 type_id = Type_Id_Lookup<T>::type_id;
514 return *
static_cast<T*
>(data);
522 template <
typename T>
525 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
528 ::new (
static_cast<T*
>(data)) T(value);
529 type_id = Type_Id_Lookup<T>::type_id;
544 switch (other.type_id)
546 case 0: ::new (
static_cast<T1*
>(data)) T1(other.
get<T1>());
break;
547 case 1: ::new (
static_cast<T2*
>(data)) T2(other.
get<T2>());
break;
548 case 2: ::new (
static_cast<T3*
>(data)) T3(other.
get<T3>());
break;
549 case 3: ::new (
static_cast<T4*
>(data)) T4(other.
get<T4>());
break;
550 case 4: ::new (
static_cast<T5*
>(data)) T5(other.
get<T5>());
break;
551 case 5: ::new (
static_cast<T6*
>(data)) T6(other.
get<T6>());
break;
552 case 6: ::new (
static_cast<T7*
>(data)) T7(other.
get<T7>());
break;
553 case 7: ::new (
static_cast<T8*
>(data)) T8(other.
get<T8>());
break;
557 type_id = other.type_id;
570 return type_id == other.type_id;
578 template <
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6,
typename U7,
typename U8>
583 switch (other.type_id)
585 case 0:
is_same = (type_id == Type_Id_Lookup<U1>::type_id);
break;
586 case 1:
is_same = (type_id == Type_Id_Lookup<U2>::type_id);
break;
587 case 2:
is_same = (type_id == Type_Id_Lookup<U3>::type_id);
break;
588 case 3:
is_same = (type_id == Type_Id_Lookup<U4>::type_id);
break;
589 case 4:
is_same = (type_id == Type_Id_Lookup<U5>::type_id);
break;
590 case 5:
is_same = (type_id == Type_Id_Lookup<U6>::type_id);
break;
591 case 6:
is_same = (type_id == Type_Id_Lookup<U7>::type_id);
break;
592 case 7:
is_same = (type_id == Type_Id_Lookup<U8>::type_id);
break;
607 case 0: r.read(
static_cast<T1&
>(data));
break;
608 case 1: r.read(
static_cast<T2&
>(data));
break;
609 case 2: r.read(
static_cast<T3&
>(data));
break;
610 case 3: r.read(
static_cast<T4&
>(data));
break;
611 case 4: r.read(
static_cast<T5&
>(data));
break;
612 case 5: r.read(
static_cast<T6&
>(data));
break;
613 case 6: r.read(
static_cast<T7&
>(data));
break;
614 case 7: r.read(
static_cast<T8&
>(data));
break;
632 template <
typename T>
635 return type_id == Type_Id_Lookup<T>::type_id;
659 template <
typename T>
662 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
665 return static_cast<T&
>(data);
673 template <
typename T>
676 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
679 return static_cast<const T&
>(data);
686 template <
typename TBase>
689 return *upcast_functor<TBase, T1, T2, T3, T4, T5, T6, T7, T8>()(data, type_id);
696 template <
typename TBase>
699 return *upcast_functor<TBase, T1, T2, T3, T4, T5, T6, T7, T8>()(data, type_id);
705 operator T1&() {
return get<T1>(); }
706 operator T2&() {
return get<T2>(); }
707 operator T3&() {
return get<T3>(); }
708 operator T4&() {
return get<T4>(); }
709 operator T5&() {
return get<T5>(); }
710 operator T6&() {
return get<T6>(); }
711 operator T7&() {
return get<T7>(); }
712 operator T8&() {
return get<T8>(); }
718 template <
typename T>
721 return Type_Is_Supported<T>::value;
729 void destruct_current()
733 case 0: {
static_cast<T1*
>(data)->~T1();
break; }
734 case 1: {
static_cast<T2*
>(data)->~T2();
break; }
735 case 2: {
static_cast<T3*
>(data)->~T3();
break; }
736 case 3: {
static_cast<T4*
>(data)->~T4();
break; }
737 case 4: {
static_cast<T5*
>(data)->~T5();
break; }
738 case 5: {
static_cast<T6*
>(data)->~T6();
break; }
739 case 6: {
static_cast<T7*
>(data)->~T7();
break; }
740 case 7: {
static_cast<T8*
>(data)->~T8();
break; }
754 template <
typename TBase,
typename U1,
typename U2 = no_type2,
typename U3 = no_type3,
typename U4 = no_type4,
typename U5 = no_type5,
typename U6 = no_type6,
typename U7 = no_type7,
typename U8 = no_type8>
759 TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
763 case 0:
return reinterpret_cast<U1*
>(p_data);
764 case 1:
return reinterpret_cast<U2*
>(p_data);
765 case 2:
return reinterpret_cast<U3*
>(p_data);
766 case 3:
return reinterpret_cast<U4*
>(p_data);
767 case 4:
return reinterpret_cast<U5*
>(p_data);
768 case 5:
return reinterpret_cast<U6*
>(p_data);
769 case 6:
return reinterpret_cast<U7*
>(p_data);
770 case 7:
return reinterpret_cast<U8*
>(p_data);
771 default:
return reinterpret_cast<TBase*
>(0);
775 const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
const
779 case 0:
return reinterpret_cast<const U1*
>(p_data);
780 case 1:
return reinterpret_cast<const U2*
>(p_data);
781 case 2:
return reinterpret_cast<const U3*
>(p_data);
782 case 3:
return reinterpret_cast<const U4*
>(p_data);
783 case 4:
return reinterpret_cast<const U5*
>(p_data);
784 case 5:
return reinterpret_cast<const U6*
>(p_data);
785 case 6:
return reinterpret_cast<const U7*
>(p_data);
786 case 7:
return reinterpret_cast<const U8*
>(p_data);
787 default:
return reinterpret_cast<TBase*
>(0);
795 template <
typename TBase,
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6,
typename U7>
796 class upcast_functor<TBase, U1, U2, U3, U4, U5, U6, U7, no_type8>
800 TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
804 case 0:
return reinterpret_cast<U1*
>(p_data);
805 case 1:
return reinterpret_cast<U2*
>(p_data);
806 case 2:
return reinterpret_cast<U3*
>(p_data);
807 case 3:
return reinterpret_cast<U4*
>(p_data);
808 case 4:
return reinterpret_cast<U5*
>(p_data);
809 case 5:
return reinterpret_cast<U6*
>(p_data);
810 case 6:
return reinterpret_cast<U7*
>(p_data);
811 default:
return reinterpret_cast<TBase*
>(0);
815 const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
const
819 case 0:
return reinterpret_cast<const U1*
>(p_data);
820 case 1:
return reinterpret_cast<const U2*
>(p_data);
821 case 2:
return reinterpret_cast<const U3*
>(p_data);
822 case 3:
return reinterpret_cast<const U4*
>(p_data);
823 case 4:
return reinterpret_cast<const U5*
>(p_data);
824 case 5:
return reinterpret_cast<const U6*
>(p_data);
825 case 6:
return reinterpret_cast<const U7*
>(p_data);
826 default:
return reinterpret_cast<TBase*
>(0);
834 template <
typename TBase,
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6>
835 class upcast_functor<TBase, U1, U2, U3, U4, U5, U6, no_type7, no_type8>
839 TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
843 case 0:
return reinterpret_cast<U1*
>(p_data);
844 case 1:
return reinterpret_cast<U2*
>(p_data);
845 case 2:
return reinterpret_cast<U3*
>(p_data);
846 case 3:
return reinterpret_cast<U4*
>(p_data);
847 case 4:
return reinterpret_cast<U5*
>(p_data);
848 case 5:
return reinterpret_cast<U6*
>(p_data);
849 default:
return reinterpret_cast<TBase*
>(0);
853 const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
const
857 case 0:
return reinterpret_cast<const U1*
>(p_data);
858 case 1:
return reinterpret_cast<const U2*
>(p_data);
859 case 2:
return reinterpret_cast<const U3*
>(p_data);
860 case 3:
return reinterpret_cast<const U4*
>(p_data);
861 case 4:
return reinterpret_cast<const U5*
>(p_data);
862 case 5:
return reinterpret_cast<const U6*
>(p_data);
863 default:
return reinterpret_cast<TBase*
>(0);
871 template <
typename TBase,
typename U1,
typename U2,
typename U3,
typename U4,
typename U5>
872 class upcast_functor<TBase, U1, U2, U3, U4, U5, no_type6, no_type7, no_type8>
876 TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
880 case 0:
return reinterpret_cast<U1*
>(p_data);
881 case 1:
return reinterpret_cast<U2*
>(p_data);
882 case 2:
return reinterpret_cast<U3*
>(p_data);
883 case 3:
return reinterpret_cast<U4*
>(p_data);
884 case 4:
return reinterpret_cast<U5*
>(p_data);
885 default:
return reinterpret_cast<TBase*
>(0);
889 const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
const
893 case 0:
return reinterpret_cast<const U1*
>(p_data);
894 case 1:
return reinterpret_cast<const U2*
>(p_data);
895 case 2:
return reinterpret_cast<const U3*
>(p_data);
896 case 3:
return reinterpret_cast<const U4*
>(p_data);
897 case 4:
return reinterpret_cast<const U5*
>(p_data);
898 default:
return reinterpret_cast<TBase*
>(0);
906 template <
typename TBase,
typename U1,
typename U2,
typename U3,
typename U4>
907 class upcast_functor<TBase, U1, U2, U3, U4, no_type5, no_type6, no_type7, no_type8>
911 TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
915 case 0:
return reinterpret_cast<U1*
>(p_data);
916 case 1:
return reinterpret_cast<U2*
>(p_data);
917 case 2:
return reinterpret_cast<U3*
>(p_data);
918 case 3:
return reinterpret_cast<U4*
>(p_data);
919 default:
return reinterpret_cast<TBase*
>(0);
923 const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
const
927 case 0:
return reinterpret_cast<const U1*
>(p_data);
928 case 1:
return reinterpret_cast<const U2*
>(p_data);
929 case 2:
return reinterpret_cast<const U3*
>(p_data);
930 case 3:
return reinterpret_cast<const U4*
>(p_data);
931 default:
return reinterpret_cast<TBase*
>(0);
939 template <
typename TBase,
typename U1,
typename U2,
typename U3>
940 class upcast_functor<TBase, U1, U2, U3, no_type4, no_type5, no_type6, no_type7, no_type8>
944 TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
948 case 0:
return reinterpret_cast<U1*
>(p_data);
949 case 1:
return reinterpret_cast<U2*
>(p_data);
950 case 2:
return reinterpret_cast<U3*
>(p_data);
951 default:
return reinterpret_cast<TBase*
>(0);
955 const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
const
959 case 0:
return reinterpret_cast<const U1*
>(p_data);
960 case 1:
return reinterpret_cast<const U2*
>(p_data);
961 case 2:
return reinterpret_cast<const U3*
>(p_data);
962 default:
return reinterpret_cast<TBase*
>(0);
970 template <
typename TBase,
typename U1,
typename U2>
971 class upcast_functor<TBase, U1, U2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
975 TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
979 case 0:
return reinterpret_cast<U1*
>(p_data);
980 case 1:
return reinterpret_cast<U2*
>(p_data);
981 default:
return reinterpret_cast<TBase*
>(0);
985 const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
const
989 case 0:
return reinterpret_cast<const U1*
>(p_data);
990 case 1:
return reinterpret_cast<const U2&
>(p_data);
991 default:
return reinterpret_cast<TBase*
>(0);
999 template <
typename TBase,
typename U1>
1000 class upcast_functor<TBase, U1, no_type2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
1004 TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
1008 case 0:
return reinterpret_cast<U1*
>(p_data);
1009 default:
return reinterpret_cast<TBase*
>(0);
1013 const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
const
1017 case 0:
return reinterpret_cast<const U1*
>(p_data);
1018 default:
return reinterpret_cast<TBase*
>(0);
Definition: constant.h:45
Definition: null_type.h:39
Definition: variant.h:216
#define ETL_ASSERT(b, e)
Definition: error_handler.h:290
exception(string_type reason_, string_type file_, numeric_type line_)
Constructor.
Definition: exception.h:67
Definition: exception.h:47
Definition: integral_limits.h:54
Definition: largest.h:227
integral_constant
Definition: type_traits_generator.h:800
is_same
Definition: type_traits_generator.h:981
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3, const TP4 &value4)
Emplace with four constructor parameters.
Definition: variant.h:506
variant(const T &value)
Definition: variant.h:411
bool is_same_type(const variant< U1, U2, U3, U4, U5, U6, U7, U8 > &other) const
Definition: variant.h:579
static bool is_supported_type()
Definition: variant.h:719
T & get()
Definition: variant.h:660
~variant()
Destructor.
Definition: variant.h:200
variant()
Definition: variant.h:401
bool is_same_type(const variant &other) const
Definition: variant.h:568
const T & get() const
Definition: variant.h:674
void call(reader &r)
Definition: variant.h:603
uint_least8_t type_id_t
The type used for ids.
Definition: variant.h:123
reader_type< T1, T2, T3, T4, T5, T6, T7, T8 > reader
The base type for derived readers.
Definition: variant.h:395
bool is_type() const
Definition: variant.h:633
void clear()
Clears the value to 'no valid stored value'.
Definition: variant.h:649
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3)
Emplace with three constructor parameters.
Definition: variant.h:491
variant & operator=(const T &value)
Definition: variant.h:523
size_t index() const
Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID.
Definition: variant.h:641
static const type_id_t UNSUPPORTED_TYPE_ID
The id a unsupported types.
Definition: variant.h:128
TBase & upcast()
Definition: variant.h:687
T & emplace(const TP1 &value1)
Emplace with one constructor parameter.
Definition: variant.h:461
const TBase & upcast() const
Definition: variant.h:697
T & emplace(const TP1 &value1, const TP2 &value2)
Emplace with two constructor parameters.
Definition: variant.h:476
variant(const variant &other)
Definition: variant.h:423
bool is_valid() const
Definition: variant.h:623
Definition: variant.h:117
Definition: absolute.h:37
Definition: alignment.h:118