Embedded Template Library  1.0
variant.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2014 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 ******************************************************************************/
30 
31 #ifndef ETL_VARIANT_INCLUDED
32 #define ETL_VARIANT_INCLUDED
33 
34 #include <stdint.h>
35 
36 #include "platform.h"
37 #include "utility.h"
38 #include "array.h"
39 #include "largest.h"
40 #include "exception.h"
41 #include "type_traits.h"
42 #include "integral_limits.h"
43 #include "static_assert.h"
44 #include "alignment.h"
45 #include "error_handler.h"
46 #include "null_type.h"
47 #include "placement_new.h"
48 
49 #if defined(ETL_COMPILER_KEIL)
50  #pragma diag_suppress 940
51  #pragma diag_suppress 111
52 #endif
53 
54 #undef ETL_FILE
55 #define ETL_FILE "24"
56 
57 //*****************************************************************************
61 //*****************************************************************************
62 
63 namespace etl
64 {
65  namespace private_variant
66  {
67  //*************************************************************************
70  //*************************************************************************
71  template <const size_t ID>
72  struct no_type
73  {
74  };
75  }
76 
77  //***************************************************************************
80  //***************************************************************************
82  {
83  public:
84  variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
85  : exception(reason_, file_name_, line_number_)
86  {
87  }
88  };
89 
90  //***************************************************************************
93  //***************************************************************************
95  {
96  public:
97  variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
98  : variant_exception(ETL_ERROR_TEXT("variant: unsupported type", ETL_FILE"A"), file_name_, line_number_)
99  {
100  }
101  };
102 
103  //***************************************************************************
107  //***************************************************************************
108  template <typename T1,
109  typename T2 = etl::null_type<2>,
110  typename T3 = etl::null_type<3>,
111  typename T4 = etl::null_type<4>,
112  typename T5 = etl::null_type<5>,
113  typename T6 = etl::null_type<6>,
114  typename T7 = etl::null_type<7>,
115  typename T8 = etl::null_type<8> >
116  class variant
117  {
118  public:
119 
120  //***************************************************************************
122  //***************************************************************************
123  typedef uint_least8_t type_id_t;
124 
125  //***************************************************************************
127  //***************************************************************************
129 
130  private:
131 
132  // All types of variant are friends.
133  template <typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7, typename U8>
134  friend class variant;
135 
136  //***************************************************************************
138  //***************************************************************************
139  typedef typename largest_type<T1, T2, T3, T4, T5, T6, T7, T8>::type largest_t;
140 
141  //***************************************************************************
143  //***************************************************************************
144  static const size_t SIZE = sizeof(largest_t);
145 
146  //***************************************************************************
148  //***************************************************************************
150 
151  //***************************************************************************
153  //***************************************************************************
154  typedef etl::null_type<2> no_type2;
155  typedef etl::null_type<3> no_type3;
156  typedef etl::null_type<4> no_type4;
157  typedef etl::null_type<5> no_type5;
158  typedef etl::null_type<6> no_type6;
159  typedef etl::null_type<7> no_type7;
160  typedef etl::null_type<8> no_type8;
161 
162  //***************************************************************************
164  //***************************************************************************
165  template <typename T>
166  struct Type_Id_Lookup
167  {
168  static const uint_least8_t type_id = etl::is_same<T, T1>::value ? 0 :
177  };
178 
179  //***************************************************************************
181  //***************************************************************************
182  template <typename T>
183  struct Type_Is_Supported : public integral_constant<bool,
184  is_same<T, T1>::value ||
185  is_same<T, T2>::value ||
186  is_same<T, T3>::value ||
187  is_same<T, T4>::value ||
188  is_same<T, T5>::value ||
189  is_same<T, T6>::value ||
190  is_same<T, T7>::value ||
191  is_same<T, T8>::value>
192  {
193  };
194 
195  public:
196 
197  //***************************************************************************
199  //***************************************************************************
201  {
202  destruct_current();
203  }
204 
205  //*************************************************************************
206  //**** Reader types *******************************************************
207  //*************************************************************************
208 
209  //*************************************************************************
213  //*************************************************************************
214  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>
216  {
217  public:
218 
219  friend class variant;
220 
221  virtual void read(typename etl::parameter_type<R1>::type value) = 0;
222  virtual void read(typename etl::parameter_type<R2>::type value) = 0;
223  virtual void read(typename etl::parameter_type<R3>::type value) = 0;
224  virtual void read(typename etl::parameter_type<R4>::type value) = 0;
225  virtual void read(typename etl::parameter_type<R5>::type value) = 0;
226  virtual void read(typename etl::parameter_type<R6>::type value) = 0;
227  virtual void read(typename etl::parameter_type<R7>::type value) = 0;
228  virtual void read(typename etl::parameter_type<R8>::type value) = 0;
229  };
230 
231  //*************************************************************************
233  //*************************************************************************
234  template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6, typename R7>
235  class reader_type<R1, R2, R3, R4, R5, R6, R7, no_type8>
236  {
237  public:
238 
239  friend class variant;
240 
241  virtual void read(typename etl::parameter_type<R1>::type value) = 0;
242  virtual void read(typename etl::parameter_type<R2>::type value) = 0;
243  virtual void read(typename etl::parameter_type<R3>::type value) = 0;
244  virtual void read(typename etl::parameter_type<R4>::type value) = 0;
245  virtual void read(typename etl::parameter_type<R5>::type value) = 0;
246  virtual void read(typename etl::parameter_type<R6>::type value) = 0;
247  virtual void read(typename etl::parameter_type<R7>::type value) = 0;
248 
249  private:
250 
251  void read(no_type8&) {};
252  };
253 
254  //*************************************************************************
256  //*************************************************************************
257  template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6>
258  class reader_type<R1, R2, R3, R4, R5, R6, no_type7, no_type8>
259  {
260  public:
261 
262  friend class variant;
263 
264  virtual void read(typename etl::parameter_type<R1>::type value) = 0;
265  virtual void read(typename etl::parameter_type<R2>::type value) = 0;
266  virtual void read(typename etl::parameter_type<R3>::type value) = 0;
267  virtual void read(typename etl::parameter_type<R4>::type value) = 0;
268  virtual void read(typename etl::parameter_type<R5>::type value) = 0;
269  virtual void read(typename etl::parameter_type<R6>::type value) = 0;
270 
271  private:
272 
273  void read(no_type7&) {};
274  void read(no_type8&) {};
275  };
276 
277  //*************************************************************************
279  //*************************************************************************
280  template <typename R1, typename R2, typename R3, typename R4, typename R5>
281  class reader_type<R1, R2, R3, R4, R5, no_type6, no_type7, no_type8>
282  {
283  public:
284 
285  friend class variant;
286 
287  virtual void read(typename etl::parameter_type<R1>::type value) = 0;
288  virtual void read(typename etl::parameter_type<R2>::type value) = 0;
289  virtual void read(typename etl::parameter_type<R3>::type value) = 0;
290  virtual void read(typename etl::parameter_type<R4>::type value) = 0;
291  virtual void read(typename etl::parameter_type<R5>::type value) = 0;
292 
293  private:
294 
295  void read(no_type6&) {};
296  void read(no_type7&) {};
297  void read(no_type8&) {};
298  };
299 
300  //*************************************************************************
302  //*************************************************************************
303  template <typename R1, typename R2, typename R3, typename R4>
304  class reader_type<R1, R2, R3, R4, no_type5, no_type6, no_type7, no_type8>
305  {
306  public:
307 
308  friend class variant;
309 
310  virtual void read(typename etl::parameter_type<R1>::type value) = 0;
311  virtual void read(typename etl::parameter_type<R2>::type value) = 0;
312  virtual void read(typename etl::parameter_type<R3>::type value) = 0;
313  virtual void read(typename etl::parameter_type<R4>::type value) = 0;
314 
315  private:
316 
317  void read(no_type5&) {};
318  void read(no_type6&) {};
319  void read(no_type7&) {};
320  void read(no_type8&) {};
321  };
322 
323  //*************************************************************************
325  //*************************************************************************
326  template <typename R1, typename R2, typename R3>
328  {
329  public:
330 
331  friend class variant;
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 
337  private:
338 
339  void read(no_type4&) {};
340  void read(no_type5&) {};
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>
351  {
352  public:
353 
354  friend class variant;
355 
356  virtual void read(typename etl::parameter_type<R1>::type value) = 0;
357  virtual void read(typename etl::parameter_type<R2>::type value) = 0;
358 
359  private:
360 
361  void read(no_type3&) {};
362  void read(no_type4&) {};
363  void read(no_type5&) {};
364  void read(no_type6&) {};
365  void read(no_type7&) {};
366  void read(no_type8&) {};
367  };
368 
369  //*************************************************************************
371  //*************************************************************************
372  template <typename R1>
374  {
375  public:
376 
377  friend class variant;
378 
379  virtual void read(typename etl::parameter_type<R1>::type value) = 0;
380 
381  private:
382 
383  void read(no_type2&) {};
384  void read(no_type3&) {};
385  void read(no_type4&) {};
386  void read(no_type5&) {};
387  void read(no_type6&) {};
388  void read(no_type7&) {};
389  void read(no_type8&) {};
390  };
391 
392  //***************************************************************************
394  //***************************************************************************
396 
397  //***************************************************************************
400  //***************************************************************************
402  : type_id(UNSUPPORTED_TYPE_ID)
403  {
404  }
405 
406  //***************************************************************************
409  //***************************************************************************
410  template <typename T>
411  variant(const T& value)
412  {
413  ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
414 
415  ::new (static_cast<T*>(data)) T(value);
416  type_id = Type_Id_Lookup<T>::type_id;
417  }
418 
419  //***************************************************************************
422  //***************************************************************************
423  variant(const variant& other)
424  {
425  switch (other.type_id)
426  {
427  case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
428  case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
429  case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
430  case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
431  case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
432  case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
433  case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
434  case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
435  default: break;
436  }
437 
438  type_id = other.type_id;
439  }
440 
441 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && !defined(ETL_VARIANT_FORCE_CPP03)
442  //*************************************************************************
444  //*************************************************************************
445  template <typename T, typename... Args>
446  T& emplace(Args&&... args)
447  {
448  ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
449 
450  destruct_current();
451  ::new (static_cast<T*>(data)) T(etl::forward<Args>(args)...);
452  type_id = Type_Id_Lookup<T>::type_id;
453 
454  return *static_cast<T*>(data);
455  }
456 #else
457  //***************************************************************************
459  //***************************************************************************
460  template <typename T, typename TP1>
461  T& emplace(const TP1& value1)
462  {
463  ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
464 
465  destruct_current();
466  ::new (static_cast<T*>(data)) T(value1);
467  type_id = Type_Id_Lookup<T>::type_id;
468 
469  return *static_cast<T*>(data);
470  }
471 
472  //***************************************************************************
474  //***************************************************************************
475  template <typename T, typename TP1, typename TP2>
476  T& emplace(const TP1& value1, const TP2& value2)
477  {
478  ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
479 
480  destruct_current();
481  ::new (static_cast<T*>(data)) T(value1, value2);
482  type_id = Type_Id_Lookup<T>::type_id;
483 
484  return *static_cast<T*>(data);
485  }
486 
487  //***************************************************************************
489  //***************************************************************************
490  template <typename T, typename TP1, typename TP2, typename TP3>
491  T& emplace(const TP1& value1, const TP2& value2, const TP3& value3)
492  {
493  ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
494 
495  destruct_current();
496  ::new (static_cast<T*>(data)) T(value1, value2, value3);
497  type_id = Type_Id_Lookup<T>::type_id;
498 
499  return *static_cast<T*>(data);
500  }
501 
502  //***************************************************************************
504  //***************************************************************************
505  template <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
506  T& emplace(const TP1& value1, const TP2& value2, const TP3& value3, const TP4& value4)
507  {
508  ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
509 
510  destruct_current();
511  ::new (static_cast<T*>(data)) T(value1, value2, value3, value4);
512  type_id = Type_Id_Lookup<T>::type_id;
513 
514  return *static_cast<T*>(data);
515  }
516 #endif
517 
518  //***************************************************************************
521  //***************************************************************************
522  template <typename T>
523  variant& operator =(const T& value)
524  {
525  ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
526 
527  destruct_current();
528  ::new (static_cast<T*>(data)) T(value);
529  type_id = Type_Id_Lookup<T>::type_id;
530 
531  return *this;
532  }
533 
534  //***************************************************************************
537  //***************************************************************************
538  variant& operator =(const variant& other)
539  {
540  if (this != &other)
541  {
542  destruct_current();
543 
544  switch (other.type_id)
545  {
546  case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
547  case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
548  case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
549  case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
550  case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
551  case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
552  case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
553  case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
554  default: break;
555  }
556 
557  type_id = other.type_id;
558  }
559 
560  return *this;
561  }
562 
563  //***************************************************************************
567  //***************************************************************************
568  bool is_same_type(const variant& other) const
569  {
570  return type_id == other.type_id;
571  }
572 
573  //***************************************************************************
577  //***************************************************************************
578  template <typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7, typename U8>
580  {
581  bool is_same = false;
582 
583  switch (other.type_id)
584  {
585  case 0: is_same = (type_id == Type_Id_Lookup<U1>::type_id); break;
586  case 1: is_same = (type_id == Type_Id_Lookup<U2>::type_id); break;
587  case 2: is_same = (type_id == Type_Id_Lookup<U3>::type_id); break;
588  case 3: is_same = (type_id == Type_Id_Lookup<U4>::type_id); break;
589  case 4: is_same = (type_id == Type_Id_Lookup<U5>::type_id); break;
590  case 5: is_same = (type_id == Type_Id_Lookup<U6>::type_id); break;
591  case 6: is_same = (type_id == Type_Id_Lookup<U7>::type_id); break;
592  case 7: is_same = (type_id == Type_Id_Lookup<U8>::type_id); break;
593  default: break;
594  }
595 
596  return is_same;
597  }
598 
599  //***************************************************************************
602  //***************************************************************************
603  void call(reader& r)
604  {
605  switch (type_id)
606  {
607  case 0: r.read(static_cast<T1&>(data)); break;
608  case 1: r.read(static_cast<T2&>(data)); break;
609  case 2: r.read(static_cast<T3&>(data)); break;
610  case 3: r.read(static_cast<T4&>(data)); break;
611  case 4: r.read(static_cast<T5&>(data)); break;
612  case 5: r.read(static_cast<T6&>(data)); break;
613  case 6: r.read(static_cast<T7&>(data)); break;
614  case 7: r.read(static_cast<T8&>(data)); break;
615  default: break;
616  }
617  }
618 
619  //***************************************************************************
622  //***************************************************************************
623  bool is_valid() const
624  {
625  return type_id != UNSUPPORTED_TYPE_ID;
626  }
627 
628  //***************************************************************************
631  //***************************************************************************
632  template <typename T>
633  bool is_type() const
634  {
635  return type_id == Type_Id_Lookup<T>::type_id;
636  }
637 
638  //***************************************************************************
640  //***************************************************************************
641  size_t index() const
642  {
643  return type_id;
644  }
645 
646  //***************************************************************************
648  //***************************************************************************
649  void clear()
650  {
651  destruct_current();
652  }
653 
654  //***************************************************************************
658  //***************************************************************************
659  template <typename T>
660  T& get()
661  {
662  ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
663  ETL_ASSERT(is_type<T>(), ETL_ERROR(variant_incorrect_type_exception));
664 
665  return static_cast<T&>(data);
666  }
667 
668  //***************************************************************************
672  //***************************************************************************
673  template <typename T>
674  const T& get() const
675  {
676  ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
677  ETL_ASSERT(is_type<T>(), ETL_ERROR(variant_incorrect_type_exception));
678 
679  return static_cast<const T&>(data);
680  }
681 
682  //***************************************************************************
685  //***************************************************************************
686  template <typename TBase>
687  TBase& upcast()
688  {
689  return *upcast_functor<TBase, T1, T2, T3, T4, T5, T6, T7, T8>()(data, type_id);
690  }
691 
692  //***************************************************************************
695  //***************************************************************************
696  template <typename TBase>
697  const TBase& upcast() const
698  {
699  return *upcast_functor<TBase, T1, T2, T3, T4, T5, T6, T7, T8>()(data, type_id);
700  }
701 
702  //***************************************************************************
704  //***************************************************************************
705  operator T1&() { return get<T1>(); }
706  operator T2&() { return get<T2>(); }
707  operator T3&() { return get<T3>(); }
708  operator T4&() { return get<T4>(); }
709  operator T5&() { return get<T5>(); }
710  operator T6&() { return get<T6>(); }
711  operator T7&() { return get<T7>(); }
712  operator T8&() { return get<T8>(); }
713 
714  //***************************************************************************
717  //***************************************************************************
718  template <typename T>
719  static bool is_supported_type()
720  {
721  return Type_Is_Supported<T>::value;
722  }
723 
724  private:
725 
726  //***************************************************************************
728  //***************************************************************************
729  void destruct_current()
730  {
731  switch (type_id)
732  {
733  case 0: { static_cast<T1*>(data)->~T1(); break; }
734  case 1: { static_cast<T2*>(data)->~T2(); break; }
735  case 2: { static_cast<T3*>(data)->~T3(); break; }
736  case 3: { static_cast<T4*>(data)->~T4(); break; }
737  case 4: { static_cast<T5*>(data)->~T5(); break; }
738  case 5: { static_cast<T6*>(data)->~T6(); break; }
739  case 6: { static_cast<T7*>(data)->~T7(); break; }
740  case 7: { static_cast<T8*>(data)->~T8(); break; }
741  default: { break; }
742  }
743 
744  type_id = UNSUPPORTED_TYPE_ID;
745  }
746 
747  //*************************************************************************
748  //**** Up-cast functors ***************************************************
749  //*************************************************************************
750 
751  //*************************************************************************
753  //*************************************************************************
754  template <typename TBase, typename U1, typename U2 = no_type2, typename U3 = no_type3, typename U4 = no_type4, typename U5 = no_type5, typename U6 = no_type6, typename U7 = no_type7, typename U8 = no_type8>
755  class upcast_functor
756  {
757  public:
758 
759  TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
760  {
761  switch (typeId)
762  {
763  case 0: return reinterpret_cast<U1*>(p_data);
764  case 1: return reinterpret_cast<U2*>(p_data);
765  case 2: return reinterpret_cast<U3*>(p_data);
766  case 3: return reinterpret_cast<U4*>(p_data);
767  case 4: return reinterpret_cast<U5*>(p_data);
768  case 5: return reinterpret_cast<U6*>(p_data);
769  case 6: return reinterpret_cast<U7*>(p_data);
770  case 7: return reinterpret_cast<U8*>(p_data);
771  default: return reinterpret_cast<TBase*>(0);
772  }
773  }
774 
775  const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId) const
776  {
777  switch (typeId)
778  {
779  case 0: return reinterpret_cast<const U1*>(p_data);
780  case 1: return reinterpret_cast<const U2*>(p_data);
781  case 2: return reinterpret_cast<const U3*>(p_data);
782  case 3: return reinterpret_cast<const U4*>(p_data);
783  case 4: return reinterpret_cast<const U5*>(p_data);
784  case 5: return reinterpret_cast<const U6*>(p_data);
785  case 6: return reinterpret_cast<const U7*>(p_data);
786  case 7: return reinterpret_cast<const U8*>(p_data);
787  default: return reinterpret_cast<TBase*>(0);
788  }
789  }
790  };
791 
792  //*************************************************************************
794  //*************************************************************************
795  template <typename TBase, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7>
796  class upcast_functor<TBase, U1, U2, U3, U4, U5, U6, U7, no_type8>
797  {
798  public:
799 
800  TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
801  {
802  switch (typeId)
803  {
804  case 0: return reinterpret_cast<U1*>(p_data);
805  case 1: return reinterpret_cast<U2*>(p_data);
806  case 2: return reinterpret_cast<U3*>(p_data);
807  case 3: return reinterpret_cast<U4*>(p_data);
808  case 4: return reinterpret_cast<U5*>(p_data);
809  case 5: return reinterpret_cast<U6*>(p_data);
810  case 6: return reinterpret_cast<U7*>(p_data);
811  default: return reinterpret_cast<TBase*>(0);
812  }
813  }
814 
815  const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId) const
816  {
817  switch (typeId)
818  {
819  case 0: return reinterpret_cast<const U1*>(p_data);
820  case 1: return reinterpret_cast<const U2*>(p_data);
821  case 2: return reinterpret_cast<const U3*>(p_data);
822  case 3: return reinterpret_cast<const U4*>(p_data);
823  case 4: return reinterpret_cast<const U5*>(p_data);
824  case 5: return reinterpret_cast<const U6*>(p_data);
825  case 6: return reinterpret_cast<const U7*>(p_data);
826  default: return reinterpret_cast<TBase*>(0);
827  }
828  }
829  };
830 
831  //*************************************************************************
833  //*************************************************************************
834  template <typename TBase, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6>
835  class upcast_functor<TBase, U1, U2, U3, U4, U5, U6, no_type7, no_type8>
836  {
837  public:
838 
839  TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
840  {
841  switch (typeId)
842  {
843  case 0: return reinterpret_cast<U1*>(p_data);
844  case 1: return reinterpret_cast<U2*>(p_data);
845  case 2: return reinterpret_cast<U3*>(p_data);
846  case 3: return reinterpret_cast<U4*>(p_data);
847  case 4: return reinterpret_cast<U5*>(p_data);
848  case 5: return reinterpret_cast<U6*>(p_data);
849  default: return reinterpret_cast<TBase*>(0);
850  }
851  }
852 
853  const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId) const
854  {
855  switch (typeId)
856  {
857  case 0: return reinterpret_cast<const U1*>(p_data);
858  case 1: return reinterpret_cast<const U2*>(p_data);
859  case 2: return reinterpret_cast<const U3*>(p_data);
860  case 3: return reinterpret_cast<const U4*>(p_data);
861  case 4: return reinterpret_cast<const U5*>(p_data);
862  case 5: return reinterpret_cast<const U6*>(p_data);
863  default: return reinterpret_cast<TBase*>(0);
864  }
865  }
866  };
867 
868  //*************************************************************************
870  //*************************************************************************
871  template <typename TBase, typename U1, typename U2, typename U3, typename U4, typename U5>
872  class upcast_functor<TBase, U1, U2, U3, U4, U5, no_type6, no_type7, no_type8>
873  {
874  public:
875 
876  TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
877  {
878  switch (typeId)
879  {
880  case 0: return reinterpret_cast<U1*>(p_data);
881  case 1: return reinterpret_cast<U2*>(p_data);
882  case 2: return reinterpret_cast<U3*>(p_data);
883  case 3: return reinterpret_cast<U4*>(p_data);
884  case 4: return reinterpret_cast<U5*>(p_data);
885  default: return reinterpret_cast<TBase*>(0);
886  }
887  }
888 
889  const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId) const
890  {
891  switch (typeId)
892  {
893  case 0: return reinterpret_cast<const U1*>(p_data);
894  case 1: return reinterpret_cast<const U2*>(p_data);
895  case 2: return reinterpret_cast<const U3*>(p_data);
896  case 3: return reinterpret_cast<const U4*>(p_data);
897  case 4: return reinterpret_cast<const U5*>(p_data);
898  default: return reinterpret_cast<TBase*>(0);
899  }
900  }
901  };
902 
903  //*************************************************************************
905  //*************************************************************************
906  template <typename TBase, typename U1, typename U2, typename U3, typename U4>
907  class upcast_functor<TBase, U1, U2, U3, U4, no_type5, no_type6, no_type7, no_type8>
908  {
909  public:
910 
911  TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
912  {
913  switch (typeId)
914  {
915  case 0: return reinterpret_cast<U1*>(p_data);
916  case 1: return reinterpret_cast<U2*>(p_data);
917  case 2: return reinterpret_cast<U3*>(p_data);
918  case 3: return reinterpret_cast<U4*>(p_data);
919  default: return reinterpret_cast<TBase*>(0);
920  }
921  }
922 
923  const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId) const
924  {
925  switch (typeId)
926  {
927  case 0: return reinterpret_cast<const U1*>(p_data);
928  case 1: return reinterpret_cast<const U2*>(p_data);
929  case 2: return reinterpret_cast<const U3*>(p_data);
930  case 3: return reinterpret_cast<const U4*>(p_data);
931  default: return reinterpret_cast<TBase*>(0);
932  }
933  }
934  };
935 
936  //*************************************************************************
938  //*************************************************************************
939  template <typename TBase, typename U1, typename U2, typename U3>
940  class upcast_functor<TBase, U1, U2, U3, no_type4, no_type5, no_type6, no_type7, no_type8>
941  {
942  public:
943 
944  TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
945  {
946  switch (typeId)
947  {
948  case 0: return reinterpret_cast<U1*>(p_data);
949  case 1: return reinterpret_cast<U2*>(p_data);
950  case 2: return reinterpret_cast<U3*>(p_data);
951  default: return reinterpret_cast<TBase*>(0);
952  }
953  }
954 
955  const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId) const
956  {
957  switch (typeId)
958  {
959  case 0: return reinterpret_cast<const U1*>(p_data);
960  case 1: return reinterpret_cast<const U2*>(p_data);
961  case 2: return reinterpret_cast<const U3*>(p_data);
962  default: return reinterpret_cast<TBase*>(0);
963  }
964  }
965  };
966 
967  //*************************************************************************
969  //*************************************************************************
970  template <typename TBase, typename U1, typename U2>
971  class upcast_functor<TBase, U1, U2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
972  {
973  public:
974 
975  TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
976  {
977  switch (typeId)
978  {
979  case 0: return reinterpret_cast<U1*>(p_data);
980  case 1: return reinterpret_cast<U2*>(p_data);
981  default: return reinterpret_cast<TBase*>(0);
982  }
983  }
984 
985  const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId) const
986  {
987  switch (typeId)
988  {
989  case 0: return reinterpret_cast<const U1*>(p_data);
990  case 1: return reinterpret_cast<const U2&>(p_data);
991  default: return reinterpret_cast<TBase*>(0);
992  }
993  }
994  };
995 
996  //*************************************************************************
998  //*************************************************************************
999  template <typename TBase, typename U1>
1000  class upcast_functor<TBase, U1, no_type2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
1001  {
1002  public:
1003 
1004  TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId)
1005  {
1006  switch (typeId)
1007  {
1008  case 0: return reinterpret_cast<U1*>(p_data);
1009  default: return reinterpret_cast<TBase*>(0);
1010  }
1011  }
1012 
1013  const TBase* operator()(uint_least8_t* p_data, uint_least8_t typeId) const
1014  {
1015  switch (typeId)
1016  {
1017  case 0: return reinterpret_cast<const U1*>(p_data);
1018  default: return reinterpret_cast<TBase*>(0);
1019  }
1020  }
1021  };
1022 
1023  //***************************************************************************
1026  //***************************************************************************
1028 
1029  //***************************************************************************
1031  //***************************************************************************
1032  type_id_t type_id;
1033  };
1034 }
1035 
1036 #undef ETL_FILE
1037 
1038 #endif
Definition: constant.h:45
Definition: null_type.h:39
Definition: variant.h:216
#define ETL_ASSERT(b, e)
Definition: error_handler.h:290
exception(string_type reason_, string_type file_, numeric_type line_)
Constructor.
Definition: exception.h:67
Definition: exception.h:47
Definition: integral_limits.h:54
Definition: largest.h:227
integral_constant
Definition: type_traits_generator.h:800
is_same
Definition: type_traits_generator.h:981
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3, const TP4 &value4)
Emplace with four constructor parameters.
Definition: variant.h:506
variant(const T &value)
Definition: variant.h:411
bool is_same_type(const variant< U1, U2, U3, U4, U5, U6, U7, U8 > &other) const
Definition: variant.h:579
static bool is_supported_type()
Definition: variant.h:719
T & get()
Definition: variant.h:660
~variant()
Destructor.
Definition: variant.h:200
variant()
Definition: variant.h:401
bool is_same_type(const variant &other) const
Definition: variant.h:568
const T & get() const
Definition: variant.h:674
void call(reader &r)
Definition: variant.h:603
uint_least8_t type_id_t
The type used for ids.
Definition: variant.h:123
reader_type< T1, T2, T3, T4, T5, T6, T7, T8 > reader
The base type for derived readers.
Definition: variant.h:395
bool is_type() const
Definition: variant.h:633
void clear()
Clears the value to 'no valid stored value'.
Definition: variant.h:649
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3)
Emplace with three constructor parameters.
Definition: variant.h:491
variant & operator=(const T &value)
Definition: variant.h:523
size_t index() const
Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID.
Definition: variant.h:641
static const type_id_t UNSUPPORTED_TYPE_ID
The id a unsupported types.
Definition: variant.h:128
TBase & upcast()
Definition: variant.h:687
T & emplace(const TP1 &value1)
Emplace with one constructor parameter.
Definition: variant.h:461
const TBase & upcast() const
Definition: variant.h:697
T & emplace(const TP1 &value1, const TP2 &value2)
Emplace with two constructor parameters.
Definition: variant.h:476
variant(const variant &other)
Definition: variant.h:423
bool is_valid() const
Definition: variant.h:623
Definition: variant.h:117
Definition: variant.h:82
Definition: absolute.h:37
Definition: alignment.h:118
Definition: variant.h:73