|
|
@ -2,6 +2,7 @@ |
|
|
|
|
|
|
|
#include "gp_config.hpp"
|
|
|
|
|
|
|
|
#include <gp/algorithm/move.hpp>
|
|
|
|
#include <gp/algorithm/tmp_manip.hpp>
|
|
|
|
#include "gp/allocator/dummy.hpp"
|
|
|
|
#include "gp/exception.hpp"
|
|
|
@ -18,19 +19,26 @@ namespace gp{ |
|
|
|
class fixed_variant final { |
|
|
|
std::size_t index = std::numeric_limits<std::size_t>::max(); |
|
|
|
char buffer[max_size<T...>()]; |
|
|
|
gp::function<void(void*, void*)> cpytor = [](void*, void*){}; |
|
|
|
gp::function<void(void*, void*)> mvtor = [](void*, void*){}; |
|
|
|
gp::function<void(void*)> dtor = [](void*){}; |
|
|
|
gp::function<void(void*, void*)> cpytor = {[](void*, void*){}, nullopt}; |
|
|
|
gp::function<void(void*, void*)> mvtor = {[](void*, void*){}, nullopt}; |
|
|
|
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<list_contains_class<U,T...>::value,int>::type>
|
|
|
|
constexpr fixed_variant(U& value) |
|
|
|
: index{r_index_of<U, T...>::value} |
|
|
|
{ |
|
|
|
new(buffer) U(value); |
|
|
|
dtor = gp::function<void(void*)>([](void* thing){((U*)thing)->~U();}); |
|
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(*(U*)src);}); |
|
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(gp::move(*(U*)src));}); |
|
|
|
dtor = gp::function<void(void*)>([](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); |
|
|
|
} |
|
|
|
|
|
|
|
template<typename U>//, typename std::enable_if<list_contains_class<U,T...>::value,int>::type>
|
|
|
@ -38,9 +46,9 @@ namespace gp{ |
|
|
|
: index{r_index_of<U, T...>::value} |
|
|
|
{ |
|
|
|
new(buffer) U(std::move(value)); |
|
|
|
dtor = gp::function<void(void*)>([](void* thing){((U*)thing)->~U();}); |
|
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(*(U*)src);}); |
|
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(gp::move(*(U*)src));}); |
|
|
|
dtor = gp::function<void(void*)>([](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); |
|
|
|
} |
|
|
|
|
|
|
|
constexpr fixed_variant(fixed_variant& oth) |
|
|
@ -52,6 +60,15 @@ namespace gp{ |
|
|
|
cpytor(oth.buffer, buffer); |
|
|
|
} |
|
|
|
|
|
|
|
constexpr fixed_variant(fixed_variant&& oth) |
|
|
|
{ |
|
|
|
mvtor(buffer, oth.buffer); |
|
|
|
gp::swap(dtor, oth.dtor); |
|
|
|
gp::swap(cpytor, oth.cpytor); |
|
|
|
gp::swap(mvtor, oth.mvtor); |
|
|
|
gp::swap(index, oth.index); |
|
|
|
} |
|
|
|
|
|
|
|
template<typename U> |
|
|
|
constexpr size_t alt() const { |
|
|
|
return r_index_of<U, T...>::value; |
|
|
@ -70,7 +87,17 @@ namespace gp{ |
|
|
|
index = value.index; |
|
|
|
cpytor = value.cpytor; |
|
|
|
dtor = value.dtor; |
|
|
|
mvtor(value.buffer, buffer); |
|
|
|
mvtor = value.mvtor; |
|
|
|
cpytor(value.buffer, buffer); |
|
|
|
} |
|
|
|
|
|
|
|
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); |
|
|
|
} |
|
|
|
|
|
|
|
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> |
|
|
@ -82,9 +109,9 @@ namespace gp{ |
|
|
|
} |
|
|
|
index = r_index_of<U, T...>::value; |
|
|
|
new(buffer) U(value); |
|
|
|
dtor = gp::function([](void* thing){((U*)thing)->~U();}); |
|
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(*(U*)src);}); |
|
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(gp::move(*(U*)src));}); |
|
|
|
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); |
|
|
|
} |
|
|
|
|
|
|
|
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> |
|
|
@ -95,17 +122,18 @@ namespace gp{ |
|
|
|
dtor((void*)buffer); |
|
|
|
} |
|
|
|
index = r_index_of<U, T...>::value; |
|
|
|
k">new(buffer) U(std::move(value)); |
|
|
|
dtor = gp::functionp">([](void* thing){((U*)thing)->~U();}); |
|
|
|
cpytor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(*(U*)src);}); |
|
|
|
mvtor = gp::function<void(void*, void*)>([](void* src, void* dest){new(dest) U(gp::move(*(U*)src));}); |
|
|
|
n">dtor = gp::function([](void* thing){((U*)thing)->~U();}, nullopt); |
|
|
|
cpytor = gp::functiono"><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(n">gp::move(*(U*)src));}, nullopt); |
|
|
|
mvtor(buffer, value.buffer); |
|
|
|
} |
|
|
|
|
|
|
|
~fixed_variant() |
|
|
|
{ |
|
|
|
if(index != std::numeric_limits<std::size_t>::max()) |
|
|
|
if(index != std::numeric_limits<std::size_t>::max() && dtor.ready()) |
|
|
|
{ |
|
|
|
dtor((void*)buffer); |
|
|
|
index = std::numeric_limits<std::size_t>::max(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|