any: skip vtable on move for reference types

This commit is contained in:
Michele Caini
2024-10-25 09:20:30 +02:00
parent 6405aece3a
commit e13c87a447
2 changed files with 19 additions and 11 deletions

1
TODO
View File

@@ -42,3 +42,4 @@ TODO:
* sigh_mixin: change cb signature from reg/entt to storage/entt (breaking for the good)
* don't pass reactive storage by default to callback
* runtime types support for meta for types that aren't backed by C++ types
* bypass vtable in any (improvements available for move/get, add more policy types)

View File

@@ -75,13 +75,13 @@ class basic_any {
}
break;
case operation::move:
if constexpr(in_situ<Type>) {
if(value.mode == any_policy::owner) {
return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->storage) Type{std::move(*const_cast<Type *>(elem))};
}
}
ENTT_ASSERT(value.mode == any_policy::owner, "Unexpected mode");
return (static_cast<basic_any *>(const_cast<void *>(other))->instance = std::exchange(const_cast<basic_any &>(value).instance, nullptr));
if constexpr(in_situ<Type>) {
return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->storage) Type{std::move(*const_cast<Type *>(elem))};
} else {
return (static_cast<basic_any *>(const_cast<void *>(other))->instance = std::exchange(const_cast<basic_any &>(value).instance, nullptr));
}
case operation::transfer:
if constexpr(std::is_move_assignable_v<Type>) {
*const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
@@ -208,7 +208,10 @@ public:
info{other.info},
vtable{other.vtable},
mode{other.mode} {
if(other.vtable) {
if(other.mode != any_policy::owner) {
ENTT_ASSERT(other.mode == any_policy::ref || other.mode == any_policy::cref, "Unexpected mode");
instance = std::exchange(other.instance, nullptr);
} else if(other.vtable) {
other.vtable(operation::move, other, this);
}
}
@@ -247,13 +250,17 @@ public:
reset();
if(other.vtable) {
if(other.mode != any_policy::owner) {
ENTT_ASSERT(other.mode == any_policy::ref || other.mode == any_policy::cref, "Unexpected mode");
instance = std::exchange(other.instance, nullptr);
} else if(other.vtable) {
other.vtable(operation::move, other, this);
info = other.info;
vtable = other.vtable;
mode = other.mode;
}
info = other.info;
vtable = other.vtable;
mode = other.mode;
return *this;
}