meta: break pointless meta destructors support for perf reasons (breaking change, use type destructors instead)

This commit is contained in:
skypjack
2025-09-04 15:05:15 +02:00
parent dc70d97760
commit 7f38b7668e
7 changed files with 14 additions and 122 deletions
-31
View File
@@ -75,11 +75,6 @@ protected:
}
}
void dtor(meta_dtor_node node) {
reset_bucket(parent);
meta_context::from(*ctx).value[parent].dtor = node;
}
void data(meta_data_node node) {
reset_bucket(node.id);
@@ -284,32 +279,6 @@ public:
return *this;
}
/**
* @brief Assigns a meta destructor to a meta type.
*
* Both free functions and member functions can be assigned to meta types in
* the role of destructors.<br/>
* The signature of a free function should be identical to the following:
*
* @code{.cpp}
* void(Type &);
* @endcode
*
* Member functions should not take arguments instead.<br/>
* The purpose is to give users the ability to free up resources that
* require special treatment before an object is actually destroyed.
*
* @tparam Func The actual function to use as a destructor.
* @return A meta factory for the parent type.
*/
template<auto Func>
meta_factory dtor() noexcept {
static_assert(std::is_invocable_v<decltype(Func), Type &>, "The function doesn't accept an object of the type provided");
auto *const op = +[](void *instance) { std::invoke(Func, *static_cast<Type *>(instance)); };
base_type::dtor(internal::meta_dtor_node{op});
return *this;
}
/**
* @brief Assigns a meta data to a meta type.
* @tparam Data The actual variable to attach to the meta type.
+1 -12
View File
@@ -194,12 +194,6 @@ class meta_any {
}
}
void release() {
if(storage.owner() && (node.dtor.dtor != nullptr)) {
node.dtor.dtor(storage.data());
}
}
meta_any(const meta_any &other, any ref) noexcept
: storage{std::move(ref)},
ctx{other.ctx} {
@@ -333,9 +327,7 @@ public:
vtable{std::exchange(other.vtable, nullptr)} {}
/*! @brief Frees the internal storage, whatever it means. */
~meta_any() {
release();
}
~meta_any() = default;
/**
* @brief Copy assignment operator.
@@ -344,7 +336,6 @@ public:
*/
meta_any &operator=(const meta_any &other) {
if(this != &other) {
release();
storage = other.storage;
ctx = other.ctx;
resolve = other.resolve;
@@ -524,7 +515,6 @@ public:
/*! @copydoc any::emplace */
template<typename Type, typename... Args>
void emplace(Args &&...args) {
release();
storage.emplace<Type>(std::forward<Args>(args)...);
resolve = internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>;
node = resolve(internal::meta_context::from(*ctx));
@@ -539,7 +529,6 @@ public:
/*! @copydoc any::reset */
void reset() {
release();
storage.reset();
resolve = nullptr;
node = {};
-5
View File
@@ -87,10 +87,6 @@ struct meta_ctor_node {
meta_any (*invoke)(const meta_ctx &, meta_any *const){};
};
struct meta_dtor_node {
void (*dtor)(void *){};
};
struct meta_data_node {
using size_type = std::size_t;
@@ -148,7 +144,6 @@ struct meta_type_node {
double (*conversion_helper)(void *, const void *){};
meta_any (*from_void)(const meta_ctx &, void *, const void *){};
meta_template_node templ{};
meta_dtor_node dtor{};
meta_custom_node custom{};
std::shared_ptr<meta_type_descriptor> details;
};
+7 -17
View File
@@ -39,15 +39,10 @@ struct empty {
empty &operator=(const empty &) = default;
virtual ~empty() {
++destructor_counter;
++counter;
}
static void destroy(empty &) {
++destroy_counter;
}
inline static int destroy_counter = 0; // NOLINT
inline static int destructor_counter = 0; // NOLINT
inline static int counter = 0; // NOLINT
};
struct fat: empty {
@@ -94,13 +89,11 @@ struct MetaAny: ::testing::Test {
using namespace entt::literals;
entt::meta_factory<empty>{}
.type("empty"_hs)
.dtor<empty::destroy>();
.type("empty"_hs);
entt::meta_factory<fat>{}
.type("fat"_hs)
.base<empty>()
.dtor<fat::destroy>();
.base<empty>();
entt::meta_factory<clazz>{}
.type("clazz"_hs)
@@ -109,8 +102,7 @@ struct MetaAny: ::testing::Test {
.func<clazz::func>("func"_hs)
.conv<int>();
empty::destroy_counter = 0;
empty::destructor_counter = 0;
empty::counter = 0;
}
void TearDown() override {
@@ -1024,8 +1016,7 @@ TEST_F(MetaAny, SBODestruction) {
any = std::move(other);
}
ASSERT_EQ(empty::destroy_counter, 3);
ASSERT_EQ(empty::destructor_counter, 6);
ASSERT_EQ(empty::counter, 6);
}
TEST_F(MetaAny, NoSBODestruction) {
@@ -1037,8 +1028,7 @@ TEST_F(MetaAny, NoSBODestruction) {
any = std::move(other);
}
ASSERT_EQ(fat::destroy_counter, 3);
ASSERT_EQ(empty::destructor_counter, 4);
ASSERT_EQ(empty::counter, 4);
}
TEST_F(MetaAny, VoidDestruction) {
-16
View File
@@ -117,7 +117,6 @@ class MetaContext: public ::testing::Test {
.custom<char>('c')
.base<base>()
.ctor<char, int>()
.dtor<&clazz::move_to_bucket>()
.data<nullptr, &clazz::value>("value"_hs)
.data<&clazz::value>("rw"_hs)
.func<&clazz::cfunc>("func"_hs);
@@ -336,21 +335,6 @@ TEST_F(MetaContext, MetaConv) {
ASSERT_EQ(local.cast<int>(), value.get_mul());
}
TEST_F(MetaContext, MetaDtor) {
auto global = entt::resolve<clazz>().construct();
auto local = entt::resolve<clazz>(ctx()).construct();
ASSERT_EQ(clazz::bucket, bucket_value);
global.reset();
ASSERT_EQ(clazz::bucket, bucket_value);
local.reset();
ASSERT_NE(clazz::bucket, bucket_value);
}
TEST_F(MetaContext, MetaCustom) {
using namespace entt::literals;
+6 -13
View File
@@ -17,12 +17,6 @@
struct base {
virtual ~base() = default;
static void destroy(base &) {
++counter;
}
inline static int counter = 0; // NOLINT
int value{3};
};
@@ -81,13 +75,11 @@ struct MetaData: ::testing::Test {
entt::meta_factory<base>{}
.type("base"_hs)
.dtor<base::destroy>()
.data<&base::value>("value"_hs);
entt::meta_factory<derived>{}
.type("derived"_hs)
.base<base>()
.dtor<derived::destroy>()
.data<&base::value>("value_from_base"_hs);
entt::meta_factory<clazz>{}
@@ -120,8 +112,6 @@ struct MetaData: ::testing::Test {
.type("array"_hs)
.data<&array::global>("global"_hs)
.data<&array::local>("local"_hs);
base::counter = 0;
}
void TearDown() override {
@@ -318,10 +308,13 @@ TEST_F(MetaData, SetCast) {
using namespace entt::literals;
clazz instance{};
derived other{};
ASSERT_EQ(base::counter, 0);
ASSERT_TRUE(entt::resolve<clazz>().data("base"_hs).set(instance, derived{}));
ASSERT_EQ(base::counter, 1);
other.value = 1;
ASSERT_EQ(instance.instance.value, 3);
ASSERT_TRUE(entt::resolve<clazz>().data("base"_hs).set(instance, other));
ASSERT_EQ(instance.instance.value, 1);
}
TEST_F(MetaData, SetConvert) {
-28
View File
@@ -49,18 +49,6 @@ private:
int value{};
};
struct dtor_callback {
dtor_callback(bool &ref)
: cb{&ref} {}
static void on_destroy(dtor_callback &instance) {
*instance.cb = !*instance.cb;
}
private:
bool *cb;
};
struct MetaFactory: ::testing::Test {
void TearDown() override {
entt::meta_reset();
@@ -175,22 +163,6 @@ TEST_F(MetaFactory, Ctor) {
ASSERT_EQ(other.cast<const clazz &>().get_int(), values[1u]);
}
TEST_F(MetaFactory, Dtor) {
bool check = false;
entt::meta_factory<dtor_callback> factory{};
entt::meta_any any{std::in_place_type<dtor_callback>, check};
any.reset();
ASSERT_FALSE(check);
factory.dtor<&dtor_callback::on_destroy>();
any.emplace<dtor_callback>(check);
any.reset();
ASSERT_TRUE(check);
}
TEST_F(MetaFactory, DataMemberObject) {
using namespace entt::literals;