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)))
77 reinterpret_cast<T*
>(data)->~
T();
85 inline static void move(std::type_index old_t,
void *old_v,
void *new_v)
87 if(old_t == std::type_index(
typeid(
T)))
89 new (new_v)
T(std::move(*reinterpret_cast<T*>(old_v)));
97 inline static void copy(std::type_index old_t,
const void *old_v,
void *new_v)
99 if(old_t == std::type_index(
typeid(
T)))
101 new (new_v)
T(*reinterpret_cast<const T*>(old_v));
113 inline static void Destroy(std::type_index,
void *) { }
114 inline static void move(std::type_index,
void *,
void *) { }
115 inline static void copy(std::type_index,
const void *,
void *) { }
122 template <
typename... Types>
132 using data_t =
typename std::aligned_storage<data_size, align_size>::type;
139 : m_type(typeid(
void))
148 : m_type(other.m_type)
150 Helper_t::move(other.m_type, &other.m_data, &m_data);
157 : m_type(other.m_type)
166 class =
typename std::enable_if<Contains<typename std::remove_reference<T>::type, Types...>::value>::type>
168 : m_type(typeid(void))
170 Helper_t::Destroy(m_type, &m_data);
171 typedef typename std::remove_reference<T>::type U;
172 new (&m_data) U(std::forward<T>(value));
173 m_type = std::type_index(
typeid(
T));
181 Helper_t::Destroy(m_type, &m_data);
193 Helper_t::move(other.m_type, &other.m_data, &m_data);
194 m_type = other.m_type;
200 return m_type == other.m_type;
205 return m_type < other.m_type;
208 template <
typename T>
211 return m_type == std::type_index(
typeid(
T));
216 return m_type == std::type_index(
typeid(
void));
224 template <
typename T>
225 typename std::decay<T>::type&
get()
227 using U =
typename std::decay<T>::type;
230 TTK_ERROR_STREAM(
typeid(U).
name() <<
" is not defined. " <<
"current type is " << m_type.name());
231 throw std::bad_cast();
233 return *(U*) (&m_data);
236 template <
typename T>
239 return Index<
T, Types...>::value;
252 template <
typename... Types>
257 #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)
The class of the variant module.
static void move(std::type_index old_t, void *old_v, void *new_v)