25 template <
size_t arg,
size_t... rest>
29 struct IntegerMax<arg> : std::integral_constant<size_t, arg> {};
31 template <
size_t arg1,
size_t arg2,
size_t... rest>
32 struct IntegerMax<arg1, arg2, rest...> : std::integral_constant<size_t, arg1 >= arg2 ?
IntegerMax<arg1, rest...>::value :
IntegerMax<arg2, rest...>::value> {};
35 template <
typename... Args>
36 struct MaxAlign : std::integral_constant<int, IntegerMax<std::alignment_of<Args>::value...>::value> {};
39 template <
typename T,
typename... List>
42 template <
typename T,
typename Head,
typename... Rest>
43 struct Contains<
T, Head, Rest...> : std::conditional< std::is_same<T, Head>::value, std::true_type, Contains<T, Rest...>>::type {};
49 template <
typename Type,
typename... Types>
52 template <
typename Type,
typename First,
typename... Types>
55 template <
typename Type,
typename... Types>
56 struct GetLeftSize<Type, Type, Types...> : std::integral_constant<int, sizeof...(Types)> {};
58 template <
typename Type>
59 struct GetLeftSize<Type> : std::integral_constant<int, -1> {};
62 template <
typename T,
typename... Types>
63 struct Index : std::integral_constant<int, sizeof...(Types) - GetLeftSize<T, Types...>::value - 1> {};
66 template <
typename... Args>
69 template <
typename T,
typename... Args>
72 inline static void Destroy(std::type_index
id,
void * data)
74 if(
id == std::type_index(
typeid(
T)))
76 reinterpret_cast<T*
>(data)->~
T();
81 inline static void move(std::type_index old_t,
void *old_v,
void *new_v)
83 if(old_t == std::type_index(
typeid(
T)))
84 new (new_v)
T(std::move(*reinterpret_cast<T*>(old_v)));
89 inline static void copy(std::type_index old_t,
const void *old_v,
void *new_v)
91 if(old_t == std::type_index(
typeid(
T)))
92 new (new_v)
T(*reinterpret_cast<const T*>(old_v));
101 inline static void Destroy(std::type_index,
void *) {}
102 inline static void move(std::type_index,
void *,
void *) {}
103 inline static void copy(std::type_index,
const void *,
void *) {}
107 template <
typename... Types>
117 using data_t =
typename std::aligned_storage<data_size, align_size>::type;
124 : m_type(typeid(void))
132 : m_type(other.m_type)
134 Helper_t::move(other.m_type, &other.m_data, &m_data);
141 : m_type(other.m_type)
150 class =
typename std::enable_if<Contains<typename std::remove_reference<T>::type, Types...>::value>::type>
152 : m_type(typeid(void))
154 Helper_t::Destroy(m_type, &m_data);
155 typedef typename std::remove_reference<T>::type U;
156 new (&m_data) U(std::forward<T>(value));
157 m_type = std::type_index(
typeid(
T));
165 Helper_t::Destroy(m_type, &m_data);
177 Helper_t::move(other.m_type, &other.m_data, &m_data);
178 m_type = other.m_type;
184 return m_type == other.m_type;
189 return m_type < other.m_type;
192 template <
typename T>
195 return m_type == std::type_index(
typeid(
T));
200 return m_type == std::type_index(
typeid(
void));
208 template <
typename T>
209 typename std::decay<T>::type&
get()
211 using U =
typename std::decay<T>::type;
214 TTK_ERROR_STREAM(
typeid(U).
name() <<
" is not defined. " <<
"current type is " << m_type.name());
215 throw std::bad_cast();
217 return *(U*) (&m_data);
223 return Index<
T, Types...>::value;
236 template <
typename... Types>
241 #endif // TTKVARIANT_H
static void copy(std::type_index old_t, const void *old_v, void *new_v)
#define TTK_MODULE_EXPORT
bool isEmpty() const noexcept
typename std::aligned_storage< data_size, align_size >::type data_t
bool operator==(const TTKVariant &other) const noexcept
int indexOf() const noexcept
bool isSame() const noexcept
static void Destroy(std::type_index id, void *data)
static void Destroy(std::type_index, void *)
TTKVariant(const TTKVariant< Types...> &other)
static void copy(std::type_index, const void *, void *)
bool operator<(const TTKVariant &other) const noexcept
std::type_index type() const noexcept
VariantHelper< Types...> Helper_t
TTKVariant & operator=(TTKVariant &&other)
TTKVariant & operator=(const TTKVariant &other)
static void move(std::type_index, void *, void *)
#define TTK_ERROR_STREAM(msg)
TTKVariant(TTKVariant< Types...> &&other)
static void move(std::type_index old_t, void *old_v, void *new_v)