Embedded Template Library 1.0
variant_legacy.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 jwellbelove, Robin S�derholm
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#include "../platform.h"
32#include "../utility.h"
33#include "../array.h"
34#include "../largest.h"
35#include "../exception.h"
36#include "../type_traits.h"
37#include "../integral_limits.h"
38#include "../static_assert.h"
39#include "../alignment.h"
40#include "../error_handler.h"
41#include "../null_type.h"
42#include "../placement_new.h"
43
44#include <stdint.h>
45
46#if defined(ETL_COMPILER_KEIL)
47 #pragma diag_suppress 940
48 #pragma diag_suppress 111
49#endif
50
51//*****************************************************************************
55//*****************************************************************************
56namespace etl
57{
58#if ETL_USING_CPP11 && !defined(ETL_USE_LEGACY_VARIANT)
59 namespace legacy
60 {
61#endif
62 namespace private_variant
63 {
64 //*************************************************************************
67 //*************************************************************************
68 template <size_t ID>
69 struct no_type
70 {
71 };
72 }
73
74 //***************************************************************************
77 //***************************************************************************
78 struct monostate
79 {
80 };
81
82 //***************************************************************************
85 //***************************************************************************
87 {
88 public:
89 variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
90 : exception(reason_, file_name_, line_number_)
91 {
92 }
93 };
94
95 //***************************************************************************
98 //***************************************************************************
100 {
101 public:
102 variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
103 : variant_exception(ETL_ERROR_TEXT("variant:unsupported type", ETL_VARIANT_FILE_ID"A"), file_name_, line_number_)
104 {
105 }
106 };
107
108 //***************************************************************************
111 //***************************************************************************
113 {
114 public:
115 bad_variant_access(string_type file_name_, numeric_type line_number_)
116 : variant_exception(ETL_ERROR_TEXT("variant:bad variant access", ETL_VARIANT_FILE_ID"B"), file_name_, line_number_)
117 {}
118 };
119
120 //***************************************************************************
123 //***************************************************************************
125 {
126 public:
127 variant_not_a_base_exception(string_type file_name_, numeric_type line_number_)
128 : variant_exception(ETL_ERROR_TEXT("variant:not_a base", ETL_VARIANT_FILE_ID"C"), file_name_, line_number_)
129 {
130 }
131 };
132
133 //***************************************************************************
137 //***************************************************************************
138 template <typename T1,
139 typename T2 = etl::null_type<2>,
140 typename T3 = etl::null_type<3>,
141 typename T4 = etl::null_type<4>,
142 typename T5 = etl::null_type<5>,
143 typename T6 = etl::null_type<6>,
144 typename T7 = etl::null_type<7>,
145 typename T8 = etl::null_type<8> >
147 {
148 public:
149
150 //***************************************************************************
152 //***************************************************************************
153 typedef uint_least8_t type_id_t;
154
155 //***************************************************************************
157 //***************************************************************************
158 static const type_id_t UNSUPPORTED_TYPE_ID = etl::integral_limits<type_id_t>::max;
159
160 private:
161
162 // All types of variant are friends.
163 template <typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7, typename U8>
164 friend class variant;
165
166 //***************************************************************************
168 //***************************************************************************
169 typedef typename etl::largest_type<T1, T2, T3, T4, T5, T6, T7, T8>::type largest_t;
170
171 //***************************************************************************
173 //***************************************************************************
174 static const size_t SIZE = sizeof(largest_t);
175
176 //***************************************************************************
178 //***************************************************************************
180
181 //***************************************************************************
183 //***************************************************************************
191
192 //***************************************************************************
194 //***************************************************************************
195 template <typename T>
196 struct Type_Id_Lookup
197 {
198 static const uint_least8_t type_id = etl::is_same<T, T1>::value ? 0 :
206 UNSUPPORTED_TYPE_ID;
207 };
208
209 //***************************************************************************
211 //***************************************************************************
212 template <typename T>
213 struct Type_Is_Supported : public etl::integral_constant<bool,
214 etl::is_same<T, T1>::value ||
215 etl::is_same<T, T2>::value ||
216 etl::is_same<T, T3>::value ||
217 etl::is_same<T, T4>::value ||
218 etl::is_same<T, T5>::value ||
219 etl::is_same<T, T6>::value ||
220 etl::is_same<T, T7>::value ||
221 etl::is_same<T, T8>::value>
222 {
223 };
224
225 public:
226
227 //***************************************************************************
229 //***************************************************************************
231 {
232 destruct_current();
233 }
234
235 //*************************************************************************
236 //**** Reader types *******************************************************
237 //*************************************************************************
238
239 //*************************************************************************
243 //*************************************************************************
244 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>
246 {
247 public:
248
249 friend class variant;
250
251 virtual ~reader_type()
252 {
253 }
254
255 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
256 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
257 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
258 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
259 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
260 virtual void read(typename etl::parameter_type<R6>::type value) = 0;
261 virtual void read(typename etl::parameter_type<R7>::type value) = 0;
262 virtual void read(typename etl::parameter_type<R8>::type value) = 0;
263 };
264
265 //*************************************************************************
267 //*************************************************************************
268 template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6, typename R7>
269 class reader_type<R1, R2, R3, R4, R5, R6, R7, no_type8>
270 {
271 public:
272
273 friend class variant;
274
275 virtual ~reader_type()
276 {
277 }
278
279 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
280 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
281 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
282 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
283 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
284 virtual void read(typename etl::parameter_type<R6>::type value) = 0;
285 virtual void read(typename etl::parameter_type<R7>::type value) = 0;
286
287 private:
288
289 void read(no_type8&) {};
290 };
291
292 //*************************************************************************
294 //*************************************************************************
295 template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6>
296 class reader_type<R1, R2, R3, R4, R5, R6, no_type7, no_type8>
297 {
298 public:
299
300 friend class variant;
301
302 virtual ~reader_type()
303 {
304 }
305
306 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
307 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
308 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
309 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
310 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
311 virtual void read(typename etl::parameter_type<R6>::type value) = 0;
312
313 private:
314
315 void read(no_type7&) {};
316 void read(no_type8&) {};
317 };
318
319 //*************************************************************************
321 //*************************************************************************
322 template <typename R1, typename R2, typename R3, typename R4, typename R5>
323 class reader_type<R1, R2, R3, R4, R5, no_type6, no_type7, no_type8>
324 {
325 public:
326
327 friend class variant;
328
329 virtual ~reader_type()
330 {
331 }
332
333 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
334 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
335 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
336 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
337 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
338
339 private:
340
341 void read(no_type6&) {};
342 void read(no_type7&) {};
343 void read(no_type8&) {};
344 };
345
346 //*************************************************************************
348 //*************************************************************************
349 template <typename R1, typename R2, typename R3, typename R4>
351 {
352 public:
353
354 friend class variant;
355
356 virtual ~reader_type()
357 {
358 }
359
360 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
361 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
362 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
363 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
364
365 private:
366
367 void read(no_type5&) {};
368 void read(no_type6&) {};
369 void read(no_type7&) {};
370 void read(no_type8&) {};
371 };
372
373 //*************************************************************************
375 //*************************************************************************
376 template <typename R1, typename R2, typename R3>
378 {
379 public:
380
381 friend class variant;
382
383 virtual ~reader_type()
384 {
385 }
386
387 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
388 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
389 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
390
391 private:
392
393 void read(no_type4&) {};
394 void read(no_type5&) {};
395 void read(no_type6&) {};
396 void read(no_type7&) {};
397 void read(no_type8&) {};
398 };
399
400 //*************************************************************************
402 //*************************************************************************
403 template <typename R1, typename R2>
405 {
406 public:
407
408 friend class variant;
409
410 virtual ~reader_type()
411 {
412 }
413
414 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
415 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
416
417 private:
418
419 void read(no_type3&) {};
420 void read(no_type4&) {};
421 void read(no_type5&) {};
422 void read(no_type6&) {};
423 void read(no_type7&) {};
424 void read(no_type8&) {};
425 };
426
427 //*************************************************************************
429 //*************************************************************************
430 template <typename R1>
432 {
433 public:
434
435 friend class variant;
436
437 virtual ~reader_type()
438 {
439 }
440
441 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
442
443 private:
444
445 void read(no_type2&) {};
446 void read(no_type3&) {};
447 void read(no_type4&) {};
448 void read(no_type5&) {};
449 void read(no_type6&) {};
450 void read(no_type7&) {};
451 void read(no_type8&) {};
452 };
453
454 //***************************************************************************
456 //***************************************************************************
458
459 //***************************************************************************
462 //***************************************************************************
465 : type_id(UNSUPPORTED_TYPE_ID)
466 {
467 }
469
470 //***************************************************************************
473 //***************************************************************************
474 template <typename T>
475 variant(const T& value)
476 {
477 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
478
479 ::new (static_cast<T*>(data)) T(value);
480 type_id = Type_Id_Lookup<T>::type_id;
481 }
482
483 //***************************************************************************
486 //***************************************************************************
488 variant(const variant& other)
489 {
490 switch (other.type_id)
491 {
492 case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
493 case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
494 case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
495 case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
496 case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
497 case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
498 case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
499 case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
500 default: break;
501 }
502
503 type_id = other.type_id;
504 }
506
507#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VARIANT_FORCE_CPP03_IMPLEMENTATION)
508 //*************************************************************************
510 //*************************************************************************
511 template <typename T, typename... Args>
512 T& emplace(Args&&... args)
513 {
514 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
515
516 destruct_current();
517 ::new (static_cast<T*>(data)) T(etl::forward<Args>(args)...);
518 type_id = Type_Id_Lookup<T>::type_id;
519
520 return *static_cast<T*>(data);
521 }
522#else
523 //***************************************************************************
525 //***************************************************************************
526 template <typename T, typename TP1>
527 T& emplace(const TP1& value1)
528 {
529 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
530
531 destruct_current();
532 ::new (static_cast<T*>(data)) T(value1);
533 type_id = Type_Id_Lookup<T>::type_id;
534
535 return *static_cast<T*>(data);
536 }
537
538 //***************************************************************************
540 //***************************************************************************
541 template <typename T, typename TP1, typename TP2>
542 T& emplace(const TP1& value1, const TP2& value2)
543 {
544 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
545
546 destruct_current();
547 ::new (static_cast<T*>(data)) T(value1, value2);
548 type_id = Type_Id_Lookup<T>::type_id;
549
550 return *static_cast<T*>(data);
551 }
552
553 //***************************************************************************
555 //***************************************************************************
556 template <typename T, typename TP1, typename TP2, typename TP3>
557 T& emplace(const TP1& value1, const TP2& value2, const TP3& value3)
558 {
559 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
560
561 destruct_current();
562 ::new (static_cast<T*>(data)) T(value1, value2, value3);
563 type_id = Type_Id_Lookup<T>::type_id;
564
565 return *static_cast<T*>(data);
566 }
567
568 //***************************************************************************
570 //***************************************************************************
571 template <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
572 T& emplace(const TP1& value1, const TP2& value2, const TP3& value3, const TP4& value4)
573 {
574 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
575
576 destruct_current();
577 ::new (static_cast<T*>(data)) T(value1, value2, value3, value4);
578 type_id = Type_Id_Lookup<T>::type_id;
579
580 return *static_cast<T*>(data);
581 }
582#endif
583
584 //***************************************************************************
587 //***************************************************************************
588 template <typename T>
589 variant& operator =(const T& value)
590 {
591 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
592
593 destruct_current();
594 ::new (static_cast<T*>(data)) T(value);
595 type_id = Type_Id_Lookup<T>::type_id;
596
597 return *this;
598 }
599
600 //***************************************************************************
603 //***************************************************************************
604 variant& operator =(const variant& other)
605 {
606 if (this != &other)
607 {
608 destruct_current();
609
610 switch (other.type_id)
611 {
612 case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
613 case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
614 case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
615 case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
616 case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
617 case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
618 case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
619 case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
620 default: break;
621 }
622
623 type_id = other.type_id;
624 }
625
626 return *this;
627 }
628
629 //***************************************************************************
633 //***************************************************************************
634 bool is_same_type(const variant& other) const
635 {
636 return type_id == other.type_id;
637 }
638
639 //***************************************************************************
643 //***************************************************************************
644 template <typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7, typename U8>
646 {
647 bool is_same = false;
648
649 switch (other.type_id)
650 {
651 case 0: is_same = (type_id == Type_Id_Lookup<U1>::type_id); break;
652 case 1: is_same = (type_id == Type_Id_Lookup<U2>::type_id); break;
653 case 2: is_same = (type_id == Type_Id_Lookup<U3>::type_id); break;
654 case 3: is_same = (type_id == Type_Id_Lookup<U4>::type_id); break;
655 case 4: is_same = (type_id == Type_Id_Lookup<U5>::type_id); break;
656 case 5: is_same = (type_id == Type_Id_Lookup<U6>::type_id); break;
657 case 6: is_same = (type_id == Type_Id_Lookup<U7>::type_id); break;
658 case 7: is_same = (type_id == Type_Id_Lookup<U8>::type_id); break;
659 default: break;
660 }
661
662 return is_same;
663 }
664
665 //***************************************************************************
668 //***************************************************************************
669 void call(reader& r)
670 {
671 switch (type_id)
672 {
673 case 0: r.read(static_cast<T1&>(data)); break;
674 case 1: r.read(static_cast<T2&>(data)); break;
675 case 2: r.read(static_cast<T3&>(data)); break;
676 case 3: r.read(static_cast<T4&>(data)); break;
677 case 4: r.read(static_cast<T5&>(data)); break;
678 case 5: r.read(static_cast<T6&>(data)); break;
679 case 6: r.read(static_cast<T7&>(data)); break;
680 case 7: r.read(static_cast<T8&>(data)); break;
681 default: break;
682 }
683 }
684
685 //***************************************************************************
688 //***************************************************************************
689 bool is_valid() const
690 {
691 return type_id != UNSUPPORTED_TYPE_ID;
692 }
693
694 //***************************************************************************
697 //***************************************************************************
698 template <typename T>
699 bool is_type() const
700 {
701 return type_id == Type_Id_Lookup<T>::type_id;
702 }
703
704 //***************************************************************************
706 //***************************************************************************
707 size_t index() const
708 {
709 return type_id;
710 }
711
712 //***************************************************************************
714 //***************************************************************************
715 void clear()
716 {
717 destruct_current();
718 }
719
720 //***************************************************************************
724 //***************************************************************************
725 template <typename T>
726 T& get()
727 {
728 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
729 ETL_ASSERT(is_type<T>(), ETL_ERROR(variant_incorrect_type_exception));
730
731 return static_cast<T&>(data);
732 }
733
734 //***************************************************************************
738 //***************************************************************************
739 template <typename T>
740 const T& get() const
741 {
742 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
743 ETL_ASSERT(is_type<T>(), ETL_ERROR(variant_incorrect_type_exception));
744
745 return static_cast<const T&>(data);
746 }
747
748 //***************************************************************************
751 //***************************************************************************
752 template <typename TBase>
753 TBase* upcast_ptr()
754 {
755 if (is_base_of<TBase>())
756 {
757 return reinterpret_cast<TBase*>(static_cast<uint_least8_t*>(data));
758 }
759 else
760 {
761 return ETL_NULLPTR;
762 }
763 }
764
765 //***************************************************************************
768 //***************************************************************************
769 template <typename TBase>
770 TBase& upcast()
771 {
772 TBase* ptr = upcast_ptr<TBase>();
773
774 ETL_ASSERT(ptr != ETL_NULLPTR, ETL_ERROR(variant_not_a_base_exception));
775
776 return *ptr;
777 }
778
779 //***************************************************************************
782 //***************************************************************************
783 template <typename TBase>
784 const TBase* upcast_ptr() const
785 {
786 if (is_base_of<TBase>())
787 {
788 return reinterpret_cast<const TBase*>(static_cast<const uint_least8_t*>(data));
789 }
790 else
791 {
792 return ETL_NULLPTR;
793 }
794 }
795
796 //***************************************************************************
799 //***************************************************************************
800 template <typename TBase>
801 const TBase& upcast() const
802 {
803 const TBase* ptr = upcast_ptr<TBase>();
804
805 ETL_ASSERT(ptr != ETL_NULLPTR, ETL_ERROR(variant_not_a_base_exception));
806
807 return *ptr;
808 }
809
810 //***************************************************************************
812 //***************************************************************************
813 template <typename TBase>
814 bool is_base_of() const
815 {
816 bool is_base;
817
818 switch (type_id)
819 {
820 case 0: is_base = etl::is_base_of<TBase, T1>::value; break;
821 case 1: is_base = etl::is_base_of<TBase, T2>::value; break;
822 case 2: is_base = etl::is_base_of<TBase, T3>::value; break;
823 case 3: is_base = etl::is_base_of<TBase, T4>::value; break;
824 case 4: is_base = etl::is_base_of<TBase, T5>::value; break;
825 case 5: is_base = etl::is_base_of<TBase, T6>::value; break;
826 case 6: is_base = etl::is_base_of<TBase, T7>::value; break;
827 case 7: is_base = etl::is_base_of<TBase, T8>::value; break;
828 default: is_base = false; break;
829 }
830
831 return is_base;
832 }
833
834 //***************************************************************************
836 //***************************************************************************
837 operator T1& () { return get<T1>(); }
838 operator T2& () { return get<T2>(); }
839 operator T3& () { return get<T3>(); }
840 operator T4& () { return get<T4>(); }
841 operator T5& () { return get<T5>(); }
842 operator T6& () { return get<T6>(); }
843 operator T7& () { return get<T7>(); }
844 operator T8& () { return get<T8>(); }
845
846 //***************************************************************************
849 //***************************************************************************
850 template <typename T>
851 static bool is_supported_type()
852 {
853 return Type_Is_Supported<T>::value;
854 }
855
856 private:
857
859 //***************************************************************************
861 //***************************************************************************
862 void destruct_current()
863 {
864 switch (type_id)
865 {
866 case 0: { static_cast<T1*>(data)->~T1(); break; }
867 case 1: { static_cast<T2*>(data)->~T2(); break; }
868 case 2: { static_cast<T3*>(data)->~T3(); break; }
869 case 3: { static_cast<T4*>(data)->~T4(); break; }
870 case 4: { static_cast<T5*>(data)->~T5(); break; }
871 case 5: { static_cast<T6*>(data)->~T6(); break; }
872 case 6: { static_cast<T7*>(data)->~T7(); break; }
873 case 7: { static_cast<T8*>(data)->~T8(); break; }
874 default: { break; }
875 }
876
877 type_id = UNSUPPORTED_TYPE_ID;
878 }
880
881 //***************************************************************************
884 //***************************************************************************
886
887 //***************************************************************************
889 //***************************************************************************
890 type_id_t type_id;
891 };
892
893 namespace private_variant
894 {
895 template <size_t, typename>
897#define ETL_VARIANT_HELPER(INDEX, TYPE) \
898 template <typename T1, \
899 typename T2, \
900 typename T3, \
901 typename T4, \
902 typename T5, \
903 typename T6, \
904 typename T7, \
905 typename T8> \
906 struct variant_alternative_helper<INDEX, variant<T1, T2, T3, T4, T5, T6, T7, T8> > \
907 { \
908 typedef TYPE type; \
909 };
910 ETL_VARIANT_HELPER(0, T1)
911 ETL_VARIANT_HELPER(1, T2)
912 ETL_VARIANT_HELPER(2, T3)
913 ETL_VARIANT_HELPER(3, T4)
914 ETL_VARIANT_HELPER(4, T5)
915 ETL_VARIANT_HELPER(5, T6)
916 ETL_VARIANT_HELPER(6, T7)
917 ETL_VARIANT_HELPER(7, T8)
918#undef ETL_VARIANT_HELPER
919 } // namespace private_variant
920
921 template <size_t tIndex, typename TVariant>
923 {
925 };
926
927 template <size_t tIndex, typename TVariant>
928 struct variant_alternative<tIndex, TVariant const>
929 {
931 };
932
933 template <size_t tIndex, typename TVariant>
934 struct variant_alternative<tIndex, TVariant volatile>
935 {
937 };
938
939 template <size_t tIndex, typename TVariant>
940 struct variant_alternative<tIndex, TVariant const volatile>
941 {
943 };
944
945 template <typename T, typename TVariant>
946 inline T& get(TVariant& variant)
947 {
948 return variant.template get<T>();
949 }
950
951 template <typename T, typename TVariant>
952 inline T const& get(TVariant const& variant)
953 {
954 return variant.template get<T>();
955 }
956
957 template <size_t tIndex, typename TVariant>
958 inline typename variant_alternative<tIndex, TVariant>::type& get(TVariant& variant)
959 {
960 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
961 }
962
963 template <size_t tIndex, typename TVariant>
964 inline typename variant_alternative<tIndex, TVariant const>::type& get(TVariant const& variant)
965 {
966 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
967 }
968
969#define ETL_GEN_LEGACY_VISIT(VISITQUAL, VARIANTQUAL) \
970 template <typename TReturn, typename TVisitor, typename TVariant> \
971 static TReturn visit(TVisitor VISITQUAL visitor, TVariant VARIANTQUAL variant) \
972 { \
973 switch (variant.index()) \
974 { \
975 case 0: return static_cast<TReturn>(visitor(get<0>(variant))); \
976 case 1: return static_cast<TReturn>(visitor(get<1>(variant))); \
977 case 2: return static_cast<TReturn>(visitor(get<2>(variant))); \
978 case 3: return static_cast<TReturn>(visitor(get<3>(variant))); \
979 case 4: return static_cast<TReturn>(visitor(get<4>(variant))); \
980 case 5: return static_cast<TReturn>(visitor(get<5>(variant))); \
981 case 6: return static_cast<TReturn>(visitor(get<6>(variant))); \
982 case 7: return static_cast<TReturn>(visitor(get<7>(variant))); \
983 default: ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(bad_variant_access), TReturn()); \
984 } \
985 }
986
987 ETL_GEN_LEGACY_VISIT(&, &)
988 ETL_GEN_LEGACY_VISIT(const&, &)
989 ETL_GEN_LEGACY_VISIT(&, const&)
990 ETL_GEN_LEGACY_VISIT(const&, const&)
991
992#undef ETL_GEN_LEGACY_VISIT
993
994#if ETL_USING_CPP11 && !defined(ETL_USE_LEGACY_VARIANT)
995 }
996#endif
997}
998
Definition: null_type.h:40
Definition: variant_legacy.h:246
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
Definition: exception.h:47
Definition: integral_limits.h:468
Definition: largest.h:227
integral_constant
Definition: type_traits_generator.h:832
is_base_of
Definition: type_traits_generator.h:1252
is_same
Definition: type_traits_generator.h:1041
variant(const T &value)
Definition: variant_legacy.h:475
bool is_same_type(const variant< U1, U2, U3, U4, U5, U6, U7, U8 > &other) const
Definition: variant_legacy.h:645
static bool is_supported_type()
Definition: variant_legacy.h:851
const T & get() const
Definition: variant_legacy.h:740
~variant()
Destructor.
Definition: variant_legacy.h:230
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3, const TP4 &value4)
Emplace with four constructor parameters.
Definition: variant_legacy.h:572
variant()
Definition: variant_legacy.h:464
bool is_same_type(const variant &other) const
Definition: variant_legacy.h:634
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3)
Emplace with three constructor parameters.
Definition: variant_legacy.h:557
void call(reader &r)
Definition: variant_legacy.h:669
T & get()
Definition: variant_legacy.h:726
bool is_base_of() const
Check that TBase is a base class of the current variant value.
Definition: variant_legacy.h:814
uint_least8_t type_id_t
The type used for ids.
Definition: variant_legacy.h:153
T & emplace(const TP1 &value1)
Emplace with one constructor parameter.
Definition: variant_legacy.h:527
const TBase * upcast_ptr() const
Definition: variant_legacy.h:784
reader_type< T1, T2, T3, T4, T5, T6, T7, T8 > reader
The base type for derived readers.
Definition: variant_legacy.h:457
bool is_type() const
Definition: variant_legacy.h:699
void clear()
Clears the value to 'no valid stored value'.
Definition: variant_legacy.h:715
T & emplace(const TP1 &value1, const TP2 &value2)
Emplace with two constructor parameters.
Definition: variant_legacy.h:542
TBase * upcast_ptr()
Definition: variant_legacy.h:753
size_t index() const
Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID.
Definition: variant_legacy.h:707
TBase & upcast()
Definition: variant_legacy.h:770
variant(const variant &other)
Definition: variant_legacy.h:488
const TBase & upcast() const
Definition: variant_legacy.h:801
bool is_valid() const
Definition: variant_legacy.h:689
Definition: variant_legacy.h:113
Definition: variant_legacy.h:147
Definition: variant_legacy.h:87
Definition: variant_legacy.h:100
Definition: variant_legacy.h:125
Definition: variant_legacy.h:79
bitset_ext
Definition: absolute.h:38
T & get(array< T, MAXN > &a)
Definition: array.h:710
etl::optional< T > read(etl::bit_stream_reader &stream)
Read a checked type from a stream.
Definition: bit_stream.h:1348
Definition: alignment.h:223
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:48
Definition: variant_legacy.h:70
Definition: variant_legacy.h:896
Definition: variant_legacy.h:923