5 #ifndef HOBBES_UTIL_VARIANT_HPP_INCLUDED 6 #define HOBBES_UTIL_VARIANT_HPP_INCLUDED 13 template <
bool f,
typename T,
typename F>
15 template <
typename T,
typename F>
17 template <
typename T,
typename F>
23 static const size_t value =
sizeof(T);
29 static const size_t value =
alignof(T);
33 template <
template <
class>
class SzP,
typename T0,
typename ... Ts>
35 static const size_t value = SzP<T0>::value;
39 template <
template <
class>
class SzP,
typename T0,
typename T1,
typename ... Ts>
40 struct maximum<SzP, T0, T1, Ts...> :
public maximum<SzP, typename TIfF<SzP<T1>::value < SzP<T0>::value, T0, T1>::type, Ts...> {
44 template <typename ... Ts>
46 static const size_t value = sizeof...(Ts);
50 template <typename T, typename ... Ctors>
52 static const uint32_t value = 0;
54 template <typename T, typename ... Ctors>
55 struct CtorIndexOf<T, T, Ctors...> {
56 static const uint32_t value = 0;
58 template <typename T, typename Ctor, typename ... Ctors>
59 struct CtorIndexOf<T, Ctor, Ctors...> {
60 static const uint32_t value = 1 + CtorIndexOf<T, Ctors...>::value;
64 template <typename T, typename ... Ts>
70 template <typename ... Ctors>
72 static void invoke(uint32_t,void*,const void*) { }
74 template <typename Ctor, typename ... Ctors>
75 struct CCtorAt0<Ctor, Ctors...> {
76 static void invoke(uint32_t t, void* to, const void* from) {
78 new (to) Ctor(*((const Ctor*)from));
80 CCtorAt0<Ctors...>::invoke(t-1, to, from);
86 template <typename ... Ctors>
88 static void invoke(uint32_t,void*) { }
90 template <typename Ctor, typename ... Ctors>
91 struct DtorAt0<Ctor, Ctors...> {
92 static void invoke(uint32_t t, void* p) {
96 DtorAt0<Ctors...>::invoke(t-1, p);
102 template <
typename ... Ctors>
105 static_assert(
sizeof...(Ctors) > 0,
"Empty variants are impossible to construct");
108 new (this->storage)
typename First<Ctors...>::type();
110 template <
typename T>
111 variant(
const T& t) : tag(CtorIndexOf<T, Ctors...>::value) {
112 static_assert(CtorIndexOf<T, Ctors...>::value <
sizeof...(Ctors),
"Constructor type isn't part of variant");
113 new (this->storage) T(t);
116 CCtorAt0<Ctors...>::invoke(this->tag, this->storage, rhs.
storage);
120 DtorAt0<Ctors...>::invoke(this->tag, this->storage);
125 DtorAt0<Ctors...>::invoke(this->tag, this->storage);
127 CCtorAt0<Ctors...>::invoke(this->tag, this->storage, rhs.
storage);
132 template <
typename T>
133 T*
get() {
return findByCtor<T>(); }
134 template <
typename T>
135 const T*
get()
const {
return findByCtor<T>(); }
143 template <
typename T>
145 static_assert(CtorIndexOf<T, Ctors...>::value <
sizeof...(Ctors),
"Constructor type isn't part of variant");
147 if (this->tag == CtorIndexOf<T, Ctors...>::value) {
148 return (T*)(this->storage);
155 template <
typename T,
typename ... Ctors>
157 return v.template get<T>();
159 template <
typename T,
typename ... Ctors>
161 return v.template get<T>();
F type
Definition: variant.H:18
uint32_t tag
Definition: variant.H:137
T0 type
Definition: variant.H:36
variant< Ctors... > & operator=(const variant< Ctors... > &rhs)
Definition: variant.H:123
T * findByCtor() const
Definition: variant.H:144
~variant()
Definition: variant.H:119
char storage[maximum< TSizeOfF, Ctors... >::value]
Definition: variant.H:139
variant(const T &t)
Definition: variant.H:111
variant()
Definition: variant.H:107
else
Definition: variant.H:95
unit()
Definition: variant.H:165
Definition: variant.H:165
maximum< TAlignOfF, Ctors... >::type maxAlignedT
Definition: variant.H:140
Definition: variant.H:103
variant(const variant< Ctors... > &rhs)
Definition: variant.H:115
T type
Definition: variant.H:16