Embedded Template Library 1.0
Loading...
Searching...
No Matches
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#include "../monostate.h"
44
45#include <stdint.h>
46
47#if defined(ETL_COMPILER_KEIL)
48 #pragma diag_suppress 940
49 #pragma diag_suppress 111
50#endif
51
52//*****************************************************************************
56//*****************************************************************************
57namespace etl
58{
59#if ETL_NOT_USING_LEGACY_VARIANT
60 namespace legacy
61 {
62#endif
63 namespace private_variant
64 {
65 //*************************************************************************
68 //*************************************************************************
69 template <size_t Id>
70 struct no_type
71 {
72 };
73 }
74
75 //***************************************************************************
78 //***************************************************************************
80
81 //***************************************************************************
84 //***************************************************************************
85 class variant_exception : public etl::exception
86 {
87 public:
88 variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
89 : exception(reason_, file_name_, line_number_)
90 {
91 }
92 };
93
94 //***************************************************************************
97 //***************************************************************************
98 class variant_incorrect_type_exception : public variant_exception
99 {
100 public:
101 variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
102 : variant_exception(ETL_ERROR_TEXT("variant:unsupported type", ETL_VARIANT_FILE_ID"A"), file_name_, line_number_)
103 {
104 }
105 };
106
107 //***************************************************************************
110 //***************************************************************************
111 class bad_variant_access : public variant_exception
112 {
113 public:
114 bad_variant_access(string_type file_name_, numeric_type line_number_)
115 : variant_exception(ETL_ERROR_TEXT("variant:bad variant access", ETL_VARIANT_FILE_ID"B"), file_name_, line_number_)
116 {}
117 };
118
119 //***************************************************************************
122 //***************************************************************************
123 class variant_not_a_base_exception : public variant_exception
124 {
125 public:
126 variant_not_a_base_exception(string_type file_name_, numeric_type line_number_)
127 : variant_exception(ETL_ERROR_TEXT("variant:not_a base", ETL_VARIANT_FILE_ID"C"), file_name_, line_number_)
128 {
129 }
130 };
131
132 //***************************************************************************
136 //***************************************************************************
137 template <typename T1,
138 typename T2 = etl::null_type<2>,
139 typename T3 = etl::null_type<3>,
140 typename T4 = etl::null_type<4>,
141 typename T5 = etl::null_type<5>,
142 typename T6 = etl::null_type<6>,
143 typename T7 = etl::null_type<7>,
144 typename T8 = etl::null_type<8> >
145 class variant
146 {
147 public:
148
149 //***************************************************************************
151 //***************************************************************************
152 typedef uint_least8_t type_id_t;
153
154 //***************************************************************************
156 //***************************************************************************
158
159 private:
160
161 // All types of variant are friends.
162 template <typename V1, typename V2, typename V3, typename V4, typename V5, typename V6, typename V7, typename V8>
163 friend class variant;
164
165 //***************************************************************************
167 //***************************************************************************
168 typedef typename etl::largest_type<T1, T2, T3, T4, T5, T6, T7, T8>::type largest_t;
169
170 //***************************************************************************
172 //***************************************************************************
173 static const size_t SIZE = sizeof(largest_t);
174
175 //***************************************************************************
177 //***************************************************************************
178 static const size_t ALIGNMENT = etl::largest_alignment<T1, T2, T3, T4, T5, T6, T7, T8>::value;
179
180 //***************************************************************************
182 //***************************************************************************
183 typedef etl::null_type<2> no_type2;
184 typedef etl::null_type<3> no_type3;
185 typedef etl::null_type<4> no_type4;
186 typedef etl::null_type<5> no_type5;
187 typedef etl::null_type<6> no_type6;
188 typedef etl::null_type<7> no_type7;
189 typedef etl::null_type<8> no_type8;
190
191 //***************************************************************************
193 //***************************************************************************
194 template <typename T>
195 struct Type_Id_Lookup
196 {
197 static const uint_least8_t type_id = etl::is_same<T, T1>::value ? 0 :
206 };
207
208 //***************************************************************************
210 //***************************************************************************
211 template <typename T>
212 struct Type_Is_Supported : public etl::integral_constant<bool,
213 etl::is_same<T, T1>::value ||
214 etl::is_same<T, T2>::value ||
215 etl::is_same<T, T3>::value ||
216 etl::is_same<T, T4>::value ||
217 etl::is_same<T, T5>::value ||
218 etl::is_same<T, T6>::value ||
219 etl::is_same<T, T7>::value ||
220 etl::is_same<T, T8>::value>
221 {
222 };
223
224 public:
225
226 //***************************************************************************
228 //***************************************************************************
230 {
231 destruct_current();
232 }
233
234 //*************************************************************************
235 //**** Reader types *******************************************************
236 //*************************************************************************
237
238 //*************************************************************************
242 //*************************************************************************
243 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>
245 {
246 public:
247
248 friend class variant;
249
250 virtual ~reader_type()
251 {
252 }
253
254 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
255 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
256 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
257 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
258 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
259 virtual void read(typename etl::parameter_type<R6>::type value) = 0;
260 virtual void read(typename etl::parameter_type<R7>::type value) = 0;
261 virtual void read(typename etl::parameter_type<R8>::type value) = 0;
262 };
263
264 //*************************************************************************
266 //*************************************************************************
267 template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6, typename R7>
268 class reader_type<R1, R2, R3, R4, R5, R6, R7, no_type8>
269 {
270 public:
271
272 friend class variant;
273
274 virtual ~reader_type()
275 {
276 }
277
278 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
279 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
280 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
281 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
282 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
283 virtual void read(typename etl::parameter_type<R6>::type value) = 0;
284 virtual void read(typename etl::parameter_type<R7>::type value) = 0;
285
286 private:
287
288 void read(no_type8&) {};
289 };
290
291 //*************************************************************************
293 //*************************************************************************
294 template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6>
295 class reader_type<R1, R2, R3, R4, R5, R6, no_type7, no_type8>
296 {
297 public:
298
299 friend class variant;
300
301 virtual ~reader_type()
302 {
303 }
304
305 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
306 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
307 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
308 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
309 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
310 virtual void read(typename etl::parameter_type<R6>::type value) = 0;
311
312 private:
313
314 void read(no_type7&) {};
315 void read(no_type8&) {};
316 };
317
318 //*************************************************************************
320 //*************************************************************************
321 template <typename R1, typename R2, typename R3, typename R4, typename R5>
322 class reader_type<R1, R2, R3, R4, R5, no_type6, no_type7, no_type8>
323 {
324 public:
325
326 friend class variant;
327
328 virtual ~reader_type()
329 {
330 }
331
332 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
333 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
334 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
335 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
336 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
337
338 private:
339
340 void read(no_type6&) {};
341 void read(no_type7&) {};
342 void read(no_type8&) {};
343 };
344
345 //*************************************************************************
347 //*************************************************************************
348 template <typename R1, typename R2, typename R3, typename R4>
349 class reader_type<R1, R2, R3, R4, no_type5, no_type6, no_type7, no_type8>
350 {
351 public:
352
353 friend class variant;
354
355 virtual ~reader_type()
356 {
357 }
358
359 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
360 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
361 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
362 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
363
364 private:
365
366 void read(no_type5&) {};
367 void read(no_type6&) {};
368 void read(no_type7&) {};
369 void read(no_type8&) {};
370 };
371
372 //*************************************************************************
374 //*************************************************************************
375 template <typename R1, typename R2, typename R3>
376 class reader_type<R1, R2, R3, no_type4, no_type5, no_type6, no_type7, no_type8>
377 {
378 public:
379
380 friend class variant;
381
382 virtual ~reader_type()
383 {
384 }
385
386 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
387 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
388 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
389
390 private:
391
392 void read(no_type4&) {};
393 void read(no_type5&) {};
394 void read(no_type6&) {};
395 void read(no_type7&) {};
396 void read(no_type8&) {};
397 };
398
399 //*************************************************************************
401 //*************************************************************************
402 template <typename R1, typename R2>
403 class reader_type<R1, R2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
404 {
405 public:
406
407 friend class variant;
408
409 virtual ~reader_type()
410 {
411 }
412
413 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
414 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
415
416 private:
417
418 void read(no_type3&) {};
419 void read(no_type4&) {};
420 void read(no_type5&) {};
421 void read(no_type6&) {};
422 void read(no_type7&) {};
423 void read(no_type8&) {};
424 };
425
426 //*************************************************************************
428 //*************************************************************************
429 template <typename R1>
430 class reader_type<R1, no_type2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
431 {
432 public:
433
434 friend class variant;
435
436 virtual ~reader_type()
437 {
438 }
439
440 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
441
442 private:
443
444 void read(no_type2&) {};
445 void read(no_type3&) {};
446 void read(no_type4&) {};
447 void read(no_type5&) {};
448 void read(no_type6&) {};
449 void read(no_type7&) {};
450 void read(no_type8&) {};
451 };
452
453 //***************************************************************************
455 //***************************************************************************
456 typedef reader_type<T1, T2, T3, T4, T5, T6, T7, T8> reader;
457
458 //***************************************************************************
461 //***************************************************************************
463 variant()
464 : type_id(UNSUPPORTED_TYPE_ID)
465 {
466 }
467#include "diagnostic_pop.h"
468
469 //***************************************************************************
472 //***************************************************************************
473 template <typename T>
474 variant(const T& value)
475 {
476 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
477
478 ::new (static_cast<T*>(data)) T(value);
479 type_id = Type_Id_Lookup<T>::type_id;
480 }
481
482 //***************************************************************************
485 //***************************************************************************
486 template <size_t Index, typename T>
487 explicit variant(etl::in_place_index_t<Index>, T const& value)
488 : type_id(Index)
489 {
490 ETL_STATIC_ASSERT(Type_Id_Lookup<T>::type_id == Index, "Missmatched type");
491 ::new (static_cast<T*>(data)) T(value);
492 type_id = Index;
493 }
494
495 //***************************************************************************
498 //***************************************************************************
500 variant(const variant& other)
501 {
502 switch (other.type_id)
503 {
504 case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
505 case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
506 case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
507 case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
508 case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
509 case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
510 case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
511 case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
512 default: break;
513 }
514
515 type_id = other.type_id;
516 }
517#include "diagnostic_pop.h"
518
519#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VARIANT_FORCE_CPP03_IMPLEMENTATION)
520 //*************************************************************************
522 //*************************************************************************
523 template <typename T, typename... Args>
524 T& emplace(Args&&... args)
525 {
526 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
527
528 destruct_current();
529 ::new (static_cast<T*>(data)) T(etl::forward<Args>(args)...);
530 type_id = Type_Id_Lookup<T>::type_id;
531
532 return *static_cast<T*>(data);
533 }
534#else
535 //***************************************************************************
537 //***************************************************************************
538 template <typename T>
540 {
541 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
542
543 destruct_current();
544 ::new (static_cast<T*>(data)) T();
545 type_id = Type_Id_Lookup<T>::type_id;
546
547 return *static_cast<T*>(data);
548 }
549
550 //***************************************************************************
552 //***************************************************************************
553 template <typename T, typename TP1>
554 T& emplace(const TP1& value1)
555 {
556 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
557
558 destruct_current();
559 ::new (static_cast<T*>(data)) T(value1);
560 type_id = Type_Id_Lookup<T>::type_id;
561
562 return *static_cast<T*>(data);
563 }
564
565 //***************************************************************************
567 //***************************************************************************
568 template <typename T, typename TP1, typename TP2>
569 T& emplace(const TP1& value1, const TP2& value2)
570 {
571 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
572
573 destruct_current();
574 ::new (static_cast<T*>(data)) T(value1, value2);
575 type_id = Type_Id_Lookup<T>::type_id;
576
577 return *static_cast<T*>(data);
578 }
579
580 //***************************************************************************
582 //***************************************************************************
583 template <typename T, typename TP1, typename TP2, typename TP3>
584 T& emplace(const TP1& value1, const TP2& value2, const TP3& value3)
585 {
586 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
587
588 destruct_current();
589 ::new (static_cast<T*>(data)) T(value1, value2, value3);
590 type_id = Type_Id_Lookup<T>::type_id;
591
592 return *static_cast<T*>(data);
593 }
594
595 //***************************************************************************
597 //***************************************************************************
598 template <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
599 T& emplace(const TP1& value1, const TP2& value2, const TP3& value3, const TP4& value4)
600 {
601 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
602
603 destruct_current();
604 ::new (static_cast<T*>(data)) T(value1, value2, value3, value4);
605 type_id = Type_Id_Lookup<T>::type_id;
606
607 return *static_cast<T*>(data);
608 }
609#endif
610
611 //***************************************************************************
614 //***************************************************************************
615 template <typename T>
616 variant& operator =(const T& value)
617 {
618 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
619
620 destruct_current();
621 ::new (static_cast<T*>(data)) T(value);
622 type_id = Type_Id_Lookup<T>::type_id;
623
624 return *this;
625 }
626
627 //***************************************************************************
630 //***************************************************************************
631 variant& operator =(const variant& other)
632 {
633 if (this != &other)
634 {
635 destruct_current();
636
637 switch (other.type_id)
638 {
639 case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
640 case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
641 case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
642 case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
643 case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
644 case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
645 case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
646 case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
647 default: break;
648 }
649
650 type_id = other.type_id;
651 }
652
653 return *this;
654 }
655
656 //***************************************************************************
660 //***************************************************************************
661 bool is_same_type(const variant& other) const
662 {
663 return type_id == other.type_id;
664 }
665
666 //***************************************************************************
670 //***************************************************************************
671 template <typename V1, typename V2, typename V3, typename V4, typename V5, typename V6, typename V7, typename V8>
672 bool is_same_type(const variant<V1, V2, V3, V4, V5, V6, V7, V8>& other) const
673 {
674 bool is_same = false;
675
676 switch (other.type_id)
677 {
678 case 0: is_same = (type_id == Type_Id_Lookup<V1>::type_id); break;
679 case 1: is_same = (type_id == Type_Id_Lookup<V2>::type_id); break;
680 case 2: is_same = (type_id == Type_Id_Lookup<V3>::type_id); break;
681 case 3: is_same = (type_id == Type_Id_Lookup<V4>::type_id); break;
682 case 4: is_same = (type_id == Type_Id_Lookup<V5>::type_id); break;
683 case 5: is_same = (type_id == Type_Id_Lookup<V6>::type_id); break;
684 case 6: is_same = (type_id == Type_Id_Lookup<V7>::type_id); break;
685 case 7: is_same = (type_id == Type_Id_Lookup<V8>::type_id); break;
686 default: break;
687 }
688
689 return is_same;
690 }
691
692 //***************************************************************************
695 //***************************************************************************
696 void call(reader& r)
697 {
698 switch (type_id)
699 {
700 case 0: r.read(static_cast<T1&>(data)); break;
701 case 1: r.read(static_cast<T2&>(data)); break;
702 case 2: r.read(static_cast<T3&>(data)); break;
703 case 3: r.read(static_cast<T4&>(data)); break;
704 case 4: r.read(static_cast<T5&>(data)); break;
705 case 5: r.read(static_cast<T6&>(data)); break;
706 case 6: r.read(static_cast<T7&>(data)); break;
707 case 7: r.read(static_cast<T8&>(data)); break;
708 default: break;
709 }
710 }
711
712 //***************************************************************************
715 //***************************************************************************
716 bool is_valid() const
717 {
718 return type_id != UNSUPPORTED_TYPE_ID;
719 }
720
721 //***************************************************************************
724 //***************************************************************************
725 template <typename T>
726 bool is_type() const
727 {
728 return type_id == Type_Id_Lookup<T>::type_id;
729 }
730
731 //***************************************************************************
733 //***************************************************************************
734 size_t index() const
735 {
736 return type_id;
737 }
738
739 //***************************************************************************
741 //***************************************************************************
742 void clear()
743 {
744 destruct_current();
745 }
746
747 //***************************************************************************
751 //***************************************************************************
752 template <typename T>
753 T& get()
754 {
755 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
757
758 return static_cast<T&>(data);
759 }
760
761 //***************************************************************************
765 //***************************************************************************
766 template <typename T>
767 const T& get() const
768 {
769 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
771
772 return static_cast<const T&>(data);
773 }
774
775 //***************************************************************************
778 //***************************************************************************
779 template <typename TBase>
780 TBase* upcast_ptr()
781 {
782 if (is_base_of<TBase>())
783 {
784 return reinterpret_cast<TBase*>(static_cast<uint_least8_t*>(data));
785 }
786 else
787 {
788 return ETL_NULLPTR;
789 }
790 }
791
792 //***************************************************************************
795 //***************************************************************************
796 template <typename TBase>
797 TBase& upcast()
798 {
799 TBase* ptr = upcast_ptr<TBase>();
800
801 ETL_ASSERT(ptr != ETL_NULLPTR, ETL_ERROR(variant_not_a_base_exception));
802
803 return *ptr;
804 }
805
806 //***************************************************************************
809 //***************************************************************************
810 template <typename TBase>
811 const TBase* upcast_ptr() const
812 {
813 if (is_base_of<TBase>())
814 {
815 return reinterpret_cast<const TBase*>(static_cast<const uint_least8_t*>(data));
816 }
817 else
818 {
819 return ETL_NULLPTR;
820 }
821 }
822
823 //***************************************************************************
826 //***************************************************************************
827 template <typename TBase>
828 const TBase& upcast() const
829 {
830 const TBase* ptr = upcast_ptr<TBase>();
831
832 ETL_ASSERT(ptr != ETL_NULLPTR, ETL_ERROR(variant_not_a_base_exception));
833
834 return *ptr;
835 }
836
837 //***************************************************************************
839 //***************************************************************************
840 template <typename TBase>
841 bool is_base_of() const
842 {
843 bool is_base;
844
845 switch (type_id)
846 {
847 case 0: is_base = etl::is_base_of<TBase, T1>::value; break;
848 case 1: is_base = etl::is_base_of<TBase, T2>::value; break;
849 case 2: is_base = etl::is_base_of<TBase, T3>::value; break;
850 case 3: is_base = etl::is_base_of<TBase, T4>::value; break;
851 case 4: is_base = etl::is_base_of<TBase, T5>::value; break;
852 case 5: is_base = etl::is_base_of<TBase, T6>::value; break;
853 case 6: is_base = etl::is_base_of<TBase, T7>::value; break;
854 case 7: is_base = etl::is_base_of<TBase, T8>::value; break;
855 default: is_base = false; break;
856 }
857
858 return is_base;
859 }
860
861 //***************************************************************************
863 //***************************************************************************
864 operator T1& () { return get<T1>(); }
865 operator T2& () { return get<T2>(); }
866 operator T3& () { return get<T3>(); }
867 operator T4& () { return get<T4>(); }
868 operator T5& () { return get<T5>(); }
869 operator T6& () { return get<T6>(); }
870 operator T7& () { return get<T7>(); }
871 operator T8& () { return get<T8>(); }
872
873 //***************************************************************************
876 //***************************************************************************
877 template <typename T>
878 static bool is_supported_type()
879 {
880 return Type_Is_Supported<T>::value;
881 }
882
883 private:
885 //***************************************************************************
887 //***************************************************************************
888 void destruct_current()
889 {
890 switch (type_id)
891 {
892 case 0: { static_cast<T1*>(data)->~T1(); break; }
893 case 1: { static_cast<T2*>(data)->~T2(); break; }
894 case 2: { static_cast<T3*>(data)->~T3(); break; }
895 case 3: { static_cast<T4*>(data)->~T4(); break; }
896 case 4: { static_cast<T5*>(data)->~T5(); break; }
897 case 5: { static_cast<T6*>(data)->~T6(); break; }
898 case 6: { static_cast<T7*>(data)->~T7(); break; }
899 case 7: { static_cast<T8*>(data)->~T8(); break; }
900 default: { break; }
901 }
902
903 type_id = UNSUPPORTED_TYPE_ID;
904 }
905#include "diagnostic_pop.h"
906
907 //***************************************************************************
910 //***************************************************************************
911 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;
912
913 //***************************************************************************
915 //***************************************************************************
916 type_id_t type_id;
917 };
918
919 namespace private_variant
920 {
921 template <size_t, typename>
923#define ETL_VARIANT_HELPER(INDEX, TYPE) \
924 template <typename T1, \
925 typename T2, \
926 typename T3, \
927 typename T4, \
928 typename T5, \
929 typename T6, \
930 typename T7, \
931 typename T8> \
932 struct variant_alternative_helper<INDEX, variant<T1, T2, T3, T4, T5, T6, T7, T8> > \
933 { \
934 typedef TYPE type; \
935 };
936 ETL_VARIANT_HELPER(0, T1)
937 ETL_VARIANT_HELPER(1, T2)
938 ETL_VARIANT_HELPER(2, T3)
939 ETL_VARIANT_HELPER(3, T4)
940 ETL_VARIANT_HELPER(4, T5)
941 ETL_VARIANT_HELPER(5, T6)
942 ETL_VARIANT_HELPER(6, T7)
943 ETL_VARIANT_HELPER(7, T8)
944#undef ETL_VARIANT_HELPER
945 } // namespace private_variant
946
947 template <size_t tIndex, typename TVariant>
952
953 template <size_t tIndex, typename TVariant>
954 struct variant_alternative<tIndex, TVariant const>
955 {
957 };
958
959 template <size_t tIndex, typename TVariant>
960 struct variant_alternative<tIndex, TVariant volatile>
961 {
963 };
964
965 template <size_t tIndex, typename TVariant>
966 struct variant_alternative<tIndex, TVariant const volatile>
967 {
969 };
970
971 template <typename T, typename TVariant>
972 inline T& get(TVariant& variant)
973 {
974 return variant.template get<T>();
975 }
976
977 template <typename T, typename TVariant>
978 inline T const& get(TVariant const& variant)
979 {
980 return variant.template get<T>();
981 }
982
983 template <size_t tIndex, typename TVariant>
984 inline typename variant_alternative<tIndex, TVariant>::type& get(TVariant& variant)
985 {
986 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
987 }
988
989 template <size_t tIndex, typename TVariant>
990 inline typename variant_alternative<tIndex, TVariant const>::type& get(TVariant const& variant)
991 {
992 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
993 }
994
995#define ETL_GEN_LEGACY_VISIT(VISITQUAL, VARIANTQUAL) \
996 template <typename TReturn, typename TVisitor, typename TVariant> \
997 static TReturn visit(TVisitor VISITQUAL visitor, TVariant VARIANTQUAL variant) \
998 { \
999 switch (variant.index()) \
1000 { \
1001 case 0: return static_cast<TReturn>(visitor(get<0>(variant))); \
1002 case 1: return static_cast<TReturn>(visitor(get<1>(variant))); \
1003 case 2: return static_cast<TReturn>(visitor(get<2>(variant))); \
1004 case 3: return static_cast<TReturn>(visitor(get<3>(variant))); \
1005 case 4: return static_cast<TReturn>(visitor(get<4>(variant))); \
1006 case 5: return static_cast<TReturn>(visitor(get<5>(variant))); \
1007 case 6: return static_cast<TReturn>(visitor(get<6>(variant))); \
1008 case 7: return static_cast<TReturn>(visitor(get<7>(variant))); \
1009 default: ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(bad_variant_access), TReturn()); \
1010 } \
1011 }
1012
1013 ETL_GEN_LEGACY_VISIT(&, &)
1014 ETL_GEN_LEGACY_VISIT(const&, &)
1015 ETL_GEN_LEGACY_VISIT(&, const&)
1016 ETL_GEN_LEGACY_VISIT(const&, const&)
1017
1018#undef ETL_GEN_LEGACY_VISIT
1019
1020#if ETL_NOT_USING_LEGACY_VARIANT
1021 }
1022#endif
1023}
Definition null_type.h:40
Definition variant_legacy.h:245
#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
Definition integral_limits.h:516
integral_constant
Definition type_traits_generator.h:895
is_base_of
Definition type_traits_generator.h:1315
is_same
Definition type_traits_generator.h:1104
variant(const T &value)
Definition variant_legacy.h:474
static bool is_supported_type()
Definition variant_legacy.h:878
const T & get() const
Definition variant_legacy.h:767
~variant()
Destructor.
Definition variant_legacy.h:229
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3, const TP4 &value4)
Emplace with four constructor parameters.
Definition variant_legacy.h:599
bool is_same_type(const variant &other) const
Definition variant_legacy.h:661
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3)
Emplace with three constructor parameters.
Definition variant_legacy.h:584
void call(reader &r)
Definition variant_legacy.h:696
T & get()
Definition variant_legacy.h:753
bool is_base_of() const
Definition variant_legacy.h:841
variant(etl::in_place_index_t< Index >, T const &value)
Definition variant_legacy.h:487
uint_least8_t type_id_t
Definition variant_legacy.h:152
bool is_same_type(const variant< V1, V2, V3, V4, V5, V6, V7, V8 > &other) const
Definition variant_legacy.h:672
T & emplace(const TP1 &value1)
Emplace with one constructor parameter.
Definition variant_legacy.h:554
const TBase * upcast_ptr() const
Definition variant_legacy.h:811
reader_type< etl::monostate, value_type, error_type, etl::null_type< 4 >, etl::null_type< 5 >, etl::null_type< 6 >, etl::null_type< 7 >, etl::null_type< 8 > > reader
Definition variant_legacy.h:456
bool is_type() const
Definition variant_legacy.h:726
void clear()
Clears the value to 'no valid stored value'.
Definition variant_legacy.h:742
T & emplace(const TP1 &value1, const TP2 &value2)
Emplace with two constructor parameters.
Definition variant_legacy.h:569
TBase * upcast_ptr()
Definition variant_legacy.h:780
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
TBase & upcast()
Definition variant_legacy.h:797
static const type_id_t UNSUPPORTED_TYPE_ID
Definition variant_legacy.h:157
const TBase & upcast() const
Definition variant_legacy.h:828
bool is_valid() const
Definition variant_legacy.h:716
Definition variant_legacy.h:146
Definition variant_legacy.h:99
Definition variant_legacy.h:124
bitset_ext
Definition absolute.h:39
T & get(array< T, Size > &a)
Definition array.h:1216
Definition utility.h:638
A 'no-value' placeholder.
Definition monostate.h:42
etl::conditional< etl::is_fundamental< T >::value||etl::is_pointer< T >::value, T, constT & >::type type
By default fundamental and pointer types are passed by value.
Definition parameter_type.h:48
Definition variant_legacy.h:71
Definition variant_legacy.h:949