any: skip vtable on move for reference types
This commit is contained in:
1
TODO
1
TODO
@@ -42,3 +42,4 @@ TODO:
|
|||||||
* sigh_mixin: change cb signature from reg/entt to storage/entt (breaking for the good)
|
* sigh_mixin: change cb signature from reg/entt to storage/entt (breaking for the good)
|
||||||
* don't pass reactive storage by default to callback
|
* don't pass reactive storage by default to callback
|
||||||
* runtime types support for meta for types that aren't backed by C++ types
|
* 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)
|
||||||
|
|||||||
@@ -75,13 +75,13 @@ class basic_any {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case operation::move:
|
case operation::move:
|
||||||
if constexpr(in_situ<Type>) {
|
ENTT_ASSERT(value.mode == any_policy::owner, "Unexpected mode");
|
||||||
if(value.mode == any_policy::owner) {
|
|
||||||
return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->storage) Type{std::move(*const_cast<Type *>(elem))};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
case operation::transfer:
|
||||||
if constexpr(std::is_move_assignable_v<Type>) {
|
if constexpr(std::is_move_assignable_v<Type>) {
|
||||||
*const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
|
*const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
|
||||||
@@ -208,7 +208,10 @@ public:
|
|||||||
info{other.info},
|
info{other.info},
|
||||||
vtable{other.vtable},
|
vtable{other.vtable},
|
||||||
mode{other.mode} {
|
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);
|
other.vtable(operation::move, other, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,13 +250,17 @@ public:
|
|||||||
|
|
||||||
reset();
|
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);
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user