|
|
@ -24,38 +24,58 @@ namespace gp{ |
|
|
|
gp::function<void(void*)> dtor = {[](void*){}, nullopt}; |
|
|
|
static_assert(all_of_fixed_size<T...>::value, "not fixed"); |
|
|
|
|
|
|
|
void buffswap(fixed_variant& oth) { |
|
|
|
char tmp[max_size<T...>()]; |
|
|
|
mvtor(tmp, buffer); |
|
|
|
oth.mvtor(buffer, oth.buffer); |
|
|
|
mvtor(oth.buffer, tmp); |
|
|
|
} |
|
|
|
public: |
|
|
|
template<typename U, typename = std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int>> |
|
|
|
fixed_variant() |
|
|
|
: fixed_variant(typename first_of<T...>::type{}) |
|
|
|
{} |
|
|
|
|
|
|
|
template<typename U, std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int> = 0> |
|
|
|
fixed_variant(U& value) |
|
|
|
: index{r_index_of<U, T...>::value} |
|
|
|
{ |
|
|
|
using actual = gp::remove_cvref_t<U>; |
|
|
|
new(buffer) actual(value); |
|
|
|
dtor = gp::function<void(void*)>([](void* thing){((actual*)thing)->~actual();}, nullopt); |
|
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) actual(*(actual*)src);}, nullopt); |
|
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) actual(gp::move(*(actual*)src));}, nullopt); |
|
|
|
dtor = gp::function<void(void*)>([](void* thing){ |
|
|
|
((actual*)thing)->~actual(); |
|
|
|
}, nullopt); |
|
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){ |
|
|
|
new(dest) actual(*(actual*)src); |
|
|
|
}, nullopt); |
|
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){ |
|
|
|
new(dest) actual(gp::move(*(actual*)src)); |
|
|
|
}, nullopt); |
|
|
|
cpytor((char*)&value, buffer); |
|
|
|
} |
|
|
|
|
|
|
|
static_assert(list_contains_class<int, int>::value, "list_contains_class doesn't work properly"); |
|
|
|
static_assert(list_contains_class<int, char, int>::value, "list_contains_class doesn't work properly"); |
|
|
|
static_assert(list_contains_class<int, int, char>::value, "list_contains_class doesn't work properly"); |
|
|
|
static_assert(list_contains_class<int, char, int, char>::value, "list_contains_class doesn't work properly"); |
|
|
|
static_assert(!list_contains_class<int, char, char>::value, "list_contains_class doesn't work properly"); |
|
|
|
|
|
|
|
template<typename U, k">typename = std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int>> |
|
|
|
template<typename U, std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int> = 0> |
|
|
|
fixed_variant(U&& value) |
|
|
|
: index{r_index_of<U, T...>::value} |
|
|
|
{ |
|
|
|
using actual = gp::remove_cvref_t<U>; |
|
|
|
new(buffer) actual(std::move(value)); |
|
|
|
dtor = gp::function<void(void*)>([](void* thing){((actual*)thing)->~actual();}, nullopt); |
|
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) actual(*(actual*)src);}, nullopt); |
|
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) actual(gp::move(*(actual*)src));}, nullopt); |
|
|
|
dtor = gp::function<void(void*)>([](void* thing){ |
|
|
|
((actual*)thing)->~actual(); |
|
|
|
}, nullopt); |
|
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){ |
|
|
|
new(dest) actual(*(actual*)src); |
|
|
|
}, nullopt); |
|
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){ |
|
|
|
new(dest) actual(gp::move(*(actual*)src)); |
|
|
|
}, nullopt); |
|
|
|
mvtor((char*)&value, buffer); |
|
|
|
} |
|
|
|
|
|
|
|
fixed_variant(const fixed_variant& oth) |
|
|
|
: index{oth.index} |
|
|
|
, dtor{oth.dtor} |
|
|
|
, cpytor{oth.cpytor} |
|
|
|
, mvtor{oth.mvtor} |
|
|
|
{ |
|
|
|
cpytor((char*)oth.buffer, (char*)buffer); |
|
|
|
} |
|
|
|
|
|
|
|
fixed_variant(fixed_variant& oth) |
|
|
@ -68,12 +88,13 @@ namespace gp{ |
|
|
|
} |
|
|
|
|
|
|
|
fixed_variant(fixed_variant&& oth) |
|
|
|
: index{oth.index} |
|
|
|
, dtor{oth.dtor} |
|
|
|
, cpytor{oth.cpytor} |
|
|
|
, mvtor{oth.mvtor} |
|
|
|
{ |
|
|
|
mvtor(buffer, oth.buffer); |
|
|
|
gp::swap(dtor, oth.dtor); |
|
|
|
gp::swap(cpytor, oth.cpytor); |
|
|
|
gp::swap(mvtor, oth.mvtor); |
|
|
|
gp::swap(index, oth.index); |
|
|
|
oth.index = std::numeric_limits<std::size_t>::max(); |
|
|
|
mvtor(oth.buffer, buffer); |
|
|
|
} |
|
|
|
|
|
|
|
template<typename U> |
|
|
@ -100,11 +121,16 @@ namespace gp{ |
|
|
|
|
|
|
|
void operator=(fixed_variant&& value) |
|
|
|
{ |
|
|
|
buffswap(value); |
|
|
|
gp::swap(dtor, value.dtor); |
|
|
|
gp::swap(cpytor, value.cpytor); |
|
|
|
gp::swap(mvtor, value.mvtor); |
|
|
|
gp::swap(index, value.index); |
|
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
|
{ |
|
|
|
dtor((void*)buffer); |
|
|
|
} |
|
|
|
dtor = value.dtor; |
|
|
|
cpytor = value.cpytor; |
|
|
|
mvtor = value.mvtor; |
|
|
|
index = value.index; |
|
|
|
value.index = std::numeric_limits<std::size_t>::max(); |
|
|
|
mvtor(value.buffer, buffer); |
|
|
|
} |
|
|
|
|
|
|
|
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> |
|
|
@ -128,11 +154,11 @@ namespace gp{ |
|
|
|
{ |
|
|
|
dtor((void*)buffer); |
|
|
|
} |
|
|
|
new(buffer) U(gp::move(value)); |
|
|
|
index = r_index_of<U, T...>::value; |
|
|
|
dtor = gp::function([](void* thing){((U*)thing)->~U();}, nullopt); |
|
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(*(U*)src);}, nullopt); |
|
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(gp::move(*(U*)src));}, nullopt); |
|
|
|
mvtor(buffer, value.buffer); |
|
|
|
} |
|
|
|
|
|
|
|
~fixed_variant() |
|
|
@ -158,7 +184,7 @@ namespace gp{ |
|
|
|
} |
|
|
|
|
|
|
|
template<typename U> |
|
|
|
constexpr n">U& is_a() |
|
|
|
constexpr kt">bool is_a() |
|
|
|
{ |
|
|
|
if(r_index_of<U, T...>::value == index) |
|
|
|
{ |
|
|
|