34#include "../nth_type.h"
38#include "../static_assert.h"
41#include "../type_list.h"
51#if defined(ETL_COMPILER_KEIL)
52 #pragma diag_suppress 940
53 #pragma diag_suppress 111
56#if ETL_CPP11_NOT_SUPPORTED
57 #if !defined(ETL_IN_UNIT_TEST)
58 #error NOT SUPPORTED FOR C++03 OR BELOW
69 namespace private_variant
74 static constexpr bool Copyable =
true;
75 static constexpr bool Non_Copyable =
false;
76 static constexpr bool Moveable =
true;
77 static constexpr bool Non_Moveable =
false;
82 static constexpr int Copy = 0;
83 static constexpr int Move = 1;
84 static constexpr int Destroy = 2;
89 template <
typename T,
bool IsCopyable,
bool IsMoveable>
90 struct operation_type;
95 struct operation_type<void, Non_Copyable, Non_Moveable>
97 static void do_operation(
int,
char*,
const char*)
100#if defined(ETL_IN_UNIT_TEST)
108 template <
typename T>
109 struct operation_type<T, Non_Copyable, Non_Moveable>
111 static void do_operation(
int operation,
char* pstorage,
const char* )
117 reinterpret_cast<const T*
>(pstorage)->~T();
124#if defined(ETL_IN_UNIT_TEST)
135 template <
typename T>
136 struct operation_type<T, Non_Copyable, Moveable>
138 static void do_operation(
int operation,
char* pstorage,
const char* pvalue)
144 ::new (pstorage) T(etl::move(*
reinterpret_cast<T*
>(
const_cast<char*
>(pvalue))));
150 reinterpret_cast<const T*
>(pstorage)->~T();
157#if defined(ETL_IN_UNIT_TEST)
168 template <
typename T>
169 struct operation_type<T, Copyable, Non_Moveable>
171 static void do_operation(
int operation,
char* pstorage,
const char* pvalue)
177 ::new (pstorage) T(*
reinterpret_cast<const T*
>(pvalue));
183 reinterpret_cast<const T*
>(pstorage)->~T();
190#if defined(ETL_IN_UNIT_TEST)
201 template <
typename T>
202 struct operation_type<T, Copyable, Moveable>
204 static void do_operation(
int operation,
char* pstorage,
const char* pvalue)
210 ::new (pstorage) T(*
reinterpret_cast<const T*
>(pvalue));
216 ::new (pstorage) T(etl::move(*
reinterpret_cast<T*
>(
const_cast<char*
>(pvalue))));
222 reinterpret_cast<const T*
>(pstorage)->~T();
229#if defined(ETL_IN_UNIT_TEST)
240 constexpr size_t variant_npos = etl::integral_limits<size_t>::max;
244 template <
typename... TTypes>
250 template <
size_t Index,
typename T>
253 template <
size_t Index,
typename... TTypes>
256 using type = etl::nth_type_t<Index, TTypes...>;
259 template <
size_t Index,
typename T>
262 using type =
typename variant_alternative<Index, T>::type;
265 template <
size_t Index,
typename T>
266 using variant_alternative_t =
typename variant_alternative<Index, T>::type;
270 template <
typename T,
typename... TTypes>
271 ETL_CONSTEXPR14
bool holds_alternative(
const etl::variant<TTypes...>& v) ETL_NOEXCEPT;
275 template <
size_t Index,
typename... VTypes>
276 ETL_CONSTEXPR14 etl::variant_alternative_t<Index, etl::variant<VTypes...>>&
277 get(etl::variant<VTypes...>& v);
279 template <
size_t Index,
typename... VTypes>
280 ETL_CONSTEXPR14 etl::variant_alternative_t<Index, etl::variant<VTypes...>>&&
281 get(etl::variant<VTypes...>&& v);
283 template <
size_t Index,
typename... VTypes>
284 ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<VTypes...>>&
285 get(
const etl::variant<VTypes...>& v);
287 template <
size_t Index,
typename... VTypes>
288 ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<VTypes...>>&&
289 get(
const etl::variant<VTypes...>&& v);
291 template <
typename T,
typename... VTypes>
292 ETL_CONSTEXPR14 T&
get(etl::variant<VTypes...>& v);
294 template <
typename T,
typename... VTypes>
295 ETL_CONSTEXPR14 T&&
get(etl::variant<VTypes...>&& v);
297 template <
typename T,
typename... VTypes>
298 ETL_CONSTEXPR14
const T&
get(
const etl::variant<VTypes...>& v);
300 template <
typename T,
typename... VTypes>
301 ETL_CONSTEXPR14
const T&&
get(
const etl::variant<VTypes...>&& v);
303#if ETL_NOT_USING_CPP17
304 #include "variant_select_do_visitor.h"
305 #include "variant_select_do_operator.h"
314#if ETL_USING_CPP20 && ETL_USING_STL && !(defined(ETL_DEVELOPMENT_OS_APPLE) && defined(ETL_COMPILER_CLANG))
317 return std::strong_ordering::equal;
321#if ETL_NOT_USING_STL && !defined(ETL_USE_TYPE_TRAITS_BUILTINS)
340 variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
341 :
exception(reason_, file_name_, line_number_)
353 variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
354 : variant_exception(ETL_ERROR_TEXT(
"variant:unsupported type", ETL_VARIANT_FILE_ID
"A"), file_name_, line_number_)
366 bad_variant_access(string_type file_name_, numeric_type line_number_)
367 : variant_exception(ETL_ERROR_TEXT(
"variant:bad variant access", ETL_VARIANT_FILE_ID
"B"), file_name_, line_number_)
376 template <
typename... TTypes>
384 template <
size_t Index,
typename... VTypes>
385 friend ETL_CONSTEXPR14 etl::variant_alternative_t<Index, etl::variant<VTypes...>>&
386 get(etl::variant<VTypes...>& v);
388 template <
size_t Index,
typename... VTypes>
389 friend ETL_CONSTEXPR14 etl::variant_alternative_t<Index, etl::variant<VTypes...>>&&
390 get(etl::variant<VTypes...>&& v);
392 template <
size_t Index,
typename... VTypes>
393 friend ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<VTypes...>>&
394 get(
const etl::variant<VTypes...>& v);
396 template <
size_t Index,
typename... VTypes>
397 friend ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<VTypes...>>&&
398 get(
const etl::variant<VTypes...>&& v);
400 template <
typename T,
typename... VTypes>
401 friend ETL_CONSTEXPR14 T&
get(etl::variant<VTypes...>& v);
403 template <
typename T,
typename... VTypes>
404 friend ETL_CONSTEXPR14 T&&
get(etl::variant<VTypes...>&& v);
406 template <
typename T,
typename... VTypes>
407 friend ETL_CONSTEXPR14
const T&
get(
const etl::variant<VTypes...>& v);
409 template <
typename T,
typename... VTypes>
410 friend ETL_CONSTEXPR14
const T&&
get(
const etl::variant<VTypes...>&& v);
415 template <
typename... UTypes>
416 friend class variant;
421 using largest_t =
typename largest_type<TTypes...>::type;
426 static const size_t Size =
sizeof(largest_t);
431 static const size_t Alignment = etl::largest_alignment<TTypes...>::value;
436 template <
typename T,
bool IsCopyable,
bool IsMoveable>
437 using operation_type = private_variant::operation_type<T, IsCopyable, IsMoveable>;
442 static constexpr int Copy = private_variant::Copy;
443 static constexpr int Move = private_variant::Move;
444 static constexpr int Destroy = private_variant::Destroy;
449 template <
typename T>
450 using index_of_type = etl::type_list_index_of_type<etl::type_list<TTypes...>, etl::remove_cvref_t<T>>;
455 template <
size_t Index>
456 using type_from_index =
typename etl::type_list_type_at_index<etl::type_list<TTypes...>, Index>::type;
465 ETL_CONSTEXPR14 variant()
467 using type = type_from_index<0U>;
469 default_construct_in_place<type>(data);
470 operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
479 template <
typename T, etl::enable_if_t<!etl::is_same<etl::remove_cvref_t<T>, variant>::value,
int> = 0>
480 ETL_CONSTEXPR14 variant(T&& value)
481 : 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)
482 , type_id(index_of_type<T>::value)
484 static_assert(etl::is_one_of<etl::remove_cvref_t<T>, TTypes...>::value,
"Unsupported type");
486 construct_in_place<etl::remove_cvref_t<T>>(data, etl::forward<T>(value));
494 template <
typename T,
typename... TArgs>
495 ETL_CONSTEXPR14
explicit variant(etl::in_place_type_t<T>, TArgs&&... args)
496 : 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)
497 , type_id(index_of_type<T>::value)
499 static_assert(etl::is_one_of<etl::remove_cvref_t<T>, TTypes...>::value,
"Unsupported type");
501 construct_in_place_args<etl::remove_cvref_t<T>>(data, etl::forward<TArgs>(args)...);
509 template <
size_t Index,
typename... TArgs>
510 ETL_CONSTEXPR14
explicit variant(etl::in_place_index_t<Index>, TArgs&&... args)
513 using type = type_from_index<Index>;
514 static_assert(etl::is_one_of<type, TTypes...> ::value,
"Unsupported type");
516 construct_in_place_args<type>(data, etl::forward<TArgs>(args)...);
518 operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
522#if ETL_HAS_INITIALIZER_LIST
527 template <
typename T,
typename U,
typename... TArgs >
528 ETL_CONSTEXPR14
explicit variant(etl::in_place_type_t<T>, std::initializer_list<U> init, TArgs&&... args)
529 : 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)
530 , type_id(index_of_type<T>::value)
532 static_assert(etl::is_one_of<etl::remove_cvref_t<T>, TTypes...> ::value,
"Unsupported type");
534 construct_in_place_args<etl::remove_cvref_t<T>>(data, init, etl::forward<TArgs>(args)...);
542 template <
size_t Index,
typename U,
typename... TArgs >
543 ETL_CONSTEXPR14
explicit variant(etl::in_place_index_t<Index>, std::initializer_list<U> init, TArgs&&... args)
546 using type = type_from_index<Index>;
547 static_assert(etl::is_one_of<type, TTypes...> ::value,
"Unsupported type");
549 construct_in_place_args<type>(data, init, etl::forward<TArgs>(args)...);
551 operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
561 ETL_CONSTEXPR14 variant(
const variant& other)
562 : operation(other.operation)
563 , type_id(other.type_id)
567 if (other.index() == variant_npos)
569 type_id = variant_npos;
573 operation(private_variant::Copy, data, other.data);
584 ETL_CONSTEXPR14 variant(variant&& other)
585 : operation(other.operation)
586 , type_id(other.type_id)
590 if (other.index() == variant_npos)
592 type_id = variant_npos;
596 operation(private_variant::Move, data, other.data);
601 type_id = variant_npos;
611 if (
index() != variant_npos)
613 operation(private_variant::Destroy, data,
nullptr);
616 operation = operation_type<void, false, false>::do_operation;
617 type_id = variant_npos;
623 template <
typename T,
typename... TArgs>
626 static_assert(etl::is_one_of<T, TTypes...>::value,
"Unsupported type");
628 using type = etl::remove_cvref_t<T>;
630 operation(private_variant::Destroy, data,
nullptr);
632 construct_in_place_args<type>(data, etl::forward<TArgs>(args)...);
634 operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
636 type_id = index_of_type<T>::value;
638 return *
static_cast<T*
>(data);
641#if ETL_HAS_INITIALIZER_LIST
645 template <
typename T,
typename U,
typename... TArgs>
646 T&
emplace(std::initializer_list<U> il, TArgs&&... args)
648 static_assert(etl::is_one_of<T, TTypes...>::value,
"Unsupported type");
650 using type = etl::remove_cvref_t<T>;
652 operation(private_variant::Destroy, data,
nullptr);
654 construct_in_place_args<type>(data, il, etl::forward<TArgs>(args)...);
656 operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
658 type_id = index_of_type<T>::value;
660 return *
static_cast<T*
>(data);
667 template <
size_t Index,
typename... TArgs>
668 typename etl::variant_alternative_t<Index, variant<TTypes...>>&
emplace(TArgs&&... args)
670 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
672 using type = type_from_index<Index>;
674 operation(private_variant::Destroy, data,
nullptr);
676 construct_in_place_args<type>(data, etl::forward<TArgs>(args)...);
678 operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
682 return *
static_cast<type*
>(data);
685#if ETL_HAS_INITIALIZER_LIST
689 template <
size_t Index,
typename U,
typename... TArgs>
690 typename etl::variant_alternative_t<Index, variant<TTypes...>>&
emplace(std::initializer_list<U> il, TArgs&&... args)
692 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
694 using type = type_from_index<Index>;
696 operation(private_variant::Destroy, data,
nullptr);
698 construct_in_place_args<type>(data, il, etl::forward<TArgs>(args)...);
700 operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
704 return *
static_cast<type*
>(data);
712 template <
typename T, etl::enable_if_t<!etl::is_same<etl::remove_cvref_t<T>, variant>::value,
int> = 0>
715 using type = etl::remove_cvref_t<T>;
717 static_assert(etl::is_one_of<type, TTypes...>::value,
"Unsupported type");
719 operation(private_variant::Destroy, data,
nullptr);
721 construct_in_place<type>(data, etl::forward<T>(value));
723 operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
724 type_id = index_of_type<type>::value;
737 if (other.index() == variant_npos)
739 type_id = variant_npos;
743 operation(Destroy, data,
nullptr);
745 operation = other.operation;
746 operation(Copy, data, other.data);
748 type_id = other.type_id;
763 if (other.index() == variant_npos)
765 type_id = variant_npos;
769 operation(Destroy, data,
nullptr);
771 operation = other.operation;
772 operation(Move, data, other.data);
774 type_id = other.type_id;
785 constexpr bool valueless_by_exception() const ETL_NOEXCEPT
787 return type_id == variant_npos;
793 constexpr size_t index() const ETL_NOEXCEPT
803 template <
typename T>
806 return etl::is_one_of<etl::remove_cvref_t<T>, TTypes...>::value;
814 template <typename T, etl::enable_if_t<is_supported_type<T>(),
int> = 0>
815 constexpr bool is_type() const ETL_NOEXCEPT
817 return (type_id == index_of_type<T>::value);
821 template <typename T, etl::enable_if_t<!is_supported_type<T>(),
int> = 0>
822 constexpr bool is_type() const ETL_NOEXCEPT
835 return type_id == other.type_id;
841 void swap(variant& rhs) ETL_NOEXCEPT
843 variant temp(etl::move(*
this));
844 *
this = etl::move(rhs);
845 rhs = etl::move(temp);
851 template <
typename TVisitor>
852 etl::enable_if_t<etl::is_visitor<TVisitor>::value,
void>
855#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
856 do_visitor(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
858 do_visitor<
sizeof...(TTypes)>(v);
865 template <
typename TVisitor>
866 etl::enable_if_t<etl::is_visitor<TVisitor>::value,
void>
867 accept(TVisitor& v)
const
869#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
870 do_visitor(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
872 do_visitor<
sizeof...(TTypes)>(v);
879 template <
typename TVisitor>
880 etl::enable_if_t<!etl::is_visitor<TVisitor>::value,
void>
883#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
884 do_operator(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
886 do_operator<
sizeof...(TTypes)>(v);
893 template <
typename TVisitor>
894 etl::enable_if_t<!etl::is_visitor<TVisitor>::value,
void>
895 accept(TVisitor& v)
const
897#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
898 do_operator(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
900 do_operator<
sizeof...(TTypes)>(v);
908 template <
typename TVisitor>
909#if !defined(ETL_IN_UNIT_TEST)
912 void accept_visitor(TVisitor& v)
914#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
915 do_visitor(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
917 do_visitor<
sizeof...(TTypes)>(v);
925 template <
typename TVisitor>
926#if !defined(ETL_IN_UNIT_TEST)
929 void accept_visitor(TVisitor& v)
const
931#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
932 do_visitor(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
934 do_visitor<
sizeof...(TTypes)>(v);
942 template <
typename TVisitor>
943#if !defined(ETL_IN_UNIT_TEST)
946 void accept_functor(TVisitor& v)
948#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
949 do_operator(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
951 do_operator<
sizeof...(TTypes)>(v);
959 template <
typename TVisitor>
960#if !defined(ETL_IN_UNIT_TEST)
963 void accept_functor(TVisitor& v)
const
965#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
966 do_operator(v, etl::make_index_sequence<
sizeof...(TTypes)>{});
968 do_operator<
sizeof...(TTypes)>(v);
975 using operation_function = void(*)(int,
char*,
const char*);
980 template <
typename T>
981 static void construct_in_place(
char* pstorage,
const T& value)
983 using type = etl::remove_cvref_t<T>;
985 ::new (pstorage) type(value);
991 template <
typename T>
992 static void construct_in_place(
char* pstorage, T&& value)
994 using type = etl::remove_cvref_t<T>;
996 ::new (pstorage) type(etl::move(value));
1002 template <
typename T,
typename... TArgs>
1003 static void construct_in_place_args(
char* pstorage, TArgs&&... args)
1005 using type = etl::remove_cvref_t<T>;
1007 ::new (pstorage) type(etl::forward<TArgs>(args)...);
1013 template <
typename T>
1014 static void default_construct_in_place(
char* pstorage)
1016 using type = etl::remove_cvref_t<T>;
1018 ::new (pstorage) type();
1021#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1025 template <
typename TVisitor,
size_t... I>
1026 void do_visitor(TVisitor& visitor, etl::index_sequence<I...>)
1028 (attempt_visitor<I>(visitor) || ...);
1034 template <
typename TVisitor,
size_t... I>
1035 void do_visitor(TVisitor& visitor, etl::index_sequence<I...>)
const
1037 (attempt_visitor<I>(visitor) || ...);
1043 template <
size_t NTypes,
typename TVisitor>
1044 void do_visitor(TVisitor& visitor)
1046 etl::private_variant::select_do_visitor<NTypes>::do_visitor(*
this, visitor);
1052 template <
size_t NTypes,
typename TVisitor>
1053 void do_visitor(TVisitor& visitor)
const
1055 etl::private_variant::select_do_visitor<NTypes>::do_visitor(*
this, visitor);
1062 template <
size_t Index,
typename TVisitor>
1063 bool attempt_visitor(TVisitor& visitor)
1065 if (Index ==
index())
1083 template <
size_t Index,
typename TVisitor>
1084 bool attempt_visitor(TVisitor& visitor)
const
1086 if (Index ==
index())
1101#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1105 template <
typename TVisitor,
size_t... I>
1106 void do_operator(TVisitor& visitor, etl::index_sequence<I...>)
1108 (attempt_operator<I>(visitor) || ...);
1114 template <
typename TVisitor,
size_t... I>
1115 void do_operator(TVisitor& visitor, etl::index_sequence<I...>)
const
1117 (attempt_operator<I>(visitor) || ...);
1123 template <
size_t NTypes,
typename TVisitor>
1124 void do_operator(TVisitor& visitor)
1126#if defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
1127 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 8U,
"ETL_VARIANT_CPP11_MAX_8_TYPES - Only a maximum of 8 types are allowed in this variant");
1130#if defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
1131 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 16U,
"ETL_VARIANT_CPP11_MAX_16_TYPES - Only a maximum of 16 types are allowed in this variant");
1134#if defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
1135 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 24U,
"ETL_VARIANT_CPP11_MAX_24_TYPES - Only a maximum of 24 types are allowed in this variant");
1138 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 32U,
"A maximum of 32 types are allowed in this variant");
1140 etl::private_variant::select_do_operator<NTypes>::do_operator(*
this, visitor);
1146 template <
size_t NTypes,
typename TVisitor>
1147 void do_operator(TVisitor& visitor)
const
1149#if defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
1150 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 8U,
"ETL_VARIANT_CPP11_MAX_8_TYPES - Only a maximum of 8 types are allowed in this variant");
1153#if defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
1154 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 16U,
"ETL_VARIANT_CPP11_MAX_16_TYPES - Only a maximum of 16 types are allowed in this variant");
1157#if defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
1158 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 24U,
"ETL_VARIANT_CPP11_MAX_24_TYPES - Only a maximum of 24 types are allowed in this variant");
1161 ETL_STATIC_ASSERT(
sizeof...(TTypes) <= 32U,
"A maximum of 32 types are allowed in this variant");
1163 etl::private_variant::select_do_operator<NTypes>::do_operator(*
this, visitor);
1170 template <
size_t Index,
typename TVisitor>
1171 bool attempt_operator(TVisitor& visitor)
1173 if (Index ==
index())
1188 template <
size_t Index,
typename TVisitor>
1189 bool attempt_operator(TVisitor& visitor)
const
1191 if (Index ==
index())
1207 etl::uninitialized_buffer<Size, 1U, Alignment> data;
1212 operation_function operation;
1223 template <
typename T,
typename... TTypes>
1224 ETL_CONSTEXPR14
bool holds_alternative(
const etl::variant<TTypes...>& v) ETL_NOEXCEPT
1226 constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
1228 return (Index == variant_npos) ? false : (v.index() == Index);
1234 template <
size_t Index,
typename... TTypes>
1235 ETL_CONSTEXPR14
bool holds_alternative(
const etl::variant<TTypes...>& v) ETL_NOEXCEPT
1237 return (Index == v.index());
1243 template <
typename... TTypes>
1244 ETL_CONSTEXPR14
bool holds_alternative(
size_t index,
const etl::variant<TTypes...>& v) ETL_NOEXCEPT
1246 return (index == v.index());
1252 template <
size_t Index,
typename... TTypes>
1253 ETL_CONSTEXPR14 etl::variant_alternative_t<Index, etl::variant<TTypes...>>&
1254 get(etl::variant<TTypes...>& v)
1256#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1257 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
1260 ETL_ASSERT(Index == v.
index(), ETL_ERROR(etl::variant_incorrect_type_exception));
1262 using type = etl::variant_alternative_t<Index, etl::variant<TTypes...>>;
1264 return *
static_cast<type*
>(v.data);
1268 template <
size_t Index,
typename... TTypes>
1269 ETL_CONSTEXPR14 etl::variant_alternative_t<Index, etl::variant<TTypes...>>&&
1270 get(etl::variant<TTypes...>&& v)
1272#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1273 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
1276 using type = etl::variant_alternative_t<Index, etl::variant<TTypes...>>;
1278 return etl::move(*
static_cast<type*
>(v.data));
1282 template <
size_t Index,
typename... TTypes>
1283 ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<TTypes...>>&
1284 get(
const etl::variant<TTypes...>& v)
1286#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
1287 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
1290 ETL_ASSERT(Index == v.
index(), ETL_ERROR(etl::variant_incorrect_type_exception));
1292 using type = etl::variant_alternative_t<Index, etl::variant<TTypes...>>;
1294 return *
static_cast<const type*
>(v.data);
1298 template <
size_t Index,
typename... TTypes>
1299 ETL_CONSTEXPR14
const etl::variant_alternative_t<Index,
const etl::variant<TTypes...>>&&
1300 get(
const etl::variant<TTypes...>&& v)
1302#if ETL_USING_CPP17 & !defined(ETL_VARIANT_FORCE_CPP11)
1303 static_assert(Index <
sizeof...(TTypes),
"Index out of range");
1306 ETL_ASSERT(Index == v.
index(), ETL_ERROR(etl::variant_incorrect_type_exception));
1308 using type = etl::variant_alternative_t<Index, etl::variant<TTypes...>>;
1310 return etl::move(*
static_cast<const type*
>(v.data));
1314 template <
typename T,
typename... TTypes>
1315 ETL_CONSTEXPR14 T&
get(etl::variant<TTypes...>& v)
1317 constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
1323 template <
typename T,
typename... TTypes>
1324 ETL_CONSTEXPR14 T&&
get(etl::variant<TTypes...>&& v)
1326 constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
1332 template <
typename T,
typename... TTypes>
1333 ETL_CONSTEXPR14
const T&
get(
const etl::variant<TTypes...>& v)
1335 constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
1341 template <
typename T,
typename... TTypes>
1342 ETL_CONSTEXPR14
const T&&
get(
const etl::variant<TTypes...>&& v)
1344 constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
1352 template<
size_t Index,
typename... TTypes >
1353 ETL_CONSTEXPR14 etl::add_pointer_t<etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
1354 get_if(etl::variant<TTypes...>* pv) ETL_NOEXCEPT
1356 if ((pv !=
nullptr) && (pv->index() == Index))
1367 template<
size_t Index,
typename... TTypes >
1368 ETL_CONSTEXPR14 etl::add_pointer_t<
const etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
1369 get_if(
const etl::variant<TTypes...>* pv) ETL_NOEXCEPT
1371 if ((pv !=
nullptr) && (pv->index() == Index))
1382 template<
class T,
typename... TTypes >
1383 ETL_CONSTEXPR14 etl::add_pointer_t<T> get_if(etl::variant<TTypes...>* pv) ETL_NOEXCEPT
1385 constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
1387 if ((pv !=
nullptr) && (pv->index() == Index))
1398 template<
typename T,
typename... TTypes >
1399 ETL_CONSTEXPR14 etl::add_pointer_t<const T> get_if(
const etl::variant<TTypes...>* pv) ETL_NOEXCEPT
1401 constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
1403 if ((pv !=
nullptr) && (pv->index() == Index))
1416 template <
typename... TTypes>
1417 void swap(etl::variant<TTypes...>& lhs, etl::variant<TTypes...>& rhs)
1425 template <
typename T>
1426 struct variant_size;
1428 template <
typename... TTypes>
1429 struct variant_size<etl::
variant<TTypes...>>
1430 : etl::integral_constant<size_t, sizeof...(TTypes)>
1434 template <
typename T>
1435 struct variant_size<const T>
1436 : etl::integral_constant<size_t, variant_size<T>::value>
1441 template <
typename... TTypes>
1442 inline constexpr size_t variant_size_v = variant_size<TTypes...>::value;
1448 namespace private_variant
1450 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t tIndex,
typename TNext,
typename... TVariants>
1451 static ETL_CONSTEXPR14 TRet do_visit_single(TCallable&& f, TVariant&& v, TNext&&, TVariants&&... vs);
1458 struct visit_auto_return
1466 template <
typename TCallable,
typename... Ts>
1467 struct single_visit_result_type
1469 using type =
decltype(declval<TCallable>()(declval<Ts>()...));
1472 template <
typename TCallable,
typename... Ts>
1473 using single_visit_result_type_t =
typename single_visit_result_type<TCallable, Ts...>::type;
1479 template <
typename TVar,
typename T>
1480 using rlref_copy = conditional_t<is_reference<TVar>::value, T&, T&&>;
1490 template <
template <
typename...>
class,
typename...>
1491 struct visit_result_helper;
1493 template <
template <
typename...>
class TToInject,
size_t... tAltIndices,
typename TCur>
1494 struct visit_result_helper<TToInject, index_sequence<tAltIndices...>, TCur>
1496 template <
size_t tIndex>
1497 using var_type = rlref_copy<TCur,
1498 variant_alternative_t<tIndex, remove_reference_t<TCur> > >;
1500 using type = common_type_t<TToInject<var_type<tAltIndices> >...>;
1503 template <
template <
typename...>
class TToInject,
size_t... tAltIndices,
typename TCur,
typename TNext,
typename... TVs>
1504 struct visit_result_helper<TToInject, index_sequence<tAltIndices...>, TCur, TNext, TVs...>
1506 template <
size_t tIndex>
1507 using var_type = rlref_copy<TCur, variant_alternative_t<tIndex, remove_reference_t<TCur> > >;
1509 template <
size_t tIndex>
1510 struct next_inject_wrap
1512 template <
typename... TNextInj>
1513 using next_inject = TToInject<var_type<tIndex>, TNextInj...>;
1514 using recursive_result =
typename visit_result_helper<next_inject, make_index_sequence<variant_size<remove_reference_t<TNext> >::value>, TNext, TVs...>::type;
1517 using type = common_type_t<typename next_inject_wrap<tAltIndices>::recursive_result...>;
1525 template <
typename TRet,
typename...>
1531 template <
typename TCallable,
typename T1,
typename... Ts>
1532 struct visit_result<visit_auto_return, TCallable, T1, Ts...>
1535 template <
typename... Ts2>
1536 using single_res = single_visit_result_type_t<TCallable, Ts2...>;
1537 using type =
typename visit_result_helper<single_res, make_index_sequence<variant_size<remove_reference_t<T1> >::value>, T1, Ts...>::type;
1540 template <
typename... Ts>
1541 using visit_result_t =
typename visit_result<Ts...>::type;
1547 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t tIndex>
1548 constexpr TRet do_visit_single(TCallable&& f, TVariant&& v)
1550 return static_cast<TCallable&&
>(f)(
etl::get<tIndex>(
static_cast<TVariant&&
>(v)));
1558 template <
typename TRet,
typename TCallable,
typename TCurVariant,
typename... TVarRest>
1559 struct do_visit_helper
1561 using function_pointer = add_pointer_t<TRet(TCallable&&, TCurVariant&&, TVarRest&&...)>;
1563 template <
size_t tIndex>
1564 static constexpr function_pointer fptr() ETL_NOEXCEPT
1566 return &do_visit_single<TRet, TCallable, TCurVariant, tIndex, TVarRest...>;
1573 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t... tIndices,
typename... TVarRest>
1574 static ETL_CONSTEXPR14 TRet do_visit(TCallable&& f, TVariant&& v, index_sequence<tIndices...>, TVarRest&&... variants)
1576 ETL_ASSERT(!v.valueless_by_exception(), ETL_ERROR(bad_variant_access));
1578 using helper_t = do_visit_helper<TRet, TCallable, TVariant, TVarRest...>;
1579 using func_ptr =
typename helper_t::function_pointer;
1581 constexpr func_ptr jmp_table[]
1583 helper_t::template fptr<tIndices>()...
1586 return jmp_table[v.
index()](
static_cast<TCallable&&
>(f),
static_cast<TVariant&&
>(v),
static_cast<TVarRest&&
>(variants)...);
1589 template <
typename TRet,
typename TCallable,
typename TVariant,
typename... TVs>
1590 static ETL_CONSTEXPR14 TRet visit(TCallable&& f, TVariant&& v, TVs&&... vs)
1592 constexpr size_t variants = etl::variant_size<typename remove_reference<TVariant>::type>::value;
1593 return private_variant::do_visit<TRet>(
static_cast<TCallable&&
>(f),
1594 static_cast<TVariant&&
>(v),
1595 make_index_sequence<variants>{},
1596 static_cast<TVs&&
>(vs)...);
1603 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t tIndex>
1604 class constexpr_visit_closure
1606 add_pointer_t<TCallable> callable_;
1607 add_pointer_t<TVariant> variant_;
1610 constexpr constexpr_visit_closure(TCallable&& c, TVariant&& v)
1611 : callable_(&c), variant_(&v)
1615 template <
typename... Ts>
1616 ETL_CONSTEXPR14 TRet operator()(Ts&&... args)
const
1618 return static_cast<TCallable&&
>(*callable_)(get<tIndex>(
static_cast<TVariant&&
>(*variant_)),
static_cast<Ts&&
>(args)...);
1622 template <
typename TRet,
typename TCallable,
typename TVariant,
size_t tIndex,
typename TNext,
typename... TVariants>
1623 static ETL_CONSTEXPR14 TRet do_visit_single(TCallable&& f, TVariant&& v, TNext&& next, TVariants&&... vs)
1625 return private_variant::visit<TRet>(constexpr_visit_closure<TRet, TCallable, TVariant, tIndex>(
static_cast<TCallable&&
>(f),
static_cast<TVariant&&
>(v)),
1626 static_cast<TNext&&
>(next),
static_cast<TVariants&&
>(vs)...);
1635 template <
typename TRet = private_variant::visit_auto_return,
typename... TVariants,
typename TCallable,
typename TDeducedReturn = private_variant::visit_result_t<TRet, TCallable, TVariants...> >
1636 static ETL_CONSTEXPR14 TDeducedReturn visit(TCallable&& f, TVariants&&... vs)
1638 return private_variant::visit<TDeducedReturn>(
static_cast<TCallable&&
>(f),
static_cast<TVariants&&
>(vs)...);
1641 namespace private_variant
1647 template <
typename TVariant>
1648 struct equality_visitor
1650 equality_visitor(
const TVariant& rhs_)
1655 template <
typename TValue>
1656 bool operator()(
const TValue& lhs_downcasted)
1661 const TVariant& rhs;
1668 template <
typename TVariant>
1669 struct less_than_visitor
1671 less_than_visitor(
const TVariant& rhs_)
1676 template <
typename TValue>
1677 bool operator()(
const TValue& lhs_downcasted)
1679 return lhs_downcasted < etl::get<TValue>(rhs);
1682 const TVariant& rhs;
1690 template <
typename... TTypes>
1691 ETL_CONSTEXPR14
bool operator ==(
const etl::variant<TTypes...>& lhs,
const etl::variant<TTypes...>& rhs)
1694 if (lhs.valueless_by_exception() && rhs.valueless_by_exception())
1700 if (lhs.valueless_by_exception() || rhs.valueless_by_exception())
1712 private_variant::equality_visitor<etl::variant<TTypes...>>
visitor(rhs);
1714 return etl::visit(
visitor, lhs);
1721 template <
typename... TTypes>
1722 ETL_CONSTEXPR14
bool operator !=(
const etl::variant<TTypes...>& lhs,
const etl::variant<TTypes...>& rhs)
1724 return !(lhs == rhs);
1731 template <
typename... TTypes>
1732 ETL_CONSTEXPR14
bool operator <(
const etl::variant<TTypes...>& lhs,
const etl::variant<TTypes...>& rhs)
1735 if (lhs.valueless_by_exception() && rhs.valueless_by_exception())
1741 if (lhs.valueless_by_exception())
1747 if (rhs.valueless_by_exception())
1759 private_variant::less_than_visitor<etl::variant<TTypes...>>
visitor(rhs);
1761 return etl::visit(
visitor, lhs);
1768 template <
typename... TTypes>
1769 ETL_CONSTEXPR14
bool operator >(
const etl::variant<TTypes...>& lhs,
const etl::variant<TTypes...>& rhs)
1778 template <
typename... TTypes>
1779 ETL_CONSTEXPR14
bool operator <=(
const etl::variant<TTypes...>& lhs,
const etl::variant<TTypes...>& rhs)
1781 return !(lhs > rhs);
1788 template <
typename... TTypes>
1789 ETL_CONSTEXPR14
bool operator >=(
const etl::variant<TTypes...>& lhs,
const etl::variant<TTypes...>& rhs)
1791 return !(lhs < rhs);
1794 namespace private_variant
1796#if ETL_USING_CPP20 && ETL_USING_STL && !(defined(ETL_DEVELOPMENT_OS_APPLE) && defined(ETL_COMPILER_CLANG))
1801 template <
typename TVariant>
1802 struct compare_visitor
1804 compare_visitor(
const TVariant& rhs_)
1809 template <
typename TValue>
1810 std::strong_ordering operator()(
const TValue& lhs_downcasted)
1815 const TVariant& rhs;
1825#if ETL_USING_CPP20 && ETL_USING_STL && !(defined(ETL_DEVELOPMENT_OS_APPLE) && defined(ETL_COMPILER_CLANG))
1826 template <
typename... TTypes>
1828 std::common_comparison_category_t<std::compare_three_way_result_t<TTypes>...>
1829 operator <=>(
const etl::variant<TTypes...>& lhs,
const etl::variant<TTypes...>& rhs)
1831 if (lhs.valueless_by_exception() && rhs.valueless_by_exception())
1833 return std::strong_ordering::equal;
1835 else if (lhs.valueless_by_exception())
1837 return std::strong_ordering::less;
1839 else if (rhs.valueless_by_exception())
1841 return std::strong_ordering::greater;
1850 private_variant::compare_visitor<etl::variant<TTypes...>>
visitor(rhs);
1852 return etl::visit(
visitor, lhs);
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition exception.h:69
Definition exception.h:47
static bool is_supported_type()
Definition variant_legacy.h:878
~variant()
Destructor.
Definition variant_legacy.h:229
bool is_same_type(const variant &other) const
Definition variant_legacy.h:661
T & get()
Definition variant_legacy.h:753
variant & operator=(const T &value)
Definition variant_legacy.h:616
bool is_type() const
Definition variant_legacy.h:726
T & emplace()
Emplace with one constructor parameter.
Definition variant_legacy.h:539
size_t index() const
Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID.
Definition variant_legacy.h:734
Definition variant_legacy.h:112
Definition variant_legacy.h:146
Definition variant_legacy.h:86
Definition variant_legacy.h:99
etl::monostate monostate
Definition variant_legacy.h:79
bitset_ext
Definition absolute.h:39
ETL_CONSTEXPR14 void swap(etl::typed_storage_ext< T > &lhs, etl::typed_storage_ext< T > &rhs) ETL_NOEXCEPT
Swap two etl::typed_storage_ext.
Definition alignment.h:838
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1190
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1202
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1151
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1139
T & get(array< T, Size > &a)
Definition array.h:1216
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:1163
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1178
Definition type_traits_generator.h:2208
Definition type_traits_generator.h:2215
A 'no-value' placeholder.
Definition monostate.h:42
Definition variant_legacy.h:949