31 #ifndef ETL_VARIANT_NEW_INCLUDED
32 #define ETL_VARIANT_NEW_INCLUDED
36 #include "private/new.h"
45 #include "static_assert.h"
48 #include "null_type.h"
50 #if defined(ETL_COMPILER_KEIL)
51 #pragma diag_suppress 940
52 #pragma diag_suppress 111
58 #if ETL_CPP11_SUPPORTED
72 class variant_exception :
public exception
75 variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
76 :
exception(reason_, file_name_, line_number_)
85 class variant_incorrect_type_exception :
public variant_exception
88 variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
89 : variant_exception(ETL_ERROR_TEXT(
"variant: unsupported type", ETL_FILE
"A"), file_name_, line_number_)
99 template <
typename... TVariants>
107 static ETL_CONST_OR_CONSTEXPR
size_t npos = -1;
112 template <
typename... U>
113 friend class variant;
118 typedef typename largest_type<TVariants...>::type largest_t;
123 static const size_t SIZE =
sizeof(largest_t);
153 template <
typename T>
154 variant(
const T& value)
156 ETL_STATIC_ASSERT(etl::index_of<T, TVariants>::value != etl::index_of<T, TVariants>::npos,
"Unsupported type");
158 ::new (
static_cast<T*
>(data)) T(value);
159 type_id = etl::index_of<T, TVariants>::value;
166 variant(
const variant& other)
168 switch (other.type_id)
170 case 0: ::new (
static_cast<T1*
>(data)) T1(other.get<T1>());
break;
171 case 1: ::new (
static_cast<T2*
>(data)) T2(other.get<T2>());
break;
172 case 2: ::new (
static_cast<T3*
>(data)) T3(other.get<T3>());
break;
173 case 3: ::new (
static_cast<T4*
>(data)) T4(other.get<T4>());
break;
174 case 4: ::new (
static_cast<T5*
>(data)) T5(other.get<T5>());
break;
175 case 5: ::new (
static_cast<T6*
>(data)) T6(other.get<T6>());
break;
176 case 6: ::new (
static_cast<T7*
>(data)) T7(other.get<T7>());
break;
177 case 7: ::new (
static_cast<T8*
>(data)) T8(other.get<T8>());
break;
181 type_id = other.type_id;
184 #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && !defined(ETL_VARIANT_FORCE_CPP03)
188 template <
typename T,
typename... Args>
191 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
194 ::new (
static_cast<T*
>(data)) T(etl::forward<Args>(args)...);
195 type_id = Type_Id_Lookup<T>::type_id;
197 return *
static_cast<T*
>(data);
203 template <
typename T,
typename TP1>
206 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
209 ::new (
static_cast<T*
>(data)) T(value1);
210 type_id = Type_Id_Lookup<T>::type_id;
212 return *
static_cast<T*
>(data);
218 template <
typename T,
typename TP1,
typename TP2>
219 T&
emplace(
const TP1& value1,
const TP2& value2)
221 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
224 ::new (
static_cast<T*
>(data)) T(value1, value2);
225 type_id = Type_Id_Lookup<T>::type_id;
227 return *
static_cast<T*
>(data);
233 template <
typename T,
typename TP1,
typename TP2,
typename TP3>
234 T&
emplace(
const TP1& value1,
const TP2& value2,
const TP3& value3)
236 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
239 ::new (
static_cast<T*
>(data)) T(value1, value2, value3);
240 type_id = Type_Id_Lookup<T>::type_id;
242 return *
static_cast<T*
>(data);
248 template <
typename T,
typename TP1,
typename TP2,
typename TP3,
typename TP4>
249 T&
emplace(
const TP1& value1,
const TP2& value2,
const TP3& value3,
const TP4& value4)
251 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
254 ::new (
static_cast<T*
>(data)) T(value1, value2, value3, value4);
255 type_id = Type_Id_Lookup<T>::type_id;
257 return *
static_cast<T*
>(data);
265 template <
typename T>
268 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
271 ::new (
static_cast<T*
>(data)) T(value);
272 type_id = Type_Id_Lookup<T>::type_id;
287 switch (other.type_id)
289 case 0: ::new (
static_cast<T1*
>(data)) T1(other.get<T1>());
break;
290 case 1: ::new (
static_cast<T2*
>(data)) T2(other.get<T2>());
break;
291 case 2: ::new (
static_cast<T3*
>(data)) T3(other.get<T3>());
break;
292 case 3: ::new (
static_cast<T4*
>(data)) T4(other.get<T4>());
break;
293 case 4: ::new (
static_cast<T5*
>(data)) T5(other.get<T5>());
break;
294 case 5: ::new (
static_cast<T6*
>(data)) T6(other.get<T6>());
break;
295 case 6: ::new (
static_cast<T7*
>(data)) T7(other.get<T7>());
break;
296 case 7: ::new (
static_cast<T8*
>(data)) T8(other.get<T8>());
break;
300 type_id = other.type_id;
313 return type_id == other.type_id;
321 template <
typename U1,
typename U2,
typename U3,
typename U4,
typename U5,
typename U6,
typename U7,
typename U8>
322 bool is_same_type(
const variant<U1, U2, U3, U4, U5, U6, U7, U8>& other)
const
324 bool is_same =
false;
326 switch (other.type_id)
328 case 0: is_same = (type_id == Type_Id_Lookup<U1>::type_id);
break;
329 case 1: is_same = (type_id == Type_Id_Lookup<U2>::type_id);
break;
330 case 2: is_same = (type_id == Type_Id_Lookup<U3>::type_id);
break;
331 case 3: is_same = (type_id == Type_Id_Lookup<U4>::type_id);
break;
332 case 4: is_same = (type_id == Type_Id_Lookup<U5>::type_id);
break;
333 case 5: is_same = (type_id == Type_Id_Lookup<U6>::type_id);
break;
334 case 6: is_same = (type_id == Type_Id_Lookup<U7>::type_id);
break;
335 case 7: is_same = (type_id == Type_Id_Lookup<U8>::type_id);
break;
350 case 0: r.read(
static_cast<T1&
>(data));
break;
351 case 1: r.read(
static_cast<T2&
>(data));
break;
352 case 2: r.read(
static_cast<T3&
>(data));
break;
353 case 3: r.read(
static_cast<T4&
>(data));
break;
354 case 4: r.read(
static_cast<T5&
>(data));
break;
355 case 5: r.read(
static_cast<T6&
>(data));
break;
356 case 6: r.read(
static_cast<T7&
>(data));
break;
357 case 7: r.read(
static_cast<T8&
>(data));
break;
375 template <
typename T>
378 return type_id == Type_Id_Lookup<T>::type_id;
402 template <
typename T>
405 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
406 ETL_ASSERT(is_type<T>(), ETL_ERROR(variant_incorrect_type_exception));
408 return static_cast<T&
>(data);
416 template <
typename T>
419 ETL_STATIC_ASSERT(Type_Is_Supported<T>::value,
"Unsupported type");
420 ETL_ASSERT(is_type<T>(), ETL_ERROR(variant_incorrect_type_exception));
422 return static_cast<const T&
>(data);
429 template <
typename TBase>
432 return upcast_functor<TBase, T1, T2, T3, T4, T5, T6, T7, T8>()(data, type_id);
439 template <
typename TBase>
440 const TBase&
upcast()
const
442 return upcast_functor<TBase, T1, T2, T3, T4, T5, T6, T7, T8>()(data, type_id);
448 operator T1&() {
return get<T1>(); }
449 operator T2&() {
return get<T2>(); }
450 operator T3&() {
return get<T3>(); }
451 operator T4&() {
return get<T4>(); }
452 operator T5&() {
return get<T5>(); }
453 operator T6&() {
return get<T6>(); }
454 operator T7&() {
return get<T7>(); }
455 operator T8&() {
return get<T8>(); }
461 template <
typename T>
464 return Type_Is_Supported<T>::value;
472 void destruct_current()
476 case 0: {
static_cast<T1*
>(data)->~T1();
break; }
477 case 1: {
static_cast<T2*
>(data)->~T2();
break; }
478 case 2: {
static_cast<T3*
>(data)->~T3();
break; }
479 case 3: {
static_cast<T4*
>(data)->~T4();
break; }
480 case 4: {
static_cast<T5*
>(data)->~T5();
break; }
481 case 5: {
static_cast<T6*
>(data)->~T6();
break; }
482 case 6: {
static_cast<T7*
>(data)->~T7();
break; }
483 case 7: {
static_cast<T8*
>(data)->~T8();
break; }
490 constexpr
size_t NUMBER_OF_VARIANTS =
sizeof...(TVariants);
#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: largest.h:227
static bool is_supported_type()
Definition: variant.h:719
T & get()
Definition: variant.h:660
~variant()
Destructor.
Definition: variant.h:200
bool is_same_type(const variant &other) const
Definition: variant.h:568
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
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
bool is_valid() const
Definition: variant.h:623
Definition: absolute.h:37
Definition: alignment.h:118