38#include "../null_type.h"
41#include "../static_assert.h"
47#if defined(ETL_COMPILER_KEIL)
48 #pragma diag_suppress 940
49 #pragma diag_suppress 111
60#if ETL_NOT_USING_LEGACY_VARIANT
64 namespace private_variant
90 variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
91 :
exception(reason_, file_name_, line_number_)
100 class variant_incorrect_type_exception :
public variant_exception
104 variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
105 : variant_exception(ETL_ERROR_TEXT(
"variant:unsupported type", ETL_VARIANT_FILE_ID
"A"), file_name_, line_number_)
114 class bad_variant_access :
public variant_exception
118 bad_variant_access(string_type file_name_, numeric_type line_number_)
119 : variant_exception(ETL_ERROR_TEXT(
"variant:bad variant access", ETL_VARIANT_FILE_ID
"B"), file_name_, line_number_)
128 class variant_not_a_base_exception :
public variant_exception
132 variant_not_a_base_exception(string_type file_name_, numeric_type line_number_)
133 : variant_exception(ETL_ERROR_TEXT(
"variant:not_a base", ETL_VARIANT_FILE_ID
"C"), file_name_, line_number_)
143 template <
typename T1,
typename T2 = etl::null_type<2>,
typename T3 = etl::null_type<3>,
typename T4 = etl::null_type<4>,
144 typename T5 = etl::null_type<5>,
typename T6 = etl::null_type<6>,
typename T7 = etl::null_type<7>,
typename T8 = etl::null_type<8> >
162 template <
typename V1,
typename V2,
typename V3,
typename V4,
typename V5,
typename V6,
typename V7,
typename V8>
163 friend class variant;
168 typedef typename etl::largest_type<T1, T2, T3, T4, T5, T6, T7, T8>::type largest_t;
173 static const size_t SIZE =
sizeof(largest_t);
178 static const size_t ALIGNMENT = etl::largest_alignment<T1, T2, T3, T4, T5, T6, T7, T8>::value;
194 template <
typename T>
195 struct Type_Id_Lookup
197 static const uint_least8_t type_id = etl::is_same<T, T1>::value ? 0
198 : etl::is_same<T, T2>::value ? 1
199 : etl::is_same<T, T3>::value ? 2
200 : etl::is_same<T, T4>::value ? 3
201 : etl::is_same<T, T5>::value ? 4
202 : etl::is_same<T, T6>::value ? 5
203 : etl::is_same<T, T7>::value ? 6
204 : etl::is_same<T, T8>::value ? 7
211 template <
typename T>
212 struct Type_Is_Supported
213 :
public etl::integral_constant< bool, etl::is_same<T, T1>::value || etl::is_same<T, T2>::value || etl::is_same<T, T3>::value
214 || etl::is_same<T, T4>::value || etl::is_same<T, T5>::value || etl::is_same<T, T6>::value
215 || etl::is_same<T, T7>::value || etl::is_same<T, T8>::value>
239 template <
typename R1,
typename R2 = no_type2,
typename R3 = no_type3,
typename R4 = no_type4,
typename R5 = no_type5,
typename R6 = no_type6,
240 typename R7 = no_type7,
typename R8 = no_type8>
245 friend class variant;
262 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5,
typename R6,
typename R7>
267 friend class variant;
281 void read(no_type8&) {}
287 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5,
typename R6>
292 friend class variant;
305 void read(no_type7&) {}
306 void read(no_type8&) {}
312 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5>
313 class reader_type<R1, R2, R3, R4, R5, no_type6, no_type7, no_type8>
317 friend class variant;
329 void read(no_type6&) {}
330 void read(no_type7&) {}
331 void read(no_type8&) {}
337 template <
typename R1,
typename R2,
typename R3,
typename R4>
338 class reader_type<R1, R2, R3, R4, no_type5, no_type6, no_type7, no_type8>
342 friend class variant;
353 void read(no_type5&) {}
354 void read(no_type6&) {}
355 void read(no_type7&) {}
356 void read(no_type8&) {}
362 template <
typename R1,
typename R2,
typename R3>
363 class reader_type<R1, R2, R3, no_type4, no_type5, no_type6, no_type7, no_type8>
367 friend class variant;
377 void read(no_type4&) {}
378 void read(no_type5&) {}
379 void read(no_type6&) {}
380 void read(no_type7&) {}
381 void read(no_type8&) {}
387 template <
typename R1,
typename R2>
388 class reader_type<R1, R2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
392 friend class variant;
401 void read(no_type3&) {}
402 void read(no_type4&) {}
403 void read(no_type5&) {}
404 void read(no_type6&) {}
405 void read(no_type7&) {}
406 void read(no_type8&) {}
412 template <
typename R1>
413 class reader_type<R1, no_type2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
417 friend class variant;
425 void read(no_type2&) {}
426 void read(no_type3&) {}
427 void read(no_type4&) {}
428 void read(no_type5&) {}
429 void read(no_type6&) {}
430 void read(no_type7&) {}
431 void read(no_type8&) {}
437 typedef reader_type<T1, T2, T3, T4, T5, T6, T7, T8>
reader;
454 template <
typename T>
457 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
459 ::new (
static_cast<T*
>(data)) T(value);
460 type_id = Type_Id_Lookup<T>::type_id;
467 template <
size_t Index,
typename T>
471 ETL_STATIC_ASSERT(Type_Id_Lookup<T>::type_id == Index,
"Missmatched type");
472 ::new (
static_cast<T*
>(data)) T(value);
483 switch (other.type_id)
485 case 0: ::new (
static_cast<T1*
>(
data)) T1(other.
get<T1>());
break;
486 case 1: ::new (
static_cast<T2*
>(
data)) T2(other.
get<T2>());
break;
487 case 2: ::new (
static_cast<T3*
>(
data)) T3(other.
get<T3>());
break;
488 case 3: ::new (
static_cast<T4*
>(
data)) T4(other.
get<T4>());
break;
489 case 4: ::new (
static_cast<T5*
>(
data)) T5(other.
get<T5>());
break;
490 case 5: ::new (
static_cast<T6*
>(
data)) T6(other.
get<T6>());
break;
491 case 6: ::new (
static_cast<T7*
>(
data)) T7(other.
get<T7>());
break;
492 case 7: ::new (
static_cast<T8*
>(
data)) T8(other.
get<T8>());
break;
496 type_id = other.type_id;
500#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VARIANT_FORCE_CPP03_IMPLEMENTATION)
504 template <
typename T,
typename... Args>
505 T& emplace(Args&&... args)
507 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
510 ::new (
static_cast<T*
>(data)) T(etl::forward<Args>(args)...);
511 type_id = Type_Id_Lookup<T>::type_id;
513 return *
static_cast<T*
>(
data);
519 template <
typename T>
522 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
525 ::new (
static_cast<T*
>(data)) T();
526 type_id = Type_Id_Lookup<T>::type_id;
528 return *
static_cast<T*
>(data);
534 template <
typename T,
typename TP1>
537 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
540 ::new (
static_cast<T*
>(data)) T(value1);
541 type_id = Type_Id_Lookup<T>::type_id;
543 return *
static_cast<T*
>(data);
549 template <
typename T,
typename TP1,
typename TP2>
550 T&
emplace(
const TP1& value1,
const TP2& value2)
552 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
555 ::new (
static_cast<T*
>(data)) T(value1, value2);
556 type_id = Type_Id_Lookup<T>::type_id;
558 return *
static_cast<T*
>(data);
564 template <
typename T,
typename TP1,
typename TP2,
typename TP3>
565 T&
emplace(
const TP1& value1,
const TP2& value2,
const TP3& value3)
567 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
570 ::new (
static_cast<T*
>(data)) T(value1, value2, value3);
571 type_id = Type_Id_Lookup<T>::type_id;
573 return *
static_cast<T*
>(data);
579 template <
typename T,
typename TP1,
typename TP2,
typename TP3,
typename TP4>
580 T&
emplace(
const TP1& value1,
const TP2& value2,
const TP3& value3,
const TP4& value4)
582 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
585 ::new (
static_cast<T*
>(data)) T(value1, value2, value3, value4);
586 type_id = Type_Id_Lookup<T>::type_id;
588 return *
static_cast<T*
>(data);
596 template <
typename T>
599 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
602 ::new (
static_cast<T*
>(data)) T(value);
603 type_id = Type_Id_Lookup<T>::type_id;
618 switch (other.type_id)
620 case 0: ::new (
static_cast<T1*
>(data)) T1(other.
get<T1>());
break;
621 case 1: ::new (
static_cast<T2*
>(data)) T2(other.
get<T2>());
break;
622 case 2: ::new (
static_cast<T3*
>(data)) T3(other.
get<T3>());
break;
623 case 3: ::new (
static_cast<T4*
>(data)) T4(other.
get<T4>());
break;
624 case 4: ::new (
static_cast<T5*
>(data)) T5(other.
get<T5>());
break;
625 case 5: ::new (
static_cast<T6*
>(data)) T6(other.
get<T6>());
break;
626 case 6: ::new (
static_cast<T7*
>(data)) T7(other.
get<T7>());
break;
627 case 7: ::new (
static_cast<T8*
>(data)) T8(other.
get<T8>());
break;
631 type_id = other.type_id;
644 return type_id == other.type_id;
652 template <
typename V1,
typename V2,
typename V3,
typename V4,
typename V5,
typename V6,
typename V7,
typename V8>
653 bool is_same_type(
const variant<V1, V2, V3, V4, V5, V6, V7, V8>& other)
const
655 bool is_same =
false;
657 switch (other.type_id)
659 case 0: is_same = (type_id == Type_Id_Lookup<V1>::type_id);
break;
660 case 1: is_same = (type_id == Type_Id_Lookup<V2>::type_id);
break;
661 case 2: is_same = (type_id == Type_Id_Lookup<V3>::type_id);
break;
662 case 3: is_same = (type_id == Type_Id_Lookup<V4>::type_id);
break;
663 case 4: is_same = (type_id == Type_Id_Lookup<V5>::type_id);
break;
664 case 5: is_same = (type_id == Type_Id_Lookup<V6>::type_id);
break;
665 case 6: is_same = (type_id == Type_Id_Lookup<V7>::type_id);
break;
666 case 7: is_same = (type_id == Type_Id_Lookup<V8>::type_id);
break;
682 case 0: r.read(
static_cast<T1&
>(data));
break;
683 case 1: r.read(
static_cast<T2&
>(data));
break;
684 case 2: r.read(
static_cast<T3&
>(data));
break;
685 case 3: r.read(
static_cast<T4&
>(data));
break;
686 case 4: r.read(
static_cast<T5&
>(data));
break;
687 case 5: r.read(
static_cast<T6&
>(data));
break;
688 case 6: r.read(
static_cast<T7&
>(data));
break;
689 case 7: r.read(
static_cast<T8&
>(data));
break;
709 template <
typename T>
712 return type_id == Type_Id_Lookup<T>::type_id;
737 template <
typename T>
740 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
743 return static_cast<T&
>(data);
752 template <
typename T>
755 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
758 return static_cast<const T&
>(data);
765 template <
typename TBase>
770 return reinterpret_cast<TBase*
>(
static_cast<uint_least8_t*
>(data));
782 template <
typename TBase>
796 template <
typename TBase>
801 return reinterpret_cast<const TBase*
>(
static_cast<const uint_least8_t*
>(data));
813 template <
typename TBase>
826 template <
typename TBase>
833 case 0: is_base = etl::is_base_of<TBase, T1>::value;
break;
834 case 1: is_base = etl::is_base_of<TBase, T2>::value;
break;
835 case 2: is_base = etl::is_base_of<TBase, T3>::value;
break;
836 case 3: is_base = etl::is_base_of<TBase, T4>::value;
break;
837 case 4: is_base = etl::is_base_of<TBase, T5>::value;
break;
838 case 5: is_base = etl::is_base_of<TBase, T6>::value;
break;
839 case 6: is_base = etl::is_base_of<TBase, T7>::value;
break;
840 case 7: is_base = etl::is_base_of<TBase, T8>::value;
break;
841 default: is_base =
false;
break;
888 template <
typename T>
891 return Type_Is_Supported<T>::value;
900 void destruct_current()
906 static_cast<T1*
>(
data)->~T1();
911 static_cast<T2*
>(data)->~T2();
916 static_cast<T3*
>(
data)->~T3();
921 static_cast<T4*
>(
data)->~T4();
926 static_cast<T5*
>(
data)->~T5();
931 static_cast<T6*
>(
data)->~T6();
936 static_cast<T7*
>(
data)->~T7();
941 static_cast<T8*
>(
data)->~T8();
950 type_id = UNSUPPORTED_TYPE_ID;
958 typename etl::aligned_storage<SIZE, ALIGNMENT>::type
data;
966 namespace private_variant
968 template <
size_t,
typename>
970#define ETL_VARIANT_HELPER(INDEX, TYPE) \
971 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> \
972 struct variant_alternative_helper<INDEX, variant<T1, T2, T3, T4, T5, T6, T7, T8> > \
976 ETL_VARIANT_HELPER(0, T1)
977 ETL_VARIANT_HELPER(1, T2)
978 ETL_VARIANT_HELPER(2, T3)
979 ETL_VARIANT_HELPER(3, T4)
980 ETL_VARIANT_HELPER(4, T5)
981 ETL_VARIANT_HELPER(5, T6)
982 ETL_VARIANT_HELPER(6, T7)
983 ETL_VARIANT_HELPER(7, T8)
984#undef ETL_VARIANT_HELPER
987 template <
size_t tIndex,
typename TVariant>
993 template <
size_t tIndex,
typename TVariant>
999 template <
size_t tIndex,
typename TVariant>
1005 template <
size_t tIndex,
typename TVariant>
1011 template <
typename T,
typename TVariant>
1017 template <
typename T,
typename TVariant>
1018 inline T
const& get(TVariant
const& variant)
1020 return variant.template get<T>();
1023 template <
size_t tIndex,
typename TVariant>
1024 inline typename variant_alternative<tIndex, TVariant>::type&
get(TVariant& variant)
1026 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
1029 template <
size_t tIndex,
typename TVariant>
1030 inline typename variant_alternative<tIndex, TVariant const>::type&
get(TVariant
const& variant)
1032 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
1035#define ETL_GEN_LEGACY_VISIT(VISITQUAL, VARIANTQUAL) \
1036 template <typename TReturn, typename TVisitor, typename TVariant> \
1037 static TReturn visit(TVisitor VISITQUAL visitor, TVariant VARIANTQUAL variant) \
1039 switch (variant.index()) \
1041 case 0: return static_cast<TReturn>(visitor(get<0>(variant))); \
1042 case 1: return static_cast<TReturn>(visitor(get<1>(variant))); \
1043 case 2: return static_cast<TReturn>(visitor(get<2>(variant))); \
1044 case 3: return static_cast<TReturn>(visitor(get<3>(variant))); \
1045 case 4: return static_cast<TReturn>(visitor(get<4>(variant))); \
1046 case 5: return static_cast<TReturn>(visitor(get<5>(variant))); \
1047 case 6: return static_cast<TReturn>(visitor(get<6>(variant))); \
1048 case 7: return static_cast<TReturn>(visitor(get<7>(variant))); \
1049 default: ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(bad_variant_access), TReturn()); \
1053 ETL_GEN_LEGACY_VISIT(&, &)
1054 ETL_GEN_LEGACY_VISIT(const&, &)
1055 ETL_GEN_LEGACY_VISIT(&, const&)
1056 ETL_GEN_LEGACY_VISIT(const&, const&)
1058#undef ETL_GEN_LEGACY_VISIT
1060#if ETL_NOT_USING_LEGACY_VARIANT
Definition null_type.h:40
Definition variant_legacy.h:242
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
Definition exception.h:59
Definition integral_limits.h:518
variant(const T &value)
Definition variant_legacy.h:455
static bool is_supported_type()
Definition variant_legacy.h:889
const T & get() const
Definition variant_legacy.h:753
~variant()
Destructor.
Definition variant_legacy.h:224
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3, const TP4 &value4)
Emplace with four constructor parameters.
Definition variant_legacy.h:580
bool is_same_type(const variant &other) const
Definition variant_legacy.h:642
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3)
Emplace with three constructor parameters.
Definition variant_legacy.h:565
void call(reader &r)
Definition variant_legacy.h:678
T & get()
Definition variant_legacy.h:738
bool is_base_of() const
Definition variant_legacy.h:827
variant(etl::in_place_index_t< Index >, T const &value)
Definition variant_legacy.h:468
uint_least8_t type_id_t
Definition variant_legacy.h:152
bool is_same_type(const variant< V1, V2, V3, V4, V5, V6, V7, V8 > &other) const
Definition variant_legacy.h:653
variant & operator=(const T &value)
Definition variant_legacy.h:597
variant & operator=(const variant &other)
Definition variant_legacy.h:612
T & emplace(const TP1 &value1)
Emplace with one constructor parameter.
Definition variant_legacy.h:535
const TBase * upcast_ptr() const
Definition variant_legacy.h:797
reader_type< etl::monostate, value_type, error_type, etl::null_type< 4 >, etl::null_type< 5 >, etl::null_type< 6 >, etl::null_type< 7 >, etl::null_type< 8 > > reader
Definition variant_legacy.h:437
bool is_type() const
Definition variant_legacy.h:710
void clear()
Clears the value to 'no valid stored value'.
Definition variant_legacy.h:726
T & emplace(const TP1 &value1, const TP2 &value2)
Emplace with two constructor parameters.
Definition variant_legacy.h:550
TBase * upcast_ptr()
Definition variant_legacy.h:766
T & emplace()
Emplace with one constructor parameter.
Definition variant_legacy.h:520
size_t index() const
Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID.
Definition variant_legacy.h:718
TBase & upcast()
Definition variant_legacy.h:783
static const type_id_t UNSUPPORTED_TYPE_ID
Definition variant_legacy.h:157
const TBase & upcast() const
Definition variant_legacy.h:814
bool is_valid() const
Definition variant_legacy.h:698
Definition variant_legacy.h:146
Definition variant_legacy.h:101
Definition variant_legacy.h:129
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1228
T & get(array< T, Size > &a)
Definition array.h:1161
integral_constant
Definition type_traits.h:67
A 'no-value' placeholder.
Definition monostate.h:42
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:46
Definition variant_legacy.h:72
Definition variant_legacy.h:969
Definition variant_legacy.h:989