29 #ifndef __ETL_VARIANT__
30 #define __ETL_VARIANT__
39 #include "static_assert.h"
42 #if defined(COMPILER_KEIL)
43 #pragma diag_suppress 940
54 namespace __private_variant__
60 template <const
size_t ID>
110 template <
typename T1,
123 template <
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6,
typename U7,
typename U8>
129 typedef typename largest_type<T1, T2, T3, T4, T5, T6, T7, T8>::type largest_t;
139 typedef uint8_t type_id_t;
149 template <
typename T>
150 struct pass_by_value :
integral_constant<bool, etl::is_fundamental<T>::value || etl::is_pointer<T>::value>
157 template <
typename T,
bool>
158 struct type_definition;
163 template <
typename T>
164 struct type_definition<T, true>
172 template <
typename T>
173 struct type_definition<T, false>
175 typedef const T& type;
181 template <
typename T>
182 struct parameter_type :
public type_definition<T, pass_by_value<T>::value>
200 template <
typename T>
201 struct Type_Id_Lookup
217 template <
typename T>
219 is_same<T, T1>::value ||
220 is_same<T, T2>::value ||
221 is_same<T, T3>::value ||
222 is_same<T, T4>::value ||
223 is_same<T, T5>::value ||
224 is_same<T, T6>::value ||
225 is_same<T, T7>::value ||
226 is_same<T, T8>::value>
241 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>
248 virtual void read(
typename parameter_type<R1>::type value) = 0;
249 virtual void read(
typename parameter_type<R2>::type value) = 0;
250 virtual void read(
typename parameter_type<R3>::type value) = 0;
251 virtual void read(
typename parameter_type<R4>::type value) = 0;
252 virtual void read(
typename parameter_type<R5>::type value) = 0;
253 virtual void read(
typename parameter_type<R6>::type value) = 0;
254 virtual void read(
typename parameter_type<R7>::type value) = 0;
255 virtual void read(
typename parameter_type<R8>::type value) = 0;
261 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5,
typename R6,
typename R7>
268 virtual void read(
typename parameter_type<R1>::type value) = 0;
269 virtual void read(
typename parameter_type<R2>::type value) = 0;
270 virtual void read(
typename parameter_type<R3>::type value) = 0;
271 virtual void read(
typename parameter_type<R4>::type value) = 0;
272 virtual void read(
typename parameter_type<R5>::type value) = 0;
273 virtual void read(
typename parameter_type<R6>::type value) = 0;
274 virtual void read(
typename parameter_type<R7>::type value) = 0;
278 void read(no_type8&) {};
284 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5,
typename R6>
291 virtual void read(
typename parameter_type<R1>::type value) = 0;
292 virtual void read(
typename parameter_type<R2>::type value) = 0;
293 virtual void read(
typename parameter_type<R3>::type value) = 0;
294 virtual void read(
typename parameter_type<R4>::type value) = 0;
295 virtual void read(
typename parameter_type<R5>::type value) = 0;
296 virtual void read(
typename parameter_type<R6>::type value) = 0;
300 void read(no_type7&) {};
301 void read(no_type8&) {};
307 template <
typename R1,
typename R2,
typename R3,
typename R4,
typename R5>
308 class reader_type<R1, R2, R3, R4, R5, no_type6, no_type7, no_type8>
314 virtual void read(
typename parameter_type<R1>::type value) = 0;
315 virtual void read(
typename parameter_type<R2>::type value) = 0;
316 virtual void read(
typename parameter_type<R3>::type value) = 0;
317 virtual void read(
typename parameter_type<R4>::type value) = 0;
318 virtual void read(
typename parameter_type<R5>::type value) = 0;
322 void read(no_type6&) {};
323 void read(no_type7&) {};
324 void read(no_type8&) {};
330 template <
typename R1,
typename R2,
typename R3,
typename R4>
331 class reader_type<R1, R2, R3, R4, no_type5, no_type6, no_type7, no_type8>
337 virtual void read(
typename parameter_type<R1>::type value) = 0;
338 virtual void read(
typename parameter_type<R2>::type value) = 0;
339 virtual void read(
typename parameter_type<R3>::type value) = 0;
340 virtual void read(
typename parameter_type<R4>::type value) = 0;
344 void read(no_type5&) {};
345 void read(no_type6&) {};
346 void read(no_type7&) {};
347 void read(no_type8&) {};
353 template <
typename R1,
typename R2,
typename R3>
354 class reader_type<R1, R2, R3, no_type4, no_type5, no_type6, no_type7, no_type8>
360 virtual void read(
typename parameter_type<R1>::type value) = 0;
361 virtual void read(
typename parameter_type<R2>::type value) = 0;
362 virtual void read(
typename parameter_type<R3>::type value) = 0;
366 void read(no_type4&) {};
367 void read(no_type5&) {};
368 void read(no_type6&) {};
369 void read(no_type7&) {};
370 void read(no_type8&) {};
376 template <
typename R1,
typename R2>
377 class reader_type<R1, R2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
383 virtual void read(
typename parameter_type<R1>::type value) = 0;
384 virtual void read(
typename parameter_type<R2>::type value) = 0;
388 void read(no_type3&) {};
389 void read(no_type4&) {};
390 void read(no_type5&) {};
391 void read(no_type6&) {};
392 void read(no_type7&) {};
393 void read(no_type8&) {};
399 template <
typename R1>
400 class reader_type<R1, no_type2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
406 virtual void read(
typename parameter_type<R1>::type value) = 0;
410 void read(no_type2&) {};
411 void read(no_type3&) {};
412 void read(no_type4&) {};
413 void read(no_type5&) {};
414 void read(no_type6&) {};
415 void read(no_type7&) {};
416 void read(no_type8&) {};
426 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>
431 TBase& operator()(uint8_t* p_data, uint8_t typeId)
435 case 0:
return reinterpret_cast<U1&
>(*p_data);
436 case 1:
return reinterpret_cast<U2&
>(*p_data);
437 case 2:
return reinterpret_cast<U3&
>(*p_data);
438 case 3:
return reinterpret_cast<U4&
>(*p_data);
439 case 4:
return reinterpret_cast<U5&
>(*p_data);
440 case 5:
return reinterpret_cast<U6&
>(*p_data);
441 case 6:
return reinterpret_cast<U7&
>(*p_data);
442 case 7:
return reinterpret_cast<U8&
>(*p_data);
444 #ifdef ETL_THROW_EXCEPTIONS
451 const TBase& operator()(uint8_t* p_data, uint8_t typeId)
const
455 case 0:
return reinterpret_cast<const U1&
>(*p_data);
456 case 1:
return reinterpret_cast<const U2&
>(*p_data);
457 case 2:
return reinterpret_cast<const U3&
>(*p_data);
458 case 3:
return reinterpret_cast<const U4&
>(*p_data);
459 case 4:
return reinterpret_cast<const U5&
>(*p_data);
460 case 5:
return reinterpret_cast<const U6&
>(*p_data);
461 case 6:
return reinterpret_cast<const U7&
>(*p_data);
462 case 7:
return reinterpret_cast<const U8&
>(*p_data);
464 #ifdef ETL_THROW_EXCEPTIONS
475 template <
typename TBase,
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6,
typename U7>
480 TBase& operator()(uint8_t* p_data, uint8_t typeId)
484 case 0:
return reinterpret_cast<U1&
>(*p_data);
485 case 1:
return reinterpret_cast<U2&
>(*p_data);
486 case 2:
return reinterpret_cast<U3&
>(*p_data);
487 case 3:
return reinterpret_cast<U4&
>(*p_data);
488 case 4:
return reinterpret_cast<U5&
>(*p_data);
489 case 5:
return reinterpret_cast<U6&
>(*p_data);
490 case 6:
return reinterpret_cast<U7&
>(*p_data);
492 #ifdef ETL_THROW_EXCEPTIONS
499 const TBase& operator()(uint8_t* p_data, uint8_t typeId)
const
503 case 0:
return reinterpret_cast<const U1&
>(*p_data);
504 case 1:
return reinterpret_cast<const U2&
>(*p_data);
505 case 2:
return reinterpret_cast<const U3&
>(*p_data);
506 case 3:
return reinterpret_cast<const U4&
>(*p_data);
507 case 4:
return reinterpret_cast<const U5&
>(*p_data);
508 case 5:
return reinterpret_cast<const U6&
>(*p_data);
509 case 6:
return reinterpret_cast<const U7&
>(*p_data);
511 #ifdef ETL_THROW_EXCEPTIONS
522 template <
typename TBase,
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6>
527 TBase& operator()(uint8_t* p_data, uint8_t typeId)
531 case 0:
return reinterpret_cast<U1&
>(*p_data);
532 case 1:
return reinterpret_cast<U2&
>(*p_data);
533 case 2:
return reinterpret_cast<U3&
>(*p_data);
534 case 3:
return reinterpret_cast<U4&
>(*p_data);
535 case 4:
return reinterpret_cast<U5&
>(*p_data);
536 case 5:
return reinterpret_cast<U6&
>(*p_data);
538 #ifdef ETL_THROW_EXCEPTIONS
545 const TBase& operator()(uint8_t* p_data, uint8_t typeId)
const
549 case 0:
return reinterpret_cast<const U1&
>(*p_data);
550 case 1:
return reinterpret_cast<const U2&
>(*p_data);
551 case 2:
return reinterpret_cast<const U3&
>(*p_data);
552 case 3:
return reinterpret_cast<const U4&
>(*p_data);
553 case 4:
return reinterpret_cast<const U5&
>(*p_data);
554 case 5:
return reinterpret_cast<const U6&
>(*p_data);
556 #ifdef ETL_THROW_EXCEPTIONS
567 template <
typename TBase,
typename U1,
typename U2,
typename U3,
typename U4,
typename U5>
572 TBase& operator()(uint8_t* p_data, uint8_t typeId)
576 case 0:
return reinterpret_cast<U1&
>(*p_data);
577 case 1:
return reinterpret_cast<U2&
>(*p_data);
578 case 2:
return reinterpret_cast<U3&
>(*p_data);
579 case 3:
return reinterpret_cast<U4&
>(*p_data);
580 case 4:
return reinterpret_cast<U5&
>(*p_data);
582 #ifdef ETL_THROW_EXCEPTIONS
589 const TBase& operator()(uint8_t* p_data, uint8_t typeId)
const
593 case 0:
return reinterpret_cast<const U1&
>(*p_data);
594 case 1:
return reinterpret_cast<const U2&
>(*p_data);
595 case 2:
return reinterpret_cast<const U3&
>(*p_data);
596 case 3:
return reinterpret_cast<const U4&
>(*p_data);
597 case 4:
return reinterpret_cast<const U5&
>(*p_data);
599 #ifdef ETL_THROW_EXCEPTIONS
610 template <
typename TBase,
typename U1,
typename U2,
typename U3,
typename U4>
611 class upcast_functor<TBase, U1, U2, U3, U4, no_type5, no_type6, no_type7, no_type8>
615 TBase& operator()(uint8_t* p_data, uint8_t typeId)
619 case 0:
return reinterpret_cast<U1&
>(*p_data);
620 case 1:
return reinterpret_cast<U2&
>(*p_data);
621 case 2:
return reinterpret_cast<U3&
>(*p_data);
622 case 3:
return reinterpret_cast<U4&
>(*p_data);
624 #ifdef ETL_THROW_EXCEPTIONS
631 const TBase& operator()(uint8_t* p_data, uint8_t typeId)
const
635 case 0:
return reinterpret_cast<const U1&
>(*p_data);
636 case 1:
return reinterpret_cast<const U2&
>(*p_data);
637 case 2:
return reinterpret_cast<const U3&
>(*p_data);
638 case 3:
return reinterpret_cast<const U4&
>(*p_data);
640 #ifdef ETL_THROW_EXCEPTIONS
651 template <
typename TBase,
typename U1,
typename U2,
typename U3>
652 class upcast_functor<TBase, U1, U2, U3, no_type4, no_type5, no_type6, no_type7, no_type8>
656 TBase& operator()(uint8_t* p_data, uint8_t typeId)
660 case 0:
return reinterpret_cast<U1&
>(*p_data);
661 case 1:
return reinterpret_cast<U2&
>(*p_data);
662 case 2:
return reinterpret_cast<U3&
>(*p_data);
664 #ifdef ETL_THROW_EXCEPTIONS
671 const TBase& operator()(uint8_t* p_data, uint8_t typeId)
const
675 case 0:
return reinterpret_cast<const U1&
>(*p_data);
676 case 1:
return reinterpret_cast<const U2&
>(*p_data);
677 case 2:
return reinterpret_cast<const U3&
>(*p_data);
679 #ifdef ETL_THROW_EXCEPTIONS
690 template <
typename TBase,
typename U1,
typename U2>
691 class upcast_functor<TBase, U1, U2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
695 TBase& operator()(uint8_t* p_data, uint8_t typeId)
699 case 0:
return reinterpret_cast<U1&
>(*p_data);
700 case 1:
return reinterpret_cast<U2&
>(*p_data);
702 #ifdef ETL_THROW_EXCEPTIONS
709 const TBase& operator()(uint8_t* p_data, uint8_t typeId)
const
713 case 0:
return reinterpret_cast<const U1&
>(*p_data);
714 case 1:
return reinterpret_cast<const U2&
>(*p_data);
716 #ifdef ETL_THROW_EXCEPTIONS
727 template <
typename TBase,
typename U1>
728 class upcast_functor<TBase, U1, no_type2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
732 TBase& operator()(uint8_t* p_data, uint8_t typeId)
736 case 0:
return reinterpret_cast<U1&
>(*p_data);
738 #ifdef ETL_THROW_EXCEPTIONS
745 const TBase& operator()(uint8_t* p_data, uint8_t typeId)
const
749 case 0:
return reinterpret_cast<const U1&
>(*p_data);
751 #ifdef ETL_THROW_EXCEPTIONS
769 : type_id(UNSUPPORTED_TYPE_ID)
777 template <
typename T>
780 STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
782 new(&data.value[0]) T(value);
783 type_id = Type_Id_Lookup<T>::type_id;
792 type_id(other.type_id)
800 template <
typename T>
803 STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
805 new(&data.value[0]) T(value);
806 type_id = Type_Id_Lookup<T>::type_id;
817 return type_id == other.type_id;
825 template <
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6,
typename U7,
typename U8>
830 switch (other.type_id)
832 case 0: is_same_type = type_id == Type_Id_Lookup<U1>::type_id;
break;
833 case 1: is_same_type = type_id == Type_Id_Lookup<U2>::type_id;
break;
834 case 2: is_same_type = type_id == Type_Id_Lookup<U3>::type_id;
break;
835 case 3: is_same_type = type_id == Type_Id_Lookup<U4>::type_id;
break;
836 case 4: is_same_type = type_id == Type_Id_Lookup<U5>::type_id;
break;
837 case 5: is_same_type = type_id == Type_Id_Lookup<U6>::type_id;
break;
838 case 6: is_same_type = type_id == Type_Id_Lookup<U7>::type_id;
break;
839 case 7: is_same_type = type_id == Type_Id_Lookup<U8>::type_id;
break;
841 #ifdef ETL_THROW_EXCEPTIONS
858 case 0: reader.read(reinterpret_cast<T1&>(*&data.value[0]));
break;
859 case 1: reader.read(reinterpret_cast<T2&>(*&data.value[0]));
break;
860 case 2: reader.read(reinterpret_cast<T3&>(*&data.value[0]));
break;
861 case 3: reader.read(reinterpret_cast<T4&>(*&data.value[0]));
break;
862 case 4: reader.read(reinterpret_cast<T5&>(*&data.value[0]));
break;
863 case 5: reader.read(reinterpret_cast<T6&>(*&data.value[0]));
break;
864 case 6: reader.read(reinterpret_cast<T7&>(*&data.value[0]));
break;
865 case 7: reader.read(reinterpret_cast<T8&>(*&data.value[0]));
break;
867 #ifdef ETL_THROW_EXCEPTIONS
880 return type_id != UNSUPPORTED_TYPE_ID;
887 template <
typename T>
890 return type_id == Type_Id_Lookup<T>::type_id;
898 type_id = UNSUPPORTED_TYPE_ID;
906 template <
typename T>
909 STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
911 #ifdef ETL_THROW_EXCEPTIONS
918 return reinterpret_cast<T&
>(*&data.value[0]);
926 template <
typename T>
929 STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
931 #ifdef ETL_THROW_EXCEPTIONS
938 return reinterpret_cast<const T&
>(*&data.value[0]);
945 template <
typename TBase>
955 template <
typename TBase>
964 operator T1&() {
return get<T1>(); }
965 operator T2&() {
return get<T2>(); }
966 operator T3&() {
return get<T3>(); }
967 operator T4&() {
return get<T4>(); }
968 operator T5&() {
return get<T5>(); }
969 operator T6&() {
return get<T6>(); }
970 operator T7&() {
return get<T7>(); }
971 operator T8&() {
return get<T8>(); }
977 template <
typename T>
980 return Type_Is_Supported<T>::value;
988 template <
typename TBase,
typename T>
989 TBase& do_upcast(T& t)
991 return upcast_functor<TBase, T1, T2, T3, T4, T5, T6, T7, T8>()(t);
997 template <
typename TBase,
typename T>
998 const TBase& do_upcast(
const T& t)
const
1000 return upcast_functor<TBase, T1, T2, T3, T4, T5, T6, T7, T8>()(t);
1007 align_at<array<uint8_t, sizeof(largest_t)>, ALIGNMENT> data;
const TBase & upcast() const
Definition: variant.h:956
reader_type< T1, T2, T3, T4, T5, T6, T7, T8 > reader
The base type for derived readers.
Definition: variant.h:762
static bool is_supported_type()
Definition: variant.h:978
variant & operator=(typename parameter_type< T >::type value)
Definition: variant.h:801
Definition: variant.h:118
bool is_valid() const
Definition: variant.h:878
bool is_same_type(const variant< U1, U2, U3, U4, U5, U6, U7, U8 > &other) const
Definition: variant.h:826
exception(value_type reason)
Constructor.
Definition: exception.h:51
Definition: largest.h:120
void clear()
Clears the value to 'no valid stored value'.
Definition: variant.h:896
Definition: variant.h:242
Definition: algorithm.h:43
TBase & upcast()
Definition: variant.h:946
Definition: integral_limits.h:54
bool is_type() const
Definition: variant.h:888
variant()
Definition: variant.h:768
variant(const variant &other)
Definition: variant.h:790
variant(T value)
Definition: variant.h:778
Definition: exception.h:42
Definition: type_traits.h:195
value_type what() const
Definition: exception.h:60
Definition: type_traits.h:45
Base upcast_functor for eight types.
Definition: variant.h:427
bool is_same_type(const variant &other) const
Definition: variant.h:815
void call(reader &reader)
Definition: variant.h:854