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 "../alignment.h"
33#include "../error_handler.h"
34#include "../exception.h"
35#include "../integral_limits.h"
36#include "../largest.h"
37#include "../monostate.h"
38#include "../null_type.h"
39#include "../parameter_type.h"
40#include "../placement_new.h"
41#include "../static_assert.h"
42#include "../type_traits.h"
43#include "../utility.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//*****************************************************************************
57//*****************************************************************************
58namespace etl
59{
60#if ETL_NOT_USING_LEGACY_VARIANT
61 namespace legacy
62 {
63#endif
64 namespace private_variant
65 {
66 //*************************************************************************
69 //*************************************************************************
70 template <size_t Id>
71 struct no_type
72 {
73 };
74 } // namespace private_variant
75
76 //***************************************************************************
79 //***************************************************************************
81
82 //***************************************************************************
85 //***************************************************************************
86 class variant_exception : public etl::exception
87 {
88 public:
89
90 variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
91 : exception(reason_, file_name_, line_number_)
92 {
93 }
94 };
95
96 //***************************************************************************
99 //***************************************************************************
100 class variant_incorrect_type_exception : public variant_exception
101 {
102 public:
103
104 variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
105 : variant_exception(ETL_ERROR_TEXT("variant:unsupported type", ETL_VARIANT_FILE_ID"A"), file_name_, line_number_)
106 {
107 }
108 };
109
110 //***************************************************************************
113 //***************************************************************************
114 class bad_variant_access : public variant_exception
115 {
116 public:
117
118 bad_variant_access(string_type file_name_, numeric_type line_number_)
119 : variant_exception(ETL_ERROR_TEXT("variant:bad variant access", ETL_VARIANT_FILE_ID"B"), file_name_, line_number_)
120 {
121 }
122 };
123
124 //***************************************************************************
127 //***************************************************************************
128 class variant_not_a_base_exception : public variant_exception
129 {
130 public:
131
132 variant_not_a_base_exception(string_type file_name_, numeric_type line_number_)
133 : variant_exception(ETL_ERROR_TEXT("variant:not_a base", ETL_VARIANT_FILE_ID"C"), file_name_, line_number_)
134 {
135 }
136 };
137
138 //***************************************************************************
142 //***************************************************************************
143 template <typename T1, typename T2 = etl::null_type<2>, typename T3 = etl::null_type<3>, typename T4 = etl::null_type<4>,
144 typename T5 = etl::null_type<5>, typename T6 = etl::null_type<6>, typename T7 = etl::null_type<7>, 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
198 : etl::is_same<T, T2>::value ? 1
199 : etl::is_same<T, T3>::value ? 2
200 : etl::is_same<T, T4>::value ? 3
201 : etl::is_same<T, T5>::value ? 4
202 : etl::is_same<T, T6>::value ? 5
203 : etl::is_same<T, T7>::value ? 6
204 : etl::is_same<T, T8>::value ? 7
206 };
207
208 //***************************************************************************
210 //***************************************************************************
211 template <typename T>
212 struct Type_Is_Supported
213 : public etl::integral_constant< bool, etl::is_same<T, T1>::value || etl::is_same<T, T2>::value || etl::is_same<T, T3>::value
214 || etl::is_same<T, T4>::value || etl::is_same<T, T5>::value || etl::is_same<T, T6>::value
215 || etl::is_same<T, T7>::value || etl::is_same<T, T8>::value>
216 {
217 };
218
219 public:
220
221 //***************************************************************************
223 //***************************************************************************
225 {
226 destruct_current();
227 }
228
229 //*************************************************************************
230 //**** Reader types
231 //*******************************************************
232 //*************************************************************************
233
234 //*************************************************************************
238 //*************************************************************************
239 template <typename R1, typename R2 = no_type2, typename R3 = no_type3, typename R4 = no_type4, typename R5 = no_type5, typename R6 = no_type6,
240 typename R7 = no_type7, typename R8 = no_type8>
242 {
243 public:
244
245 friend class variant;
246
247 virtual ~reader_type() {}
248
249 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
250 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
251 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
252 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
253 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
254 virtual void read(typename etl::parameter_type<R6>::type value) = 0;
255 virtual void read(typename etl::parameter_type<R7>::type value) = 0;
256 virtual void read(typename etl::parameter_type<R8>::type value) = 0;
257 };
258
259 //*************************************************************************
261 //*************************************************************************
262 template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6, typename R7>
263 class reader_type<R1, R2, R3, R4, R5, R6, R7, no_type8>
264 {
265 public:
266
267 friend class variant;
268
269 virtual ~reader_type() {}
270
271 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
272 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
273 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
274 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
275 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
276 virtual void read(typename etl::parameter_type<R6>::type value) = 0;
277 virtual void read(typename etl::parameter_type<R7>::type value) = 0;
278
279 private:
280
281 void read(no_type8&) {}
282 };
283
284 //*************************************************************************
286 //*************************************************************************
287 template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6>
288 class reader_type<R1, R2, R3, R4, R5, R6, no_type7, no_type8>
289 {
290 public:
291
292 friend class variant;
293
294 virtual ~reader_type() {}
295
296 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
297 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
298 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
299 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
300 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
301 virtual void read(typename etl::parameter_type<R6>::type value) = 0;
302
303 private:
304
305 void read(no_type7&) {}
306 void read(no_type8&) {}
307 };
308
309 //*************************************************************************
311 //*************************************************************************
312 template <typename R1, typename R2, typename R3, typename R4, typename R5>
313 class reader_type<R1, R2, R3, R4, R5, no_type6, no_type7, no_type8>
314 {
315 public:
316
317 friend class variant;
318
319 virtual ~reader_type() {}
320
321 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
322 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
323 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
324 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
325 virtual void read(typename etl::parameter_type<R5>::type value) = 0;
326
327 private:
328
329 void read(no_type6&) {}
330 void read(no_type7&) {}
331 void read(no_type8&) {}
332 };
333
334 //*************************************************************************
336 //*************************************************************************
337 template <typename R1, typename R2, typename R3, typename R4>
338 class reader_type<R1, R2, R3, R4, no_type5, no_type6, no_type7, no_type8>
339 {
340 public:
341
342 friend class variant;
343
344 virtual ~reader_type() {}
345
346 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
347 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
348 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
349 virtual void read(typename etl::parameter_type<R4>::type value) = 0;
350
351 private:
352
353 void read(no_type5&) {}
354 void read(no_type6&) {}
355 void read(no_type7&) {}
356 void read(no_type8&) {}
357 };
358
359 //*************************************************************************
361 //*************************************************************************
362 template <typename R1, typename R2, typename R3>
363 class reader_type<R1, R2, R3, no_type4, no_type5, no_type6, no_type7, no_type8>
364 {
365 public:
366
367 friend class variant;
368
369 virtual ~reader_type() {}
370
371 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
372 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
373 virtual void read(typename etl::parameter_type<R3>::type value) = 0;
374
375 private:
376
377 void read(no_type4&) {}
378 void read(no_type5&) {}
379 void read(no_type6&) {}
380 void read(no_type7&) {}
381 void read(no_type8&) {}
382 };
383
384 //*************************************************************************
386 //*************************************************************************
387 template <typename R1, typename R2>
388 class reader_type<R1, R2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
389 {
390 public:
391
392 friend class variant;
393
394 virtual ~reader_type() {}
395
396 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
397 virtual void read(typename etl::parameter_type<R2>::type value) = 0;
398
399 private:
400
401 void read(no_type3&) {}
402 void read(no_type4&) {}
403 void read(no_type5&) {}
404 void read(no_type6&) {}
405 void read(no_type7&) {}
406 void read(no_type8&) {}
407 };
408
409 //*************************************************************************
411 //*************************************************************************
412 template <typename R1>
413 class reader_type<R1, no_type2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
414 {
415 public:
416
417 friend class variant;
418
419 virtual ~reader_type() {}
420
421 virtual void read(typename etl::parameter_type<R1>::type value) = 0;
422
423 private:
424
425 void read(no_type2&) {}
426 void read(no_type3&) {}
427 void read(no_type4&) {}
428 void read(no_type5&) {}
429 void read(no_type6&) {}
430 void read(no_type7&) {}
431 void read(no_type8&) {}
432 };
433
434 //***************************************************************************
436 //***************************************************************************
437 typedef reader_type<T1, T2, T3, T4, T5, T6, T7, T8> reader;
438
439 //***************************************************************************
442 //***************************************************************************
444 variant()
445 : type_id(UNSUPPORTED_TYPE_ID)
446 {
447 }
448#include "diagnostic_pop.h"
449
450 //***************************************************************************
453 //***************************************************************************
454 template <typename T>
455 variant(const T& value)
456 {
457 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
458
459 ::new (static_cast<T*>(data)) T(value);
460 type_id = Type_Id_Lookup<T>::type_id;
461 }
462
463 //***************************************************************************
466 //***************************************************************************
467 template <size_t Index, typename T>
468 explicit variant(etl::in_place_index_t<Index>, T const& value)
469 : type_id(Index)
470 {
471 ETL_STATIC_ASSERT(Type_Id_Lookup<T>::type_id == Index, "Missmatched type");
472 ::new (static_cast<T*>(data)) T(value);
473 type_id = Index;
474 }
475
476 //***************************************************************************
479 //***************************************************************************
481 variant(const variant& other)
482 {
483 switch (other.type_id)
484 {
485 case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
486 case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
487 case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
488 case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
489 case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
490 case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
491 case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
492 case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
493 default: break;
494 }
495
496 type_id = other.type_id;
497 }
498#include "diagnostic_pop.h"
499
500#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VARIANT_FORCE_CPP03_IMPLEMENTATION)
501 //*************************************************************************
503 //*************************************************************************
504 template <typename T, typename... Args>
505 T& emplace(Args&&... args)
506 {
507 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
508
509 destruct_current();
510 ::new (static_cast<T*>(data)) T(etl::forward<Args>(args)...);
511 type_id = Type_Id_Lookup<T>::type_id;
512
513 return *static_cast<T*>(data);
514 }
515#else
516 //***************************************************************************
518 //***************************************************************************
519 template <typename T>
521 {
522 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
523
524 destruct_current();
525 ::new (static_cast<T*>(data)) T();
526 type_id = Type_Id_Lookup<T>::type_id;
527
528 return *static_cast<T*>(data);
529 }
530
531 //***************************************************************************
533 //***************************************************************************
534 template <typename T, typename TP1>
535 T& emplace(const TP1& value1)
536 {
537 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
538
539 destruct_current();
540 ::new (static_cast<T*>(data)) T(value1);
541 type_id = Type_Id_Lookup<T>::type_id;
542
543 return *static_cast<T*>(data);
544 }
545
546 //***************************************************************************
548 //***************************************************************************
549 template <typename T, typename TP1, typename TP2>
550 T& emplace(const TP1& value1, const TP2& value2)
551 {
552 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
553
554 destruct_current();
555 ::new (static_cast<T*>(data)) T(value1, value2);
556 type_id = Type_Id_Lookup<T>::type_id;
557
558 return *static_cast<T*>(data);
559 }
560
561 //***************************************************************************
563 //***************************************************************************
564 template <typename T, typename TP1, typename TP2, typename TP3>
565 T& emplace(const TP1& value1, const TP2& value2, const TP3& value3)
566 {
567 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
568
569 destruct_current();
570 ::new (static_cast<T*>(data)) T(value1, value2, value3);
571 type_id = Type_Id_Lookup<T>::type_id;
572
573 return *static_cast<T*>(data);
574 }
575
576 //***************************************************************************
578 //***************************************************************************
579 template <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
580 T& emplace(const TP1& value1, const TP2& value2, const TP3& value3, const TP4& value4)
581 {
582 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
583
584 destruct_current();
585 ::new (static_cast<T*>(data)) T(value1, value2, value3, value4);
586 type_id = Type_Id_Lookup<T>::type_id;
587
588 return *static_cast<T*>(data);
589 }
590#endif
591
592 //***************************************************************************
595 //***************************************************************************
596 template <typename T>
597 variant& operator=(const T& value)
598 {
599 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
600
601 destruct_current();
602 ::new (static_cast<T*>(data)) T(value);
603 type_id = Type_Id_Lookup<T>::type_id;
604
605 return *this;
606 }
607
608 //***************************************************************************
611 //***************************************************************************
612 variant& operator=(const variant& other)
613 {
614 if (this != &other)
615 {
616 destruct_current();
617
618 switch (other.type_id)
619 {
620 case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
621 case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
622 case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
623 case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
624 case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
625 case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
626 case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
627 case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
628 default: break;
629 }
630
631 type_id = other.type_id;
632 }
633
634 return *this;
635 }
636
637 //***************************************************************************
641 //***************************************************************************
642 bool is_same_type(const variant& other) const
643 {
644 return type_id == other.type_id;
645 }
646
647 //***************************************************************************
651 //***************************************************************************
652 template <typename V1, typename V2, typename V3, typename V4, typename V5, typename V6, typename V7, typename V8>
653 bool is_same_type(const variant<V1, V2, V3, V4, V5, V6, V7, V8>& other) const
654 {
655 bool is_same = false;
656
657 switch (other.type_id)
658 {
659 case 0: is_same = (type_id == Type_Id_Lookup<V1>::type_id); break;
660 case 1: is_same = (type_id == Type_Id_Lookup<V2>::type_id); break;
661 case 2: is_same = (type_id == Type_Id_Lookup<V3>::type_id); break;
662 case 3: is_same = (type_id == Type_Id_Lookup<V4>::type_id); break;
663 case 4: is_same = (type_id == Type_Id_Lookup<V5>::type_id); break;
664 case 5: is_same = (type_id == Type_Id_Lookup<V6>::type_id); break;
665 case 6: is_same = (type_id == Type_Id_Lookup<V7>::type_id); break;
666 case 7: is_same = (type_id == Type_Id_Lookup<V8>::type_id); break;
667 default: break;
668 }
669
670 return is_same;
671 }
672
673 //***************************************************************************
677 //***************************************************************************
678 void call(reader& r)
679 {
680 switch (type_id)
681 {
682 case 0: r.read(static_cast<T1&>(data)); break;
683 case 1: r.read(static_cast<T2&>(data)); break;
684 case 2: r.read(static_cast<T3&>(data)); break;
685 case 3: r.read(static_cast<T4&>(data)); break;
686 case 4: r.read(static_cast<T5&>(data)); break;
687 case 5: r.read(static_cast<T6&>(data)); break;
688 case 6: r.read(static_cast<T7&>(data)); break;
689 case 7: r.read(static_cast<T8&>(data)); break;
690 default: break;
691 }
692 }
693
694 //***************************************************************************
697 //***************************************************************************
698 bool is_valid() const
699 {
700 return type_id != UNSUPPORTED_TYPE_ID;
701 }
702
703 //***************************************************************************
708 //***************************************************************************
709 template <typename T>
710 bool is_type() const
711 {
712 return type_id == Type_Id_Lookup<T>::type_id;
713 }
714
715 //***************************************************************************
717 //***************************************************************************
718 size_t index() const
719 {
720 return type_id;
721 }
722
723 //***************************************************************************
725 //***************************************************************************
726 void clear()
727 {
728 destruct_current();
729 }
730
731 //***************************************************************************
736 //***************************************************************************
737 template <typename T>
738 T& get()
739 {
740 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
742
743 return static_cast<T&>(data);
744 }
745
746 //***************************************************************************
751 //***************************************************************************
752 template <typename T>
753 const T& get() const
754 {
755 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
757
758 return static_cast<const T&>(data);
759 }
760
761 //***************************************************************************
764 //***************************************************************************
765 template <typename TBase>
766 TBase* upcast_ptr()
767 {
768 if (is_base_of<TBase>())
769 {
770 return reinterpret_cast<TBase*>(static_cast<uint_least8_t*>(data));
771 }
772 else
773 {
774 return ETL_NULLPTR;
775 }
776 }
777
778 //***************************************************************************
781 //***************************************************************************
782 template <typename TBase>
783 TBase& upcast()
784 {
785 TBase* ptr = upcast_ptr<TBase>();
786
787 ETL_ASSERT(ptr != ETL_NULLPTR, ETL_ERROR(variant_not_a_base_exception));
788
789 return *ptr;
790 }
791
792 //***************************************************************************
795 //***************************************************************************
796 template <typename TBase>
797 const TBase* upcast_ptr() const
798 {
799 if (is_base_of<TBase>())
800 {
801 return reinterpret_cast<const TBase*>(static_cast<const uint_least8_t*>(data));
802 }
803 else
804 {
805 return ETL_NULLPTR;
806 }
807 }
808
809 //***************************************************************************
812 //***************************************************************************
813 template <typename TBase>
814 const TBase& upcast() const
815 {
816 const TBase* ptr = upcast_ptr<TBase>();
817
818 ETL_ASSERT(ptr != ETL_NULLPTR, ETL_ERROR(variant_not_a_base_exception));
819
820 return *ptr;
821 }
822
823 //***************************************************************************
825 //***************************************************************************
826 template <typename TBase>
827 bool is_base_of() const
828 {
829 bool is_base;
830
831 switch (type_id)
832 {
833 case 0: is_base = etl::is_base_of<TBase, T1>::value; break;
834 case 1: is_base = etl::is_base_of<TBase, T2>::value; break;
835 case 2: is_base = etl::is_base_of<TBase, T3>::value; break;
836 case 3: is_base = etl::is_base_of<TBase, T4>::value; break;
837 case 4: is_base = etl::is_base_of<TBase, T5>::value; break;
838 case 5: is_base = etl::is_base_of<TBase, T6>::value; break;
839 case 6: is_base = etl::is_base_of<TBase, T7>::value; break;
840 case 7: is_base = etl::is_base_of<TBase, T8>::value; break;
841 default: is_base = false; break;
842 }
843
844 return is_base;
845 }
846
847 //***************************************************************************
849 //***************************************************************************
850 operator T1&()
851 {
852 return get<T1>();
853 }
854 operator T2&()
855 {
856 return get<T2>();
857 }
858 operator T3&()
859 {
860 return get<T3>();
861 }
862 operator T4&()
863 {
864 return get<T4>();
865 }
866 operator T5&()
867 {
868 return get<T5>();
869 }
870 operator T6&()
871 {
872 return get<T6>();
873 }
874 operator T7&()
875 {
876 return get<T7>();
877 }
878 operator T8&()
879 {
880 return get<T8>();
881 }
882
883 //***************************************************************************
887 //***************************************************************************
888 template <typename T>
889 static bool is_supported_type()
890 {
891 return Type_Is_Supported<T>::value;
892 }
893
894 private:
895
897 //***************************************************************************
899 //***************************************************************************
900 void destruct_current()
901 {
902 switch (type_id)
903 {
904 case 0:
905 {
906 static_cast<T1*>(data)->~T1();
907 break;
908 }
909 case 1:
910 {
911 static_cast<T2*>(data)->~T2();
912 break;
913 }
914 case 2:
915 {
916 static_cast<T3*>(data)->~T3();
917 break;
918 }
919 case 3:
920 {
921 static_cast<T4*>(data)->~T4();
922 break;
923 }
924 case 4:
925 {
926 static_cast<T5*>(data)->~T5();
927 break;
928 }
929 case 5:
930 {
931 static_cast<T6*>(data)->~T6();
932 break;
933 }
934 case 6:
935 {
936 static_cast<T7*>(data)->~T7();
937 break;
938 }
939 case 7:
940 {
941 static_cast<T8*>(data)->~T8();
942 break;
943 }
944 default:
945 {
946 break;
947 }
948 }
949
950 type_id = UNSUPPORTED_TYPE_ID;
951 }
952#include "diagnostic_pop.h"
953
954 //***************************************************************************
957 //***************************************************************************
958 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;
959
960 //***************************************************************************
962 //***************************************************************************
963 type_id_t type_id;
964 };
965
966 namespace private_variant
967 {
968 template <size_t, typename>
970#define ETL_VARIANT_HELPER(INDEX, TYPE) \
971 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> \
972 struct variant_alternative_helper<INDEX, variant<T1, T2, T3, T4, T5, T6, T7, T8> > \
973 { \
974 typedef TYPE type; \
975 };
976 ETL_VARIANT_HELPER(0, T1)
977 ETL_VARIANT_HELPER(1, T2)
978 ETL_VARIANT_HELPER(2, T3)
979 ETL_VARIANT_HELPER(3, T4)
980 ETL_VARIANT_HELPER(4, T5)
981 ETL_VARIANT_HELPER(5, T6)
982 ETL_VARIANT_HELPER(6, T7)
983 ETL_VARIANT_HELPER(7, T8)
984#undef ETL_VARIANT_HELPER
985 } // namespace private_variant
986
987 template <size_t tIndex, typename TVariant>
992
993 template <size_t tIndex, typename TVariant>
994 struct variant_alternative<tIndex, TVariant const>
995 {
997 };
998
999 template <size_t tIndex, typename TVariant>
1000 struct variant_alternative<tIndex, TVariant volatile>
1001 {
1003 };
1004
1005 template <size_t tIndex, typename TVariant>
1006 struct variant_alternative<tIndex, TVariant const volatile>
1007 {
1009 };
1010
1011 template <typename T, typename TVariant>
1012 inline T& get(TVariant& variant)
1013 {
1014 return variant.template get<T>();
1015 }
1016
1017 template <typename T, typename TVariant>
1018 inline T const& get(TVariant const& variant)
1019 {
1020 return variant.template get<T>();
1021 }
1022
1023 template <size_t tIndex, typename TVariant>
1024 inline typename variant_alternative<tIndex, TVariant>::type& get(TVariant& variant)
1025 {
1026 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
1027 }
1028
1029 template <size_t tIndex, typename TVariant>
1030 inline typename variant_alternative<tIndex, TVariant const>::type& get(TVariant const& variant)
1031 {
1032 return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
1033 }
1034
1035#define ETL_GEN_LEGACY_VISIT(VISITQUAL, VARIANTQUAL) \
1036 template <typename TReturn, typename TVisitor, typename TVariant> \
1037 static TReturn visit(TVisitor VISITQUAL visitor, TVariant VARIANTQUAL variant) \
1038 { \
1039 switch (variant.index()) \
1040 { \
1041 case 0: return static_cast<TReturn>(visitor(get<0>(variant))); \
1042 case 1: return static_cast<TReturn>(visitor(get<1>(variant))); \
1043 case 2: return static_cast<TReturn>(visitor(get<2>(variant))); \
1044 case 3: return static_cast<TReturn>(visitor(get<3>(variant))); \
1045 case 4: return static_cast<TReturn>(visitor(get<4>(variant))); \
1046 case 5: return static_cast<TReturn>(visitor(get<5>(variant))); \
1047 case 6: return static_cast<TReturn>(visitor(get<6>(variant))); \
1048 case 7: return static_cast<TReturn>(visitor(get<7>(variant))); \
1049 default: ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(bad_variant_access), TReturn()); \
1050 } \
1051 }
1052
1053 ETL_GEN_LEGACY_VISIT(&, &)
1054 ETL_GEN_LEGACY_VISIT(const&, &)
1055 ETL_GEN_LEGACY_VISIT(&, const&)
1056 ETL_GEN_LEGACY_VISIT(const&, const&)
1057
1058#undef ETL_GEN_LEGACY_VISIT
1059
1060#if ETL_NOT_USING_LEGACY_VARIANT
1061 }
1062#endif
1063} // namespace etl
Definition null_type.h:40
Definition variant_legacy.h:242
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
Definition exception.h:59
Definition integral_limits.h:518
variant(const T &value)
Definition variant_legacy.h:455
static bool is_supported_type()
Definition variant_legacy.h:889
const T & get() const
Definition variant_legacy.h:753
~variant()
Destructor.
Definition variant_legacy.h:224
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3, const TP4 &value4)
Emplace with four constructor parameters.
Definition variant_legacy.h:580
bool is_same_type(const variant &other) const
Definition variant_legacy.h:642
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3)
Emplace with three constructor parameters.
Definition variant_legacy.h:565
void call(reader &r)
Definition variant_legacy.h:678
T & get()
Definition variant_legacy.h:738
bool is_base_of() const
Definition variant_legacy.h:827
variant(etl::in_place_index_t< Index >, T const &value)
Definition variant_legacy.h:468
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:653
variant & operator=(const T &value)
Definition variant_legacy.h:597
variant & operator=(const variant &other)
Definition variant_legacy.h:612
T & emplace(const TP1 &value1)
Emplace with one constructor parameter.
Definition variant_legacy.h:535
const TBase * upcast_ptr() const
Definition variant_legacy.h:797
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:437
bool is_type() const
Definition variant_legacy.h:710
void clear()
Clears the value to 'no valid stored value'.
Definition variant_legacy.h:726
T & emplace(const TP1 &value1, const TP2 &value2)
Emplace with two constructor parameters.
Definition variant_legacy.h:550
TBase * upcast_ptr()
Definition variant_legacy.h:766
T & emplace()
Emplace with one constructor parameter.
Definition variant_legacy.h:520
size_t index() const
Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID.
Definition variant_legacy.h:718
TBase & upcast()
Definition variant_legacy.h:783
static const type_id_t UNSUPPORTED_TYPE_ID
Definition variant_legacy.h:157
const TBase & upcast() const
Definition variant_legacy.h:814
bool is_valid() const
Definition variant_legacy.h:698
Definition variant_legacy.h:146
Definition variant_legacy.h:101
Definition variant_legacy.h:129
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1228
T & get(array< T, Size > &a)
Definition array.h:1161
Definition utility.h:950
integral_constant
Definition type_traits.h:67
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:46
Definition variant_legacy.h:72
Definition variant_legacy.h:989