31#include "../platform.h"
32#include "../utility.h"
33#include "../largest.h"
34#include "../exception.h"
35#include "../type_traits.h"
36#include "../integral_limits.h"
37#include "../static_assert.h"
38#include "../alignment.h"
39#include "../error_handler.h"
40#include "../parameter_pack.h"
41#include "../placement_new.h"
42#include "../visitor.h"
44#include "../initializer_list.h"
48#if defined(ETL_COMPILER_KEIL)
49 #pragma diag_suppress 940
50 #pragma diag_suppress 111
53#if ETL_CPP11_NOT_SUPPORTED
54 #if !defined(ETL_IN_UNIT_TEST)
55 #error NOT SUPPORTED FOR C++03 OR BELOW
66 namespace private_variant
72 template <
typename... TTypes>
77 static constexpr size_t size =
sizeof...(TTypes);
87 using type = etl::remove_cvref_t<T>;
90 template <
typename Type,
typename T1,
typename... TRest>
91 struct index_of_type_helper
97 template <
typename Type,
typename T1>
98 struct index_of_type_helper<Type, T1>
100 static constexpr size_t value = 1UL;
105 static_assert(
etl::is_one_of<type, TTypes...>::value,
"T is not in parameter pack");
108 static constexpr size_t value = index_of_type_helper<type, TTypes...>::value - 1;
115 class type_from_index
120 template <
size_t II,
size_t N,
typename T1,
typename... TRest>
121 struct type_from_index_helper
123 using type =
typename etl::conditional<II == N, T1,
typename type_from_index_helper<II, N + 1, TRest...>::type>::type;
127 template <
size_t II,
size_t N,
typename T1>
128 struct type_from_index_helper<II, N, T1>
136 using type =
typename type_from_index_helper<I, 0, TTypes...>::type;
141 using type_from_index_t =
typename type_from_index<I>::type;
147 static constexpr bool Copyable =
true;
148 static constexpr bool Non_Copyable =
false;
149 static constexpr bool Moveable =
true;
150 static constexpr bool Non_Moveable =
false;
155 static constexpr int Copy = 0;
156 static constexpr int Move = 1;
157 static constexpr int Destroy = 2;
162 template <
typename T,
bool IsCopyable,
bool IsMoveable>
163 struct operation_type;
168 struct operation_type<void, Non_Copyable, Non_Moveable>
170 static void do_operation(
int ,
char* ,
const char* )
173#if defined(ETL_IN_UNIT_TEST)
181 template <
typename T>
182 struct operation_type<T, Non_Copyable, Non_Moveable>
184 static void do_operation(
int operation,
char* pstorage,
const char* )
190 reinterpret_cast<const T*
>(pstorage)->~T();
197 #if defined(ETL_IN_UNIT_TEST)
208 template <
typename T>
209 struct operation_type<T, Non_Copyable, Moveable>
211 static void do_operation(
int operation,
char* pstorage,
const char* pvalue)
217 ::new (pstorage) T(etl::move(*
reinterpret_cast<T*
>(
const_cast<char*
>(pvalue))));
223 reinterpret_cast<const T*
>(pstorage)->~T();
230 #if defined(ETL_DEBUG)
241 template <
typename T>
242 struct operation_type<T, Copyable, Non_Moveable>
244 static void do_operation(
int operation,
char* pstorage,
const char* pvalue)
250 ::new (pstorage) T(*
reinterpret_cast<const T*
>(pvalue));
256 reinterpret_cast<const T*
>(pstorage)->~T();
263 #if defined(ETL_IN_UNIT_TEST)
274 template <
typename T>
275 struct operation_type<T, Copyable, Moveable>
277 static void do_operation(
int operation,
char* pstorage,
const char* pvalue)
283 ::new (pstorage) T(*
reinterpret_cast<const T*
>(pvalue));
289 ::new (pstorage) T(etl::move(*
reinterpret_cast<T*
>(
const_cast<char*
>(pvalue))));
295 reinterpret_cast<const T*
>(pstorage)->~T();
302#if defined(ETL_IN_UNIT_TEST)
317 template <
typename... TTypes>
323 template <
size_t Index,
typename T>
324 struct variant_alternative;
326 template <
size_t Index,
typename... TTypes>
327 struct variant_alternative<Index,
etl::variant<TTypes...>>
329 using type =
typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<Index>::type;
332 template <
size_t Index,
typename T>
333 struct variant_alternative<Index, const T>
335 using type =
typename variant_alternative<Index, T>::type;
338 template <
size_t Index,
typename T>
339 using variant_alternative_t =
typename variant_alternative<Index, T>::type;
343 template <
typename T,
typename... TTypes>
348 template <
size_t Index,
typename... VTypes>
349 ETL_CONSTEXPR14 etl::variant_alternative_t<Index,
etl::variant<VTypes...>>&
352 template <
size_t Index,
typename... VTypes>
353 ETL_CONSTEXPR14 etl::variant_alternative_t<Index,
etl::variant<VTypes...>>&&
356 template <
size_t Index,
typename... VTypes>
357 ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<VTypes...>>&
360 template <
size_t Index,
typename... VTypes>
361 ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<VTypes...>>&&
364 template <
typename T,
typename... VTypes>
367 template <
typename T,
typename... VTypes>
370 template <
typename T,
typename... VTypes>
373 template <
typename T,
typename... VTypes>
391#if ETL_NOT_USING_STL && !defined(ETL_USE_TYPE_TRAITS_BUILTINS)
407 class variant_exception :
public exception
410 variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
411 :
exception(reason_, file_name_, line_number_)
420 class variant_incorrect_type_exception :
public variant_exception
423 variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
424 : variant_exception(ETL_ERROR_TEXT(
"variant:unsupported type", ETL_VARIANT_FILE_ID
"A"), file_name_, line_number_)
433 class bad_variant_access :
public variant_exception
436 bad_variant_access(string_type file_name_, numeric_type line_number_)
437 : variant_exception(ETL_ERROR_TEXT(
"variant:bad variant access", ETL_VARIANT_FILE_ID
"B"), file_name_, line_number_)
446 template <
typename... TTypes>
459 template <
size_t Index,
typename... VTypes>
460 friend ETL_CONSTEXPR14 etl::variant_alternative_t<Index,
etl::variant<VTypes...>>&
463 template <
size_t Index,
typename... VTypes>
464 friend ETL_CONSTEXPR14 etl::variant_alternative_t<Index,
etl::variant<VTypes...>>&&
467 template <
size_t Index,
typename... VTypes>
468 friend ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<VTypes...>>&
471 template <
size_t Index,
typename... VTypes>
472 friend ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<VTypes...>>&&
475 template <
typename T,
typename... VTypes>
478 template <
typename T,
typename... VTypes>
481 template <
typename T,
typename... VTypes>
484 template <
typename T,
typename... VTypes>
490 template <
typename... UTypes>
491 friend class variant;
496 using largest_t =
typename largest_type<TTypes...>::type;
501 static const size_t Size =
sizeof(largest_t);
511 template <
typename T,
bool IsCopyable,
bool IsMoveable>
512 using operation_type = private_variant::operation_type<T, IsCopyable, IsMoveable>;
517 static constexpr int Copy = private_variant::Copy;
518 static constexpr int Move = private_variant::Move;
519 static constexpr int Destroy = private_variant::Destroy;
528 ETL_CONSTEXPR14 variant()
530 using type =
typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<0U>::type;
532 default_construct_in_place<type>(data);
542 template <
typename T, etl::enable_if_t<!etl::is_same<etl::remove_cvref_t<T>, variant>::value,
int> = 0>
543 ETL_CONSTEXPR14 variant(T&& value)
544 : operation(operation_type<
etl::remove_cvref_t<T>,
etl::is_copy_constructible<
etl::remove_cvref_t<T>>::value,
etl::is_move_constructible<
etl::remove_cvref_t<T>>::value>::do_operation)
545 , type_id(
etl::private_variant::parameter_pack<TTypes...>::template index_of_type<
etl::remove_cvref_t<T>>::value)
549 construct_in_place<etl::remove_cvref_t<T>>(data, etl::forward<T>(value));
557 template <
typename T,
typename... TArgs>
559 : operation(operation_type<
etl::remove_cvref_t<T>,
etl::is_copy_constructible<
etl::remove_cvref_t<T>>::value,
etl::is_move_constructible<
etl::remove_cvref_t<T>>::value>::do_operation)
560 , type_id(
etl::private_variant::parameter_pack<TTypes...>::template index_of_type<
etl::remove_cvref_t<T>>::value)
564 construct_in_place_args<etl::remove_cvref_t<T>>(data, etl::forward<TArgs>(args)...);
572 template <
size_t Index,
typename... TArgs>
576 using type =
typename private_variant::parameter_pack<TTypes...>:: template type_from_index_t<Index>;
577 static_assert(
etl::is_one_of<type, TTypes...> ::value,
"Unsupported type");
579 construct_in_place_args<type>(data, etl::forward<TArgs>(args)...);
585#if ETL_HAS_INITIALIZER_LIST
590 template <
typename T,
typename U,
typename... TArgs >
592 : operation(operation_type<
etl::remove_cvref_t<T>,
etl::is_copy_constructible<
etl::remove_cvref_t<T>>::value,
etl::is_move_constructible<
etl::remove_cvref_t<T>>::value>::do_operation)
593 , type_id(private_variant::parameter_pack<TTypes...>:: template index_of_type<
etl::remove_cvref_t<T>>::value)
597 construct_in_place_args<etl::remove_cvref_t<T>>(data, init, etl::forward<TArgs>(args)...);
605 template <
size_t Index,
typename U,
typename... TArgs >
609 using type =
typename private_variant::parameter_pack<TTypes...>:: template type_from_index_t<Index>;
610 static_assert(
etl::is_one_of<type, TTypes...> ::value,
"Unsupported type");
612 construct_in_place_args<type>(data, init, etl::forward<TArgs>(args)...);
624 ETL_CONSTEXPR14 variant(
const variant& other)
625 : operation(other.operation)
626 , type_id(other.type_id)
630 if (other.index() == variant_npos)
632 type_id = variant_npos;
636 operation(private_variant::Copy, data, other.data);
647 ETL_CONSTEXPR14 variant(variant&& other)
648 : operation(other.operation)
649 , type_id(other.type_id)
653 if (other.index() == variant_npos)
655 type_id = variant_npos;
659 operation(private_variant::Move, data, other.data);
664 type_id = variant_npos;
674 if (
index() != variant_npos)
676 operation(private_variant::Destroy, data,
nullptr);
679 operation = operation_type<void, false, false>::do_operation;
680 type_id = variant_npos;
686 template <
typename T,
typename... TArgs>
689 static_assert(
etl::is_one_of<T, TTypes...>::value,
"Unsupported type");
691 using type = etl::remove_cvref_t<T>;
693 operation(private_variant::Destroy, data,
nullptr);
695 construct_in_place_args<type>(data, etl::forward<TArgs>(args)...);
699 type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
701 return *
static_cast<T*
>(data);
707 template <
size_t Index,
typename... TArgs>
710 static_assert(Index < etl::private_variant::parameter_pack<TTypes...>::size,
"Index out of range");
712 using type =
typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<Index>::type;
714 operation(private_variant::Destroy, data,
nullptr);
716 construct_in_place_args<type>(data, etl::forward<TArgs>(args)...);
722 return *
static_cast<type*
>(data);
729 template <
typename T, etl::enable_if_t<!etl::is_same<etl::remove_cvref_t<T>, variant>::value,
int> = 0>
732 using type = etl::remove_cvref_t<T>;
734 static_assert(
etl::is_one_of<type, TTypes...>::value,
"Unsupported type");
736 operation(private_variant::Destroy, data,
nullptr);
738 construct_in_place<type>(data, etl::forward<T>(value));
741 type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<type>::value;
754 if (other.index() == variant_npos)
756 type_id = variant_npos;
760 operation(Destroy, data,
nullptr);
762 operation = other.operation;
763 operation(Copy, data, other.data);
765 type_id = other.type_id;
780 if (other.index() == variant_npos)
782 type_id = variant_npos;
786 operation(Destroy, data,
nullptr);
788 operation = other.operation;
789 operation(Move, data, other.data);
791 type_id = other.type_id;
802 constexpr bool valueless_by_exception() const noexcept
804 return type_id == variant_npos;
810 constexpr size_t index() const noexcept
818 void swap(variant& rhs)
noexcept
820 variant temp(etl::move(*
this));
821 *
this = etl::move(rhs);
822 rhs = etl::move(temp);
828 template <
typename TVisitor>
829 etl::enable_if_t<etl::is_visitor<TVisitor>::value,
void>
832#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
833 do_visitor(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
842 template <
typename TVisitor>
843 etl::enable_if_t<etl::is_visitor<TVisitor>::value,
void>
844 accept(TVisitor& v)
const
846#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
847 do_visitor(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
856 template <
typename TVisitor>
857 etl::enable_if_t<!etl::is_visitor<TVisitor>::value,
void>
860#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
861 do_operator(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
870 template <
typename TVisitor>
871 etl::enable_if_t<!etl::is_visitor<TVisitor>::value,
void>
872 accept(TVisitor& v)
const
874#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
875 do_operator(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
885 template <
typename TVisitor>
886#if !defined(ETL_IN_UNIT_TEST)
889 void accept_visitor(TVisitor& v)
891#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
892 do_visitor(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
902 template <
typename TVisitor>
903#if !defined(ETL_IN_UNIT_TEST)
906 void accept_visitor(TVisitor& v)
const
908#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
909 do_visitor(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
919 template <
typename TVisitor>
920#if !defined(ETL_IN_UNIT_TEST)
923 void accept_functor(TVisitor& v)
925#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
926 do_operator(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
936 template <
typename TVisitor>
937#if !defined(ETL_IN_UNIT_TEST)
940 void accept_functor(TVisitor& v)
const
942#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
943 do_operator(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
952 using operation_function = void(*)(int,
char*,
const char*);
957 template <
typename T>
958 static void construct_in_place(
char* pstorage,
const T& value)
960 using type = etl::remove_cvref_t<T>;
962 ::new (pstorage) type(value);
968 template <
typename T>
969 static void construct_in_place(
char* pstorage, T&& value)
971 using type = etl::remove_cvref_t<T>;
973 ::new (pstorage) type(etl::move(value));
979 template <
typename T,
typename... TArgs>
980 static void construct_in_place_args(
char* pstorage, TArgs&&... args)
982 using type = etl::remove_cvref_t<T>;
984 ::new (pstorage) type(etl::forward<TArgs>(args)...);
990 template <
typename T>
991 static void default_construct_in_place(
char* pstorage)
993 using type = etl::remove_cvref_t<T>;
995 ::new (pstorage) type();
998#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1002 template <
typename TVisitor,
size_t... I>
1003 void do_visitor(TVisitor& visitor, etl::index_sequence<I...>)
1005 (attempt_visitor<I>(visitor) || ...);
1011 template <
typename TVisitor,
size_t... I>
1012 void do_visitor(TVisitor& visitor, etl::index_sequence<I...>)
const
1014 (attempt_visitor<I>(visitor) || ...);
1020 template <
typename TVisitor>
1021 void do_visitor(TVisitor& visitor)
1025 case 0: { visitor.visit(etl::get<0>(*
this));
break; }
1026 case 1: { visitor.visit(etl::get<1>(*
this));
break; }
1027 case 2: { visitor.visit(etl::get<2>(*
this));
break; }
1028 case 3: { visitor.visit(etl::get<3>(*
this));
break; }
1029 case 4: { visitor.visit(etl::get<4>(*
this));
break; }
1030 case 5: { visitor.visit(etl::get<5>(*
this));
break; }
1031 case 6: { visitor.visit(etl::get<6>(*
this));
break; }
1032 case 7: { visitor.visit(etl::get<7>(*
this));
break; }
1033#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
1034 case 8: { visitor.visit(etl::get<8>(*
this));
break; }
1035 case 9: { visitor.visit(etl::get<9>(*
this));
break; }
1036 case 10: { visitor.visit(etl::get<10>(*
this));
break; }
1037 case 11: { visitor.visit(etl::get<11>(*
this));
break; }
1038 case 12: { visitor.visit(etl::get<12>(*
this));
break; }
1039 case 13: { visitor.visit(etl::get<13>(*
this));
break; }
1040 case 14: { visitor.visit(etl::get<14>(*
this));
break; }
1041 case 15: { visitor.visit(etl::get<15>(*
this));
break; }
1042#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
1043 case 16: { visitor.visit(etl::get<16>(*
this));
break; }
1044 case 17: { visitor.visit(etl::get<17>(*
this));
break; }
1045 case 18: { visitor.visit(etl::get<18>(*
this));
break; }
1046 case 19: { visitor.visit(etl::get<19>(*
this));
break; }
1047 case 20: { visitor.visit(etl::get<20>(*
this));
break; }
1048 case 21: { visitor.visit(etl::get<21>(*
this));
break; }
1049 case 22: { visitor.visit(etl::get<22>(*
this));
break; }
1050 case 23: { visitor.visit(etl::get<23>(*
this));
break; }
1051#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
1052 case 24: { visitor.visit(etl::get<24>(*
this));
break; }
1053 case 25: { visitor.visit(etl::get<25>(*
this));
break; }
1054 case 26: { visitor.visit(etl::get<26>(*
this));
break; }
1055 case 27: { visitor.visit(etl::get<27>(*
this));
break; }
1056 case 28: { visitor.visit(etl::get<28>(*
this));
break; }
1057 case 29: { visitor.visit(etl::get<29>(*
this));
break; }
1058 case 30: { visitor.visit(etl::get<30>(*
this));
break; }
1059 case 31: { visitor.visit(etl::get<31>(*
this));
break; }
1070 template <
typename TVisitor>
1071 void do_visitor(TVisitor& visitor)
const
1075 case 0: { visitor.visit(etl::get<0>(*
this));
break; }
1076 case 1: { visitor.visit(etl::get<1>(*
this));
break; }
1077 case 2: { visitor.visit(etl::get<2>(*
this));
break; }
1078 case 3: { visitor.visit(etl::get<3>(*
this));
break; }
1079 case 4: { visitor.visit(etl::get<4>(*
this));
break; }
1080 case 5: { visitor.visit(etl::get<5>(*
this));
break; }
1081 case 6: { visitor.visit(etl::get<6>(*
this));
break; }
1082 case 7: { visitor.visit(etl::get<7>(*
this));
break; }
1083#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
1084 case 8: { visitor.visit(etl::get<8>(*
this));
break; }
1085 case 9: { visitor.visit(etl::get<9>(*
this));
break; }
1086 case 10: { visitor.visit(etl::get<10>(*
this));
break; }
1087 case 11: { visitor.visit(etl::get<11>(*
this));
break; }
1088 case 12: { visitor.visit(etl::get<12>(*
this));
break; }
1089 case 13: { visitor.visit(etl::get<13>(*
this));
break; }
1090 case 14: { visitor.visit(etl::get<14>(*
this));
break; }
1091 case 15: { visitor.visit(etl::get<15>(*
this));
break; }
1092#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
1093 case 16: { visitor.visit(etl::get<16>(*
this));
break; }
1094 case 17: { visitor.visit(etl::get<17>(*
this));
break; }
1095 case 18: { visitor.visit(etl::get<18>(*
this));
break; }
1096 case 19: { visitor.visit(etl::get<19>(*
this));
break; }
1097 case 20: { visitor.visit(etl::get<20>(*
this));
break; }
1098 case 21: { visitor.visit(etl::get<21>(*
this));
break; }
1099 case 22: { visitor.visit(etl::get<22>(*
this));
break; }
1100 case 23: { visitor.visit(etl::get<23>(*
this));
break; }
1101#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
1102 case 24: { visitor.visit(etl::get<24>(*
this));
break; }
1103 case 25: { visitor.visit(etl::get<25>(*
this));
break; }
1104 case 26: { visitor.visit(etl::get<26>(*
this));
break; }
1105 case 27: { visitor.visit(etl::get<27>(*
this));
break; }
1106 case 28: { visitor.visit(etl::get<28>(*
this));
break; }
1107 case 29: { visitor.visit(etl::get<29>(*
this));
break; }
1108 case 30: { visitor.visit(etl::get<30>(*
this));
break; }
1109 case 31: { visitor.visit(etl::get<31>(*
this));
break; }
1121 template <
size_t Index,
typename TVisitor>
1122 bool attempt_visitor(TVisitor& visitor)
1124 if (Index ==
index())
1129 auto& v = etl::get<Index>(*
this);
1142 template <
size_t Index,
typename TVisitor>
1143 bool attempt_visitor(TVisitor& visitor)
const
1145 if (Index ==
index())
1150 auto& v = etl::get<Index>(*
this);
1160#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1164 template <
typename TVisitor,
size_t... I>
1165 void do_operator(TVisitor& visitor, etl::index_sequence<I...>)
1167 (attempt_operator<I>(visitor) || ...);
1173 template <
typename TVisitor,
size_t... I>
1174 void do_operator(TVisitor& visitor, etl::index_sequence<I...>)
const
1176 (attempt_operator<I>(visitor) || ...);
1182 template <
typename TVisitor>
1183 void do_operator(TVisitor& visitor)
1185#if defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
1186 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 8U,
"ETL_VARIANT_CPP11_MAX_8_TYPES - Only a maximum of 8 types are allowed in this variant");
1189#if defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
1190 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 16U,
"ETL_VARIANT_CPP11_MAX_16_TYPES - Only a maximum of 16 types are allowed in this variant");
1193#if defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
1194 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 24U,
"ETL_VARIANT_CPP11_MAX_24_TYPES - Only a maximum of 24 types are allowed in this variant");
1197 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 32U,
"A maximum of 32 types are allowed in this variant");
1201 case 0: visitor(etl::get<0>(*
this));
break;
1202 case 1: visitor(etl::get<1>(*
this));
break;
1203 case 2: visitor(etl::get<2>(*
this));
break;
1204 case 3: visitor(etl::get<3>(*
this));
break;
1205 case 4: visitor(etl::get<4>(*
this));
break;
1206 case 5: visitor(etl::get<5>(*
this));
break;
1207 case 6: visitor(etl::get<6>(*
this));
break;
1208 case 7: visitor(etl::get<7>(*
this));
break;
1209#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
1210 case 8: visitor(etl::get<8>(*
this));
break;
1211 case 9: visitor(etl::get<9>(*
this));
break;
1212 case 10: visitor(etl::get<10>(*
this));
break;
1213 case 11: visitor(etl::get<11>(*
this));
break;
1214 case 12: visitor(etl::get<12>(*
this));
break;
1215 case 13: visitor(etl::get<13>(*
this));
break;
1216 case 14: visitor(etl::get<14>(*
this));
break;
1217 case 15: visitor(etl::get<15>(*
this));
break;
1218#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
1219 case 16: visitor(etl::get<16>(*
this));
break;
1220 case 17: visitor(etl::get<17>(*
this));
break;
1221 case 18: visitor(etl::get<18>(*
this));
break;
1222 case 19: visitor(etl::get<19>(*
this));
break;
1223 case 20: visitor(etl::get<20>(*
this));
break;
1224 case 21: visitor(etl::get<21>(*
this));
break;
1225 case 22: visitor(etl::get<22>(*
this));
break;
1226 case 23: visitor(etl::get<23>(*
this));
break;
1227#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
1228 case 24: visitor(etl::get<24>(*
this));
break;
1229 case 25: visitor(etl::get<25>(*
this));
break;
1230 case 26: visitor(etl::get<26>(*
this));
break;
1231 case 27: visitor(etl::get<27>(*
this));
break;
1232 case 28: visitor(etl::get<28>(*
this));
break;
1233 case 29: visitor(etl::get<29>(*
this));
break;
1234 case 30: visitor(etl::get<30>(*
this));
break;
1235 case 31: visitor(etl::get<31>(*
this));
break;
1246 template <
typename TVisitor>
1247 void do_operator(TVisitor& visitor)
const
1249#if defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
1250 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 8U,
"ETL_VARIANT_CPP11_MAX_8_TYPES - Only a maximum of 8 types are allowed in this variant");
1253#if defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
1254 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 16U,
"ETL_VARIANT_CPP11_MAX_16_TYPES - Only a maximum of 16 types are allowed in this variant");
1257#if defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
1258 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 24U,
"ETL_VARIANT_CPP11_MAX_24_TYPES - Only a maximum of 24 types are allowed in this variant");
1261 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 32U,
"A maximum of 32 types are allowed in this variant");
1265 case 0: visitor(etl::get<0>(*
this));
break;
1266 case 1: visitor(etl::get<1>(*
this));
break;
1267 case 2: visitor(etl::get<2>(*
this));
break;
1268 case 3: visitor(etl::get<3>(*
this));
break;
1269 case 4: visitor(etl::get<4>(*
this));
break;
1270 case 5: visitor(etl::get<5>(*
this));
break;
1271 case 6: visitor(etl::get<6>(*
this));
break;
1272 case 7: visitor(etl::get<7>(*
this));
break;
1273#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
1274 case 8: visitor(etl::get<8>(*
this));
break;
1275 case 9: visitor(etl::get<9>(*
this));
break;
1276 case 10: visitor(etl::get<10>(*
this));
break;
1277 case 11: visitor(etl::get<11>(*
this));
break;
1278 case 12: visitor(etl::get<12>(*
this));
break;
1279 case 13: visitor(etl::get<13>(*
this));
break;
1280 case 14: visitor(etl::get<14>(*
this));
break;
1281 case 15: visitor(etl::get<15>(*
this));
break;
1282#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
1283 case 16: visitor(etl::get<16>(*
this));
break;
1284 case 17: visitor(etl::get<17>(*
this));
break;
1285 case 18: visitor(etl::get<18>(*
this));
break;
1286 case 19: visitor(etl::get<19>(*
this));
break;
1287 case 20: visitor(etl::get<20>(*
this));
break;
1288 case 21: visitor(etl::get<21>(*
this));
break;
1289 case 22: visitor(etl::get<22>(*
this));
break;
1290 case 23: visitor(etl::get<23>(*
this));
break;
1291#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
1292 case 24: visitor(etl::get<24>(*
this));
break;
1293 case 25: visitor(etl::get<25>(*
this));
break;
1294 case 26: visitor(etl::get<26>(*
this));
break;
1295 case 27: visitor(etl::get<27>(*
this));
break;
1296 case 28: visitor(etl::get<28>(*
this));
break;
1297 case 29: visitor(etl::get<29>(*
this));
break;
1298 case 30: visitor(etl::get<30>(*
this));
break;
1299 case 31: visitor(etl::get<31>(*
this));
break;
1311 template <
size_t Index,
typename TVisitor>
1312 bool attempt_operator(TVisitor& visitor)
1314 if (Index ==
index())
1316 auto& v = etl::get<Index>(*
this);
1329 template <
size_t Index,
typename TVisitor>
1330 bool attempt_operator(TVisitor& visitor)
const
1332 if (Index ==
index())
1334 auto& v = etl::get<Index>(*
this);
1353 operation_function operation;
1364 template <
typename T,
typename... TTypes>
1367 constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1369 return (Index == variant_npos) ? false : (v.index() == Index);
1375 template <
size_t Index,
typename... TTypes>
1378 return (Index == v.index());
1384 template <
typename... TTypes>
1387 return (index == v.index());
1393 template <
size_t Index,
typename... TTypes>
1394 ETL_CONSTEXPR14 etl::variant_alternative_t<Index,
etl::variant<TTypes...>>&
1397#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1398 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
1403 using type = etl::variant_alternative_t<Index,
etl::variant<TTypes...>>;
1405 return *
static_cast<type*
>(v.data);
1409 template <
size_t Index,
typename... TTypes>
1410 ETL_CONSTEXPR14 etl::variant_alternative_t<Index,
etl::variant<TTypes...>>&&
1413#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1414 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
1417 using type = etl::variant_alternative_t<Index,
etl::variant<TTypes...>>;
1419 return etl::move(*
static_cast<type*
>(v.data));
1423 template <
size_t Index,
typename... TTypes>
1424 ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<TTypes...>>&
1427#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1428 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
1433 using type = etl::variant_alternative_t<Index,
etl::variant<TTypes...>>;
1435 return *
static_cast<const type*
>(v.data);
1439 template <
size_t Index,
typename... TTypes>
1440 ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<TTypes...>>&&
1443#if ETL_USING_CPP17 & !defined(ETL_VARIANT_FORCE_CPP11)
1444 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
1449 using type = etl::variant_alternative_t<Index,
etl::variant<TTypes...>>;
1451 return etl::move(*
static_cast<const type*
>(v.data));
1455 template <
typename T,
typename... TTypes>
1458 constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1460 return get<Index>(v);
1464 template <
typename T,
typename... TTypes>
1467 constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1469 return get<Index>(etl::move(v));
1473 template <
typename T,
typename... TTypes>
1476 constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1478 return get<Index>(v);
1482 template <
typename T,
typename... TTypes>
1485 constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1487 return get<Index>(etl::move(v));
1493 template<
size_t Index,
typename... TTypes >
1494 ETL_CONSTEXPR14 etl::add_pointer_t<etl::variant_alternative_t<Index,
etl::variant<TTypes...>>>
1497 if ((pv !=
nullptr) && (pv->index() == Index))
1499 return &etl::get<Index>(*pv);
1508 template<
size_t Index,
typename... TTypes >
1509 ETL_CONSTEXPR14 etl::add_pointer_t<
const etl::variant_alternative_t<Index,
etl::variant<TTypes...>>>
1512 if ((pv !=
nullptr) && (pv->index() == Index))
1514 return &etl::get<Index>(*pv);
1523 template<
class T,
typename... TTypes >
1526 constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1528 if ((pv !=
nullptr) && (pv->index() == Index))
1530 return &etl::get<Index>(*pv);
1539 template<
typename T,
typename... TTypes >
1542 constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1544 if ((pv !=
nullptr) && (pv->index() == Index))
1546 return &etl::get<Index>(*pv);
1557 template <
typename... TTypes>
1566 template <
typename T>
1567 struct variant_size;
1569 template <
typename... TTypes>
1570 struct variant_size<
etl::variant<TTypes...>>
1575 template <
typename T>
1576 struct variant_size<const T>
1582 template <
typename... TTypes>
1583 inline constexpr size_t variant_size_v = variant_size<TTypes...>::value;
1589 namespace private_variant
1591 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t tIndex,
typename TNext,
typename... TVariants>
1592 static ETL_CONSTEXPR14 TRet do_visit_single(TCallable&& f, TVariant&& v, TNext&&, TVariants&&... vs);
1599 struct visit_auto_return
1607 template <
typename TCallable,
typename... Ts>
1608 struct single_visit_result_type
1610 using type =
decltype(declval<TCallable>()(declval<Ts>()...));
1613 template <
typename TCallable,
typename... Ts>
1614 using single_visit_result_type_t =
typename single_visit_result_type<TCallable, Ts...>::type;
1620 template <
typename TVar,
typename T>
1621 using rlref_copy = conditional_t<is_reference<TVar>::value, T&, T&&>;
1631 template <
template <
typename...>
class,
typename...>
1632 struct visit_result_helper;
1634 template <
template <
typename...>
class TToInject,
size_t... tAltIndices,
typename TCur>
1635 struct visit_result_helper<TToInject, index_sequence<tAltIndices...>, TCur>
1637 template <
size_t tIndex>
1638 using var_type = rlref_copy<TCur,
1639 variant_alternative_t<tIndex, remove_reference_t<TCur> > >;
1641 using type = common_type_t<TToInject<var_type<tAltIndices> >...>;
1644 template <
template <
typename...>
class TToInject,
size_t... tAltIndices,
typename TCur,
typename TNext,
typename... TVs>
1645 struct visit_result_helper<TToInject, index_sequence<tAltIndices...>, TCur, TNext, TVs...>
1647 template <
size_t tIndex>
1648 using var_type = rlref_copy<TCur, variant_alternative_t<tIndex, remove_reference_t<TCur> > >;
1650 template <
size_t tIndex>
1651 struct next_inject_wrap
1653 template <
typename... TNextInj>
1654 using next_inject = TToInject<var_type<tIndex>, TNextInj...>;
1655 using recursive_result =
typename visit_result_helper<next_inject, make_index_sequence<variant_size<remove_reference_t<TNext> >::value>, TNext, TVs...>::type;
1658 using type = common_type_t<typename next_inject_wrap<tAltIndices>::recursive_result...>;
1666 template <
typename TRet,
typename...>
1672 template <
typename TCallable,
typename T1,
typename... Ts>
1673 struct visit_result<visit_auto_return, TCallable, T1, Ts...>
1676 template <
typename... Ts2>
1677 using single_res = single_visit_result_type_t<TCallable, Ts2...>;
1678 using type =
typename visit_result_helper<single_res, make_index_sequence<variant_size<remove_reference_t<T1> >::value>, T1, Ts...>::type;
1681 template <
typename... Ts>
1682 using visit_result_t =
typename visit_result<Ts...>::type;
1688 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t tIndex>
1689 constexpr TRet do_visit_single(TCallable&& f, TVariant&& v)
1691 return static_cast<TCallable&&
>(f)(etl::get<tIndex>(
static_cast<TVariant&&
>(v)));
1699 template <
typename TRet,
typename TCallable,
typename TCurVariant,
typename... TVarRest>
1700 struct do_visit_helper
1702 using function_pointer = add_pointer_t<TRet(TCallable&&, TCurVariant&&, TVarRest&&...)>;
1704 template <
size_t tIndex>
1705 static constexpr function_pointer fptr() noexcept
1707 return &do_visit_single<TRet, TCallable, TCurVariant, tIndex, TVarRest...>;
1714 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t... tIndices,
typename... TVarRest>
1715 static ETL_CONSTEXPR14 TRet do_visit(TCallable&& f, TVariant&& v, index_sequence<tIndices...>, TVarRest&&... variants)
1717 ETL_ASSERT(!v.valueless_by_exception(), ETL_ERROR(bad_variant_access));
1719 using helper_t = do_visit_helper<TRet, TCallable, TVariant, TVarRest...>;
1720 using func_ptr =
typename helper_t::function_pointer;
1722 constexpr func_ptr jmp_table[]
1724 helper_t::template fptr<tIndices>()...
1727 return jmp_table[v.
index()](
static_cast<TCallable&&
>(f),
static_cast<TVariant&&
>(v),
static_cast<TVarRest&&
>(variants)...);
1730 template <
typename TRet,
typename TCallable,
typename TVariant,
typename... TVs>
1731 static ETL_CONSTEXPR14 TRet visit(TCallable&& f, TVariant&& v, TVs&&... vs)
1733 constexpr size_t variants = etl::variant_size<typename remove_reference<TVariant>::type>::value;
1734 return private_variant::do_visit<TRet>(
static_cast<TCallable&&
>(f),
1735 static_cast<TVariant&&
>(v),
1736 make_index_sequence<variants>{},
1737 static_cast<TVs&&
>(vs)...);
1744 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t tIndex>
1745 class constexpr_visit_closure
1747 add_pointer_t<TCallable> callable_;
1748 add_pointer_t<TVariant> variant_;
1751 constexpr constexpr_visit_closure(TCallable&& c, TVariant&& v)
1752 : callable_(&c), variant_(&v)
1756 template <
typename... Ts>
1757 ETL_CONSTEXPR14 TRet operator()(Ts&&... args)
const
1759 return static_cast<TCallable&&
>(*callable_)(get<tIndex>(
static_cast<TVariant&&
>(*variant_)),
static_cast<Ts&&
>(args)...);
1763 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t tIndex,
typename TNext,
typename... TVariants>
1764 static ETL_CONSTEXPR14 TRet do_visit_single(TCallable&& f, TVariant&& v, TNext&& next, TVariants&&... vs)
1766 return private_variant::visit<TRet>(constexpr_visit_closure<TRet, TCallable, TVariant, tIndex>(
static_cast<TCallable&&
>(f),
static_cast<TVariant&&
>(v)),
1767 static_cast<TNext&&
>(next),
static_cast<TVariants&&
>(vs)...);
1776 template <
typename TRet = private_variant::visit_auto_return,
typename... TVariants,
typename TCallable,
typename TDeducedReturn = private_variant::visit_result_t<TRet, TCallable, TVariants...> >
1777 static ETL_CONSTEXPR14 TDeducedReturn visit(TCallable&& f, TVariants&&... vs)
1779 return private_variant::visit<TDeducedReturn>(
static_cast<TCallable&&
>(f),
static_cast<TVariants&&
>(vs)...);
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition: exception.h:69
Definition: integral_limits.h:468
Definition: largest.h:227
conditional
Definition: type_traits_generator.h:1160
integral_constant
Definition: type_traits_generator.h:832
is_same
Definition: type_traits_generator.h:1041
~variant()
Destructor.
Definition: variant_legacy.h:230
T & get()
Definition: variant_legacy.h:726
uint_least8_t type_id_t
The type used for ids.
Definition: variant_legacy.h:153
variant & operator=(const T &value)
Definition: variant_legacy.h:589
T & emplace(const TP1 &value1)
Emplace with one constructor parameter.
Definition: variant_legacy.h:527
size_t index() const
Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID.
Definition: variant_legacy.h:707
Definition: variant_legacy.h:147
Definition: variant_legacy.h:100
Definition: variant_legacy.h:79
bitset_ext
Definition: absolute.h:38
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:684
T & get(array< T, MAXN > &a)
Definition: array.h:710
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:696
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:621
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633
ETL_DEPRECATED_REASON("Misspelt class name") typedef scheduler_policy_sequential_single scheduler_policy_sequencial_single
Typedef for backwards compatibility with miss-spelt struct name.
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:657
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:672
Definition: utility.h:591
Definition: utility.h:580
Definition: type_traits_generator.h:2033
Definition: type_traits.h:1376
Definition: variant_legacy.h:923