Loading...
Searching...
No Matches
variant_legacy.h
Go to the documentation of this file.
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2014 jwellbelove, Robin S�derholm
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "../platform.h"
#include "../alignment.h"
#include "../error_handler.h"
#include "../exception.h"
#include "../integral_limits.h"
#include "../largest.h"
#include "../monostate.h"
#include "../null_type.h"
#include "../parameter_type.h"
#include "../placement_new.h"
#include "../static_assert.h"
#include "../type_traits.h"
#include "../utility.h"
#include <stdint.h>
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 940
#pragma diag_suppress 111
#endif
//*****************************************************************************
//*****************************************************************************
namespace etl
{
#if ETL_NOT_USING_LEGACY_VARIANT
namespace legacy
{
#endif
namespace private_variant
{
//*************************************************************************
//*************************************************************************
template <size_t Id>
struct no_type
{
};
} // namespace private_variant
//***************************************************************************
//***************************************************************************
typedef etl::monostate monostate;
//***************************************************************************
//***************************************************************************
class variant_exception : public etl::exception
{
public:
variant_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class variant_incorrect_type_exception : public variant_exception
{
public:
variant_incorrect_type_exception(string_type file_name_, numeric_type line_number_)
: variant_exception(ETL_ERROR_TEXT("variant:unsupported type", ETL_VARIANT_FILE_ID"A"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class bad_variant_access : public variant_exception
{
public:
bad_variant_access(string_type file_name_, numeric_type line_number_)
: variant_exception(ETL_ERROR_TEXT("variant:bad variant access", ETL_VARIANT_FILE_ID"B"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class variant_not_a_base_exception : public variant_exception
{
public:
variant_not_a_base_exception(string_type file_name_, numeric_type line_number_)
: variant_exception(ETL_ERROR_TEXT("variant:not_a base", ETL_VARIANT_FILE_ID"C"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
template <typename T1, typename T2 = etl::null_type<2>, typename T3 = etl::null_type<3>, typename T4 = etl::null_type<4>,
typename T5 = etl::null_type<5>, typename T6 = etl::null_type<6>, typename T7 = etl::null_type<7>, typename T8 = etl::null_type<8> >
class variant
{
public:
//***************************************************************************
//***************************************************************************
typedef uint_least8_t type_id_t;
//***************************************************************************
//***************************************************************************
static const type_id_t UNSUPPORTED_TYPE_ID = etl::integral_limits<type_id_t>::max;
private:
// All types of variant are friends.
template <typename V1, typename V2, typename V3, typename V4, typename V5, typename V6, typename V7, typename V8>
friend class variant;
//***************************************************************************
//***************************************************************************
typedef typename etl::largest_type<T1, T2, T3, T4, T5, T6, T7, T8>::type largest_t;
//***************************************************************************
//***************************************************************************
static const size_t SIZE = sizeof(largest_t);
//***************************************************************************
//***************************************************************************
static const size_t ALIGNMENT = etl::largest_alignment<T1, T2, T3, T4, T5, T6, T7, T8>::value;
//***************************************************************************
//***************************************************************************
typedef etl::null_type<2> no_type2;
typedef etl::null_type<3> no_type3;
typedef etl::null_type<4> no_type4;
typedef etl::null_type<5> no_type5;
typedef etl::null_type<6> no_type6;
typedef etl::null_type<7> no_type7;
typedef etl::null_type<8> no_type8;
//***************************************************************************
//***************************************************************************
template <typename T>
struct Type_Id_Lookup
{
static const uint_least8_t type_id = etl::is_same<T, T1>::value ? 0
: etl::is_same<T, T2>::value ? 1
: etl::is_same<T, T3>::value ? 2
: etl::is_same<T, T4>::value ? 3
: etl::is_same<T, T5>::value ? 4
: etl::is_same<T, T6>::value ? 5
: etl::is_same<T, T7>::value ? 6
: etl::is_same<T, T8>::value ? 7
: UNSUPPORTED_TYPE_ID;
};
//***************************************************************************
//***************************************************************************
template <typename T>
struct Type_Is_Supported
: public etl::integral_constant< bool, etl::is_same<T, T1>::value || etl::is_same<T, T2>::value || etl::is_same<T, T3>::value
|| etl::is_same<T, T4>::value || etl::is_same<T, T5>::value || etl::is_same<T, T6>::value
|| etl::is_same<T, T7>::value || etl::is_same<T, T8>::value>
{
};
public:
//***************************************************************************
//***************************************************************************
~variant()
{
destruct_current();
}
//*************************************************************************
//**** Reader types
//*******************************************************
//*************************************************************************
//*************************************************************************
//*************************************************************************
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>
class reader_type
{
public:
friend class variant;
virtual ~reader_type() {}
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
virtual void read(typename etl::parameter_type<R5>::type value) = 0;
virtual void read(typename etl::parameter_type<R6>::type value) = 0;
virtual void read(typename etl::parameter_type<R7>::type value) = 0;
virtual void read(typename etl::parameter_type<R8>::type value) = 0;
};
//*************************************************************************
//*************************************************************************
template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6, typename R7>
class reader_type<R1, R2, R3, R4, R5, R6, R7, no_type8>
{
public:
friend class variant;
virtual ~reader_type() {}
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
virtual void read(typename etl::parameter_type<R5>::type value) = 0;
virtual void read(typename etl::parameter_type<R6>::type value) = 0;
virtual void read(typename etl::parameter_type<R7>::type value) = 0;
private:
void read(no_type8&) {}
};
//*************************************************************************
//*************************************************************************
template <typename R1, typename R2, typename R3, typename R4, typename R5, typename R6>
class reader_type<R1, R2, R3, R4, R5, R6, no_type7, no_type8>
{
public:
friend class variant;
virtual ~reader_type() {}
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
virtual void read(typename etl::parameter_type<R5>::type value) = 0;
virtual void read(typename etl::parameter_type<R6>::type value) = 0;
private:
void read(no_type7&) {}
void read(no_type8&) {}
};
//*************************************************************************
//*************************************************************************
template <typename R1, typename R2, typename R3, typename R4, typename R5>
class reader_type<R1, R2, R3, R4, R5, no_type6, no_type7, no_type8>
{
public:
friend class variant;
virtual ~reader_type() {}
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
virtual void read(typename etl::parameter_type<R5>::type value) = 0;
private:
void read(no_type6&) {}
void read(no_type7&) {}
void read(no_type8&) {}
};
//*************************************************************************
//*************************************************************************
template <typename R1, typename R2, typename R3, typename R4>
class reader_type<R1, R2, R3, R4, no_type5, no_type6, no_type7, no_type8>
{
public:
friend class variant;
virtual ~reader_type() {}
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
private:
void read(no_type5&) {}
void read(no_type6&) {}
void read(no_type7&) {}
void read(no_type8&) {}
};
//*************************************************************************
//*************************************************************************
template <typename R1, typename R2, typename R3>
class reader_type<R1, R2, R3, no_type4, no_type5, no_type6, no_type7, no_type8>
{
public:
friend class variant;
virtual ~reader_type() {}
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
private:
void read(no_type4&) {}
void read(no_type5&) {}
void read(no_type6&) {}
void read(no_type7&) {}
void read(no_type8&) {}
};
//*************************************************************************
//*************************************************************************
template <typename R1, typename R2>
class reader_type<R1, R2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
{
public:
friend class variant;
virtual ~reader_type() {}
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
private:
void read(no_type3&) {}
void read(no_type4&) {}
void read(no_type5&) {}
void read(no_type6&) {}
void read(no_type7&) {}
void read(no_type8&) {}
};
//*************************************************************************
//*************************************************************************
template <typename R1>
class reader_type<R1, no_type2, no_type3, no_type4, no_type5, no_type6, no_type7, no_type8>
{
public:
friend class variant;
virtual ~reader_type() {}
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
private:
void read(no_type2&) {}
void read(no_type3&) {}
void read(no_type4&) {}
void read(no_type5&) {}
void read(no_type6&) {}
void read(no_type7&) {}
void read(no_type8&) {}
};
//***************************************************************************
//***************************************************************************
typedef reader_type<T1, T2, T3, T4, T5, T6, T7, T8> reader;
//***************************************************************************
//***************************************************************************
#include "diagnostic_uninitialized_push.h"
variant()
: type_id(UNSUPPORTED_TYPE_ID)
{
}
#include "diagnostic_pop.h"
//***************************************************************************
//***************************************************************************
template <typename T>
variant(const T& value)
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
::new (static_cast<T*>(data)) T(value);
type_id = Type_Id_Lookup<T>::type_id;
}
//***************************************************************************
//***************************************************************************
template <size_t Index, typename T>
explicit variant(etl::in_place_index_t<Index>, T const& value)
: type_id(Index)
{
ETL_STATIC_ASSERT(Type_Id_Lookup<T>::type_id == Index, "Missmatched type");
::new (static_cast<T*>(data)) T(value);
type_id = Index;
}
//***************************************************************************
//***************************************************************************
#include "diagnostic_uninitialized_push.h"
variant(const variant& other)
{
switch (other.type_id)
{
case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
default: break;
}
type_id = other.type_id;
}
#include "diagnostic_pop.h"
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VARIANT_FORCE_CPP03_IMPLEMENTATION)
//*************************************************************************
//*************************************************************************
template <typename T, typename... Args>
T& emplace(Args&&... args)
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
destruct_current();
::new (static_cast<T*>(data)) T(etl::forward<Args>(args)...);
type_id = Type_Id_Lookup<T>::type_id;
return *static_cast<T*>(data);
}
#else
//***************************************************************************
//***************************************************************************
template <typename T>
T& emplace()
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
destruct_current();
::new (static_cast<T*>(data)) T();
type_id = Type_Id_Lookup<T>::type_id;
return *static_cast<T*>(data);
}
//***************************************************************************
//***************************************************************************
template <typename T, typename TP1>
T& emplace(const TP1& value1)
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
destruct_current();
::new (static_cast<T*>(data)) T(value1);
type_id = Type_Id_Lookup<T>::type_id;
return *static_cast<T*>(data);
}
//***************************************************************************
//***************************************************************************
template <typename T, typename TP1, typename TP2>
T& emplace(const TP1& value1, const TP2& value2)
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
destruct_current();
::new (static_cast<T*>(data)) T(value1, value2);
type_id = Type_Id_Lookup<T>::type_id;
return *static_cast<T*>(data);
}
//***************************************************************************
//***************************************************************************
template <typename T, typename TP1, typename TP2, typename TP3>
T& emplace(const TP1& value1, const TP2& value2, const TP3& value3)
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
destruct_current();
::new (static_cast<T*>(data)) T(value1, value2, value3);
type_id = Type_Id_Lookup<T>::type_id;
return *static_cast<T*>(data);
}
//***************************************************************************
//***************************************************************************
template <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
T& emplace(const TP1& value1, const TP2& value2, const TP3& value3, const TP4& value4)
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
destruct_current();
::new (static_cast<T*>(data)) T(value1, value2, value3, value4);
type_id = Type_Id_Lookup<T>::type_id;
return *static_cast<T*>(data);
}
#endif
//***************************************************************************
//***************************************************************************
template <typename T>
variant& operator=(const T& value)
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
destruct_current();
::new (static_cast<T*>(data)) T(value);
type_id = Type_Id_Lookup<T>::type_id;
return *this;
}
//***************************************************************************
//***************************************************************************
variant& operator=(const variant& other)
{
if (this != &other)
{
destruct_current();
switch (other.type_id)
{
case 0: ::new (static_cast<T1*>(data)) T1(other.get<T1>()); break;
case 1: ::new (static_cast<T2*>(data)) T2(other.get<T2>()); break;
case 2: ::new (static_cast<T3*>(data)) T3(other.get<T3>()); break;
case 3: ::new (static_cast<T4*>(data)) T4(other.get<T4>()); break;
case 4: ::new (static_cast<T5*>(data)) T5(other.get<T5>()); break;
case 5: ::new (static_cast<T6*>(data)) T6(other.get<T6>()); break;
case 6: ::new (static_cast<T7*>(data)) T7(other.get<T7>()); break;
case 7: ::new (static_cast<T8*>(data)) T8(other.get<T8>()); break;
default: break;
}
type_id = other.type_id;
}
return *this;
}
//***************************************************************************
//***************************************************************************
bool is_same_type(const variant& other) const
{
return type_id == other.type_id;
}
//***************************************************************************
//***************************************************************************
template <typename V1, typename V2, typename V3, typename V4, typename V5, typename V6, typename V7, typename V8>
bool is_same_type(const variant<V1, V2, V3, V4, V5, V6, V7, V8>& other) const
{
bool is_same = false;
switch (other.type_id)
{
case 0: is_same = (type_id == Type_Id_Lookup<V1>::type_id); break;
case 1: is_same = (type_id == Type_Id_Lookup<V2>::type_id); break;
case 2: is_same = (type_id == Type_Id_Lookup<V3>::type_id); break;
case 3: is_same = (type_id == Type_Id_Lookup<V4>::type_id); break;
case 4: is_same = (type_id == Type_Id_Lookup<V5>::type_id); break;
case 5: is_same = (type_id == Type_Id_Lookup<V6>::type_id); break;
case 6: is_same = (type_id == Type_Id_Lookup<V7>::type_id); break;
case 7: is_same = (type_id == Type_Id_Lookup<V8>::type_id); break;
default: break;
}
return is_same;
}
//***************************************************************************
//***************************************************************************
void call(reader& r)
{
switch (type_id)
{
case 0: r.read(static_cast<T1&>(data)); break;
case 1: r.read(static_cast<T2&>(data)); break;
case 2: r.read(static_cast<T3&>(data)); break;
case 3: r.read(static_cast<T4&>(data)); break;
case 4: r.read(static_cast<T5&>(data)); break;
case 5: r.read(static_cast<T6&>(data)); break;
case 6: r.read(static_cast<T7&>(data)); break;
case 7: r.read(static_cast<T8&>(data)); break;
default: break;
}
}
//***************************************************************************
//***************************************************************************
bool is_valid() const
{
return type_id != UNSUPPORTED_TYPE_ID;
}
//***************************************************************************
//***************************************************************************
template <typename T>
bool is_type() const
{
return type_id == Type_Id_Lookup<T>::type_id;
}
//***************************************************************************
//***************************************************************************
size_t index() const
{
return type_id;
}
//***************************************************************************
//***************************************************************************
void clear()
{
destruct_current();
}
//***************************************************************************
//***************************************************************************
template <typename T>
T& get()
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
ETL_ASSERT(is_type<T>(), ETL_ERROR(variant_incorrect_type_exception));
return static_cast<T&>(data);
}
//***************************************************************************
//***************************************************************************
template <typename T>
const T& get() const
{
ETL_STATIC_ASSERT(Type_Is_Supported<T>::value, "Unsupported type");
ETL_ASSERT(is_type<T>(), ETL_ERROR(variant_incorrect_type_exception));
return static_cast<const T&>(data);
}
//***************************************************************************
//***************************************************************************
template <typename TBase>
TBase* upcast_ptr()
{
if (is_base_of<TBase>())
{
return reinterpret_cast<TBase*>(static_cast<uint_least8_t*>(data));
}
else
{
return ETL_NULLPTR;
}
}
//***************************************************************************
//***************************************************************************
template <typename TBase>
TBase& upcast()
{
TBase* ptr = upcast_ptr<TBase>();
ETL_ASSERT(ptr != ETL_NULLPTR, ETL_ERROR(variant_not_a_base_exception));
return *ptr;
}
//***************************************************************************
//***************************************************************************
template <typename TBase>
const TBase* upcast_ptr() const
{
if (is_base_of<TBase>())
{
return reinterpret_cast<const TBase*>(static_cast<const uint_least8_t*>(data));
}
else
{
return ETL_NULLPTR;
}
}
//***************************************************************************
//***************************************************************************
template <typename TBase>
const TBase& upcast() const
{
const TBase* ptr = upcast_ptr<TBase>();
ETL_ASSERT(ptr != ETL_NULLPTR, ETL_ERROR(variant_not_a_base_exception));
return *ptr;
}
//***************************************************************************
//***************************************************************************
template <typename TBase>
bool is_base_of() const
{
bool is_base;
switch (type_id)
{
case 0: is_base = etl::is_base_of<TBase, T1>::value; break;
case 1: is_base = etl::is_base_of<TBase, T2>::value; break;
case 2: is_base = etl::is_base_of<TBase, T3>::value; break;
case 3: is_base = etl::is_base_of<TBase, T4>::value; break;
case 4: is_base = etl::is_base_of<TBase, T5>::value; break;
case 5: is_base = etl::is_base_of<TBase, T6>::value; break;
case 6: is_base = etl::is_base_of<TBase, T7>::value; break;
case 7: is_base = etl::is_base_of<TBase, T8>::value; break;
default: is_base = false; break;
}
return is_base;
}
//***************************************************************************
//***************************************************************************
operator T1&()
{
return get<T1>();
}
operator T2&()
{
return get<T2>();
}
operator T3&()
{
return get<T3>();
}
operator T4&()
{
return get<T4>();
}
operator T5&()
{
return get<T5>();
}
operator T6&()
{
return get<T6>();
}
operator T7&()
{
return get<T7>();
}
operator T8&()
{
return get<T8>();
}
//***************************************************************************
//***************************************************************************
template <typename T>
static bool is_supported_type()
{
return Type_Is_Supported<T>::value;
}
private:
#include "diagnostic_uninitialized_push.h"
//***************************************************************************
//***************************************************************************
void destruct_current()
{
switch (type_id)
{
case 0:
{
static_cast<T1*>(data)->~T1();
break;
}
case 1:
{
static_cast<T2*>(data)->~T2();
break;
}
case 2:
{
static_cast<T3*>(data)->~T3();
break;
}
case 3:
{
static_cast<T4*>(data)->~T4();
break;
}
case 4:
{
static_cast<T5*>(data)->~T5();
break;
}
case 5:
{
static_cast<T6*>(data)->~T6();
break;
}
case 6:
{
static_cast<T7*>(data)->~T7();
break;
}
case 7:
{
static_cast<T8*>(data)->~T8();
break;
}
default:
{
break;
}
}
type_id = UNSUPPORTED_TYPE_ID;
}
#include "diagnostic_pop.h"
//***************************************************************************
//***************************************************************************
typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;
//***************************************************************************
//***************************************************************************
type_id_t type_id;
};
namespace private_variant
{
template <size_t, typename>
struct variant_alternative_helper;
#define ETL_VARIANT_HELPER(INDEX, TYPE) \
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> \
struct variant_alternative_helper<INDEX, variant<T1, T2, T3, T4, T5, T6, T7, T8> > \
{ \
typedef TYPE type; \
};
ETL_VARIANT_HELPER(0, T1)
ETL_VARIANT_HELPER(1, T2)
ETL_VARIANT_HELPER(2, T3)
ETL_VARIANT_HELPER(3, T4)
ETL_VARIANT_HELPER(4, T5)
ETL_VARIANT_HELPER(5, T6)
ETL_VARIANT_HELPER(6, T7)
ETL_VARIANT_HELPER(7, T8)
#undef ETL_VARIANT_HELPER
} // namespace private_variant
template <size_t tIndex, typename TVariant>
struct variant_alternative
{
typedef typename private_variant::variant_alternative_helper< tIndex, TVariant>::type type;
};
template <size_t tIndex, typename TVariant>
struct variant_alternative<tIndex, TVariant const>
{
typedef typename private_variant::variant_alternative_helper< tIndex, TVariant>::type const type;
};
template <size_t tIndex, typename TVariant>
struct variant_alternative<tIndex, TVariant volatile>
{
typedef typename private_variant::variant_alternative_helper< tIndex, TVariant>::type volatile type;
};
template <size_t tIndex, typename TVariant>
struct variant_alternative<tIndex, TVariant const volatile>
{
typedef typename private_variant::variant_alternative_helper< tIndex, TVariant>::type const volatile type;
};
template <typename T, typename TVariant>
inline T& get(TVariant& variant)
{
return variant.template get<T>();
}
template <typename T, typename TVariant>
inline T const& get(TVariant const& variant)
{
return variant.template get<T>();
}
template <size_t tIndex, typename TVariant>
inline typename variant_alternative<tIndex, TVariant>::type& get(TVariant& variant)
{
return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
}
template <size_t tIndex, typename TVariant>
inline typename variant_alternative<tIndex, TVariant const>::type& get(TVariant const& variant)
{
return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
}
#define ETL_GEN_LEGACY_VISIT(VISITQUAL, VARIANTQUAL) \
template <typename TReturn, typename TVisitor, typename TVariant> \
static TReturn visit(TVisitor VISITQUAL visitor, TVariant VARIANTQUAL variant) \
{ \
switch (variant.index()) \
{ \
case 0: return static_cast<TReturn>(visitor(get<0>(variant))); \
case 1: return static_cast<TReturn>(visitor(get<1>(variant))); \
case 2: return static_cast<TReturn>(visitor(get<2>(variant))); \
case 3: return static_cast<TReturn>(visitor(get<3>(variant))); \
case 4: return static_cast<TReturn>(visitor(get<4>(variant))); \
case 5: return static_cast<TReturn>(visitor(get<5>(variant))); \
case 6: return static_cast<TReturn>(visitor(get<6>(variant))); \
case 7: return static_cast<TReturn>(visitor(get<7>(variant))); \
default: ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(bad_variant_access), TReturn()); \
} \
}
ETL_GEN_LEGACY_VISIT(&, &)
ETL_GEN_LEGACY_VISIT(const&, &)
ETL_GEN_LEGACY_VISIT(&, const&)
ETL_GEN_LEGACY_VISIT(const&, const&)
#undef ETL_GEN_LEGACY_VISIT
#if ETL_NOT_USING_LEGACY_VARIANT
}
#endif
} // namespace etl
alignment.h
etl::null_type
Definition null_type.h:40
etl::variant::reader_type
Definition variant_legacy.h:242
diagnostic_pop.h
diagnostic_uninitialized_push.h
Make this a clone of the supplied priority queue.
error_handler.h
exception.h
ETL_ASSERT
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
etl::exception::exception
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
etl::exception
Definition exception.h:59
etl::integral_limits
Definition integral_limits.h:517
etl::variant::variant
variant(const T &value)
Definition variant_legacy.h:455
etl::variant::is_supported_type
static bool is_supported_type()
Definition variant_legacy.h:889
etl::variant::get
const T & get() const
Definition variant_legacy.h:753
etl::variant::~variant
~variant()
Destructor.
Definition variant_legacy.h:224
etl::variant::emplace
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3, const TP4 &value4)
Emplace with four constructor parameters.
Definition variant_legacy.h:580
etl::variant::is_same_type
bool is_same_type(const variant &other) const
Definition variant_legacy.h:642
etl::variant::emplace
T & emplace(const TP1 &value1, const TP2 &value2, const TP3 &value3)
Emplace with three constructor parameters.
Definition variant_legacy.h:565
etl::variant::call
void call(reader &r)
Definition variant_legacy.h:678
etl::variant::get
T & get()
Definition variant_legacy.h:738
etl::variant< value_type, error_type >::is_base_of
bool is_base_of() const
Definition variant_legacy.h:827
etl::variant::variant
variant(etl::in_place_index_t< Index >, T const &value)
Definition variant_legacy.h:468
etl::variant< value_type, error_type >::type_id_t
uint_least8_t type_id_t
Definition variant_legacy.h:152
etl::variant::is_same_type
bool is_same_type(const variant< V1, V2, V3, V4, V5, V6, V7, V8 > &other) const
Definition variant_legacy.h:653
etl::variant::operator=
variant & operator=(const T &value)
Definition variant_legacy.h:597
etl::variant::operator=
variant & operator=(const variant &other)
Definition variant_legacy.h:612
etl::variant::emplace
T & emplace(const TP1 &value1)
Emplace with one constructor parameter.
Definition variant_legacy.h:535
etl::variant::upcast_ptr
const TBase * upcast_ptr() const
Definition variant_legacy.h:797
etl::variant< value_type, error_type >::reader
reader_type< value_type, error_type, etl::null_type< 3 >, 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
etl::variant::is_type
bool is_type() const
Definition variant_legacy.h:710
etl::variant::clear
void clear()
Clears the value to 'no valid stored value'.
Definition variant_legacy.h:726
etl::variant::emplace
T & emplace(const TP1 &value1, const TP2 &value2)
Emplace with two constructor parameters.
Definition variant_legacy.h:550
etl::variant::upcast_ptr
TBase * upcast_ptr()
Definition variant_legacy.h:766
etl::variant::emplace
T & emplace()
Emplace with one constructor parameter.
Definition variant_legacy.h:520
etl::variant::index
size_t index() const
Gets the index of the type currently stored or UNSUPPORTED_TYPE_ID.
Definition variant_legacy.h:718
etl::variant::upcast
TBase & upcast()
Definition variant_legacy.h:783
etl::variant< value_type, error_type >::UNSUPPORTED_TYPE_ID
static const type_id_t UNSUPPORTED_TYPE_ID
Definition variant_legacy.h:157
etl::variant::upcast
const TBase & upcast() const
Definition variant_legacy.h:814
etl::variant::is_valid
bool is_valid() const
Definition variant_legacy.h:698
etl::variant
Definition variant_legacy.h:146
etl::variant_incorrect_type_exception
Definition variant_legacy.h:101
etl::variant_not_a_base_exception
Definition variant_legacy.h:129
integral_limits.h
largest.h
monostate.h
etl
Definition absolute.h:40
etl::data
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1470
etl::get
T & get(array< T, Size > &a)
Definition array.h:1158
parameter_type.h
placement_new.h
platform.h
etl::in_place_index_t
Definition utility.h:964
etl::integral_constant
integral_constant
Definition type_traits.h:67
etl::monostate
A 'no-value' placeholder.
Definition monostate.h:42
etl::parameter_type::type
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
etl::private_variant::no_type
Definition variant_legacy.h:72
etl::private_variant::variant_alternative_helper
Definition variant_legacy.h:969
etl::variant_alternative
Definition variant_legacy.h:989
type_traits.h
utility.h