|
@ -23,7 +23,7 @@ namespace gp{ |
|
|
template<typename ...T> |
|
|
template<typename ...T> |
|
|
class fixed_variant final { |
|
|
class fixed_variant final { |
|
|
std::size_t index = std::numeric_limits<std::size_t>::max(); |
|
|
std::size_t index = std::numeric_limits<std::size_t>::max(); |
|
|
t">char buffer[max_size<T...>()]; |
|
|
|
|
|
|
|
|
">alignas(gp::max(alignof(T)...)) char data[max_size<T...>()]; |
|
|
gp::function<void(void*, void*)> cpytor = {[](void*, void*){}, nullopt}; |
|
|
gp::function<void(void*, void*)> cpytor = {[](void*, void*){}, nullopt}; |
|
|
gp::function<void(void*, void*)> mvtor = {[](void*, void*){}, nullopt}; |
|
|
gp::function<void(void*, void*)> mvtor = {[](void*, void*){}, nullopt}; |
|
|
gp::function<void(void*)> dtor = {[](void*){}, nullopt}; |
|
|
gp::function<void(void*)> dtor = {[](void*){}, nullopt}; |
|
@ -54,7 +54,7 @@ namespace gp{ |
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){ |
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){ |
|
|
new(dest) actual(gp::move(*(actual*)src)); |
|
|
new(dest) actual(gp::move(*(actual*)src)); |
|
|
}, nullopt); |
|
|
}, nullopt); |
|
|
cpytor((char*)&value, buffer); |
|
|
|
|
|
|
|
|
cpytor((char*)&value, data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static_assert(list_contains_class<int, int>::value, "list_contains_class doesn't work properly"); |
|
|
static_assert(list_contains_class<int, int>::value, "list_contains_class doesn't work properly"); |
|
@ -83,7 +83,7 @@ namespace gp{ |
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){ |
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){ |
|
|
new(dest) actual(gp::move(*(actual*)src)); |
|
|
new(dest) actual(gp::move(*(actual*)src)); |
|
|
}, nullopt); |
|
|
}, nullopt); |
|
|
mvtor((char*)&value, buffer); |
|
|
|
|
|
|
|
|
mvtor((char*)&value, data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fixed_variant(const fixed_variant& oth) |
|
|
fixed_variant(const fixed_variant& oth) |
|
@ -92,7 +92,7 @@ namespace gp{ |
|
|
, cpytor{oth.cpytor} |
|
|
, cpytor{oth.cpytor} |
|
|
, mvtor{oth.mvtor} |
|
|
, mvtor{oth.mvtor} |
|
|
{ |
|
|
{ |
|
|
cpytor((char*)oth.buffer, (char*)buffer); |
|
|
|
|
|
|
|
|
cpytor((char*)oth.data, (char*)data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fixed_variant(fixed_variant& oth) |
|
|
fixed_variant(fixed_variant& oth) |
|
@ -101,7 +101,7 @@ namespace gp{ |
|
|
, cpytor{oth.cpytor} |
|
|
, cpytor{oth.cpytor} |
|
|
, mvtor{oth.mvtor} |
|
|
, mvtor{oth.mvtor} |
|
|
{ |
|
|
{ |
|
|
cpytor(oth.buffer, buffer); |
|
|
|
|
|
|
|
|
cpytor(oth.data, data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fixed_variant(fixed_variant&& oth) |
|
|
fixed_variant(fixed_variant&& oth) |
|
@ -111,7 +111,7 @@ namespace gp{ |
|
|
, mvtor{oth.mvtor} |
|
|
, mvtor{oth.mvtor} |
|
|
{ |
|
|
{ |
|
|
oth.index = std::numeric_limits<std::size_t>::max(); |
|
|
oth.index = std::numeric_limits<std::size_t>::max(); |
|
|
mvtor(oth.buffer, buffer); |
|
|
|
|
|
|
|
|
mvtor(oth.data, data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
@ -140,27 +140,27 @@ namespace gp{ |
|
|
{ |
|
|
{ |
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
{ |
|
|
{ |
|
|
dtor((void*)buffer); |
|
|
|
|
|
|
|
|
dtor((void*)data); |
|
|
} |
|
|
} |
|
|
index = value.index; |
|
|
index = value.index; |
|
|
cpytor = value.cpytor; |
|
|
cpytor = value.cpytor; |
|
|
dtor = value.dtor; |
|
|
dtor = value.dtor; |
|
|
mvtor = value.mvtor; |
|
|
mvtor = value.mvtor; |
|
|
cpytor(value.buffer, buffer); |
|
|
|
|
|
|
|
|
cpytor(value.data, data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void operator=(fixed_variant&& value) |
|
|
void operator=(fixed_variant&& value) |
|
|
{ |
|
|
{ |
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
{ |
|
|
{ |
|
|
dtor((void*)buffer); |
|
|
|
|
|
|
|
|
dtor((void*)data); |
|
|
} |
|
|
} |
|
|
dtor = value.dtor; |
|
|
dtor = value.dtor; |
|
|
cpytor = value.cpytor; |
|
|
cpytor = value.cpytor; |
|
|
mvtor = value.mvtor; |
|
|
mvtor = value.mvtor; |
|
|
index = value.index; |
|
|
index = value.index; |
|
|
value.index = std::numeric_limits<std::size_t>::max(); |
|
|
value.index = std::numeric_limits<std::size_t>::max(); |
|
|
mvtor(value.buffer, buffer); |
|
|
|
|
|
|
|
|
mvtor(value.data, data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> |
|
|
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> |
|
@ -168,10 +168,10 @@ namespace gp{ |
|
|
{ |
|
|
{ |
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
{ |
|
|
{ |
|
|
dtor((void*)buffer); |
|
|
|
|
|
|
|
|
dtor((void*)data); |
|
|
} |
|
|
} |
|
|
index = r_index_of<gp::remove_cvref_t<U>, T...>::value; |
|
|
index = r_index_of<gp::remove_cvref_t<U>, T...>::value; |
|
|
new(buffer) U(value); |
|
|
|
|
|
|
|
|
new(data) U(value); |
|
|
dtor = gp::function([](void* thing){((U*)thing)->~U();}, nullopt); |
|
|
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); |
|
|
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 = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(gp::move(*(U*)src));}, nullopt); |
|
@ -182,9 +182,9 @@ namespace gp{ |
|
|
{ |
|
|
{ |
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
{ |
|
|
{ |
|
|
dtor((void*)buffer); |
|
|
|
|
|
|
|
|
dtor((void*)data); |
|
|
} |
|
|
} |
|
|
new(buffer) U(gp::move(value)); |
|
|
|
|
|
|
|
|
new(data) U(gp::move(value)); |
|
|
index = r_index_of<gp::remove_cvref_t<U>, T...>::value; |
|
|
index = r_index_of<gp::remove_cvref_t<U>, T...>::value; |
|
|
dtor = gp::function([](void* thing){((U*)thing)->~U();}, nullopt); |
|
|
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); |
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(*(U*)src);}, nullopt); |
|
@ -195,7 +195,7 @@ namespace gp{ |
|
|
{ |
|
|
{ |
|
|
if(index != std::numeric_limits<std::size_t>::max() && dtor.ready()) |
|
|
if(index != std::numeric_limits<std::size_t>::max() && dtor.ready()) |
|
|
{ |
|
|
{ |
|
|
dtor((void*)buffer); |
|
|
|
|
|
|
|
|
dtor((void*)data); |
|
|
index = std::numeric_limits<std::size_t>::max(); |
|
|
index = std::numeric_limits<std::size_t>::max(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -217,7 +217,7 @@ namespace gp{ |
|
|
throw bad_variant_access<U>{}; |
|
|
throw bad_variant_access<U>{}; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return *reinterpret_cast<U*>(buffer); |
|
|
|
|
|
|
|
|
return *reinterpret_cast<U*>(data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|