meta: support transparently base members when attached to meta types for derived classes
This commit is contained in:
@@ -28,12 +28,12 @@ struct meta_function_descriptor<Type, Ret (Class::*)(Args...) const> {
|
||||
/*! @brief Meta function return type. */
|
||||
using return_type = Ret;
|
||||
/*! @brief Meta function arguments. */
|
||||
using args_type = std::conditional_t<std::is_same_v<Type, Class>, type_list<Args...>, type_list<const Class &, Args...>>;
|
||||
using args_type = std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<const Class &, Args...>>;
|
||||
|
||||
/*! @brief True if the meta function is const, false otherwise. */
|
||||
static constexpr auto is_const = true;
|
||||
/*! @brief True if the meta function is static, false otherwise. */
|
||||
static constexpr auto is_static = !std::is_same_v<Type, Class>;
|
||||
static constexpr auto is_static = !std::is_base_of_v<Class, Type>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -48,12 +48,12 @@ struct meta_function_descriptor<Type, Ret (Class::*)(Args...)> {
|
||||
/*! @brief Meta function return type. */
|
||||
using return_type = Ret;
|
||||
/*! @brief Meta function arguments. */
|
||||
using args_type = std::conditional_t<std::is_same_v<Type, Class>, type_list<Args...>, type_list<Class &, Args...>>;
|
||||
using args_type = std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<Class &, Args...>>;
|
||||
|
||||
/*! @brief True if the meta function is const, false otherwise. */
|
||||
static constexpr auto is_const = false;
|
||||
/*! @brief True if the meta function is static, false otherwise. */
|
||||
static constexpr auto is_static = !std::is_same_v<Type, Class>;
|
||||
static constexpr auto is_static = !std::is_base_of_v<Class, Type>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -67,7 +67,7 @@ struct meta_function_descriptor<Type, Ret Class::*> {
|
||||
/*! @brief Meta data return type. */
|
||||
using return_type = Ret;
|
||||
/*! @brief Meta data arguments. */
|
||||
using args_type = std::conditional_t<std::is_same_v<Type, Class>, type_list<Ret>, type_list<Class &, Ret>>;
|
||||
using args_type = std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Ret>, type_list<Class &, Ret>>;
|
||||
|
||||
/*! @brief True if the meta data is const, false otherwise. */
|
||||
static constexpr auto is_const = false;
|
||||
@@ -87,12 +87,12 @@ struct meta_function_descriptor<Type, Ret (*)(MaybeType, Args...)> {
|
||||
/*! @brief Meta function return type. */
|
||||
using return_type = Ret;
|
||||
/*! @brief Meta function arguments. */
|
||||
using args_type = std::conditional_t<std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<MaybeType>>>, type_list<Args...>, type_list<MaybeType, Args...>>;
|
||||
using args_type = std::conditional_t<std::is_base_of_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type>, type_list<Args...>, type_list<MaybeType, Args...>>;
|
||||
|
||||
/*! @brief True if the meta function is const, false otherwise. */
|
||||
static constexpr auto is_const = std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<MaybeType>>> && std::is_const_v<std::remove_reference_t<MaybeType>>;
|
||||
static constexpr auto is_const = std::is_base_of_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type> && std::is_const_v<std::remove_reference_t<MaybeType>>;
|
||||
/*! @brief True if the meta function is static, false otherwise. */
|
||||
static constexpr auto is_static = !std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<MaybeType>>>;
|
||||
static constexpr auto is_static = !std::is_base_of_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type>;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -109,7 +109,8 @@ struct MetaData: ::testing::Test {
|
||||
entt::meta<derived_t>()
|
||||
.type("derived"_hs)
|
||||
.base<base_t>()
|
||||
.dtor<derived_t::destroy>();
|
||||
.dtor<derived_t::destroy>()
|
||||
.data<&base_t::value>("value_from_base"_hs);
|
||||
|
||||
entt::meta<clazz_t>()
|
||||
.type("clazz"_hs)
|
||||
@@ -612,7 +613,7 @@ TEST_F(MetaData, AsConstRef) {
|
||||
ASSERT_EQ(instance.i, 0);
|
||||
}
|
||||
|
||||
TEST_F(MetaData, FromBase) {
|
||||
TEST_F(MetaData, SetGetBaseData) {
|
||||
using namespace entt::literals;
|
||||
|
||||
auto type = entt::resolve<derived_t>();
|
||||
@@ -622,6 +623,21 @@ TEST_F(MetaData, FromBase) {
|
||||
|
||||
ASSERT_EQ(instance.value, 3);
|
||||
ASSERT_TRUE(type.data("value"_hs).set(instance, 42));
|
||||
ASSERT_EQ(type.data("value"_hs).get(instance).cast<int>(), 42);
|
||||
ASSERT_EQ(instance.value, 42);
|
||||
}
|
||||
|
||||
TEST_F(MetaData, SetGetFromBase) {
|
||||
using namespace entt::literals;
|
||||
|
||||
auto type = entt::resolve<derived_t>();
|
||||
derived_t instance{};
|
||||
|
||||
ASSERT_TRUE(type.data("value_from_base"_hs));
|
||||
|
||||
ASSERT_EQ(instance.value, 3);
|
||||
ASSERT_TRUE(type.data("value_from_base"_hs).set(instance, 42));
|
||||
ASSERT_EQ(type.data("value_from_base"_hs).get(instance).cast<int>(), 42);
|
||||
ASSERT_EQ(instance.value, 42);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,18 @@ struct base_t {
|
||||
++counter;
|
||||
}
|
||||
|
||||
void func(int v) {
|
||||
void setter(int v) {
|
||||
value = v;
|
||||
}
|
||||
|
||||
int getter() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
static void static_setter(base_t &ref, int v) {
|
||||
ref.value = v;
|
||||
}
|
||||
|
||||
inline static int counter = 0;
|
||||
int value{3};
|
||||
};
|
||||
@@ -86,13 +94,16 @@ struct MetaFunc: ::testing::Test {
|
||||
entt::meta<base_t>()
|
||||
.type("base"_hs)
|
||||
.dtor<base_t::destroy>()
|
||||
.func<&base_t::func>("func"_hs)
|
||||
.func<&base_t::setter>("setter"_hs)
|
||||
.func<fake_member>("fake_member"_hs)
|
||||
.func<fake_const_member>("fake_const_member"_hs);
|
||||
|
||||
entt::meta<derived_t>()
|
||||
.type("derived"_hs)
|
||||
.base<base_t>()
|
||||
.func<&base_t::setter>("setter_from_base"_hs)
|
||||
.func<&base_t::getter>("getter_from_base"_hs)
|
||||
.func<&base_t::static_setter>("static_setter_from_base"_hs)
|
||||
.dtor<derived_t::destroy>();
|
||||
|
||||
entt::meta<func_t>()
|
||||
@@ -474,20 +485,50 @@ TEST_F(MetaFunc, AsConstRef) {
|
||||
ASSERT_EQ(func.invoke(instance).cast<int>(), 3);
|
||||
}
|
||||
|
||||
TEST_F(MetaFunc, FromBase) {
|
||||
TEST_F(MetaFunc, InvokeBaseFunction) {
|
||||
using namespace entt::literals;
|
||||
|
||||
auto type = entt::resolve<derived_t>();
|
||||
derived_t instance{};
|
||||
|
||||
ASSERT_TRUE(type.func("func"_hs));
|
||||
ASSERT_TRUE(type.func("setter"_hs));
|
||||
ASSERT_EQ(instance.value, 3);
|
||||
|
||||
type.func("func"_hs).invoke(instance, 42);
|
||||
type.func("setter"_hs).invoke(instance, 42);
|
||||
|
||||
ASSERT_EQ(instance.value, 42);
|
||||
}
|
||||
|
||||
TEST_F(MetaFunc, InvokeFromBase) {
|
||||
using namespace entt::literals;
|
||||
|
||||
auto type = entt::resolve<derived_t>();
|
||||
derived_t instance{};
|
||||
|
||||
auto setter_from_base = type.func("setter_from_base"_hs);
|
||||
|
||||
ASSERT_TRUE(setter_from_base);
|
||||
ASSERT_EQ(instance.value, 3);
|
||||
|
||||
setter_from_base.invoke(instance, 42);
|
||||
|
||||
ASSERT_EQ(instance.value, 42);
|
||||
|
||||
auto getter_from_base = type.func("getter_from_base"_hs);
|
||||
|
||||
ASSERT_TRUE(getter_from_base);
|
||||
ASSERT_EQ(getter_from_base.invoke(instance).cast<int>(), 42);
|
||||
|
||||
auto static_setter_from_base = type.func("static_setter_from_base"_hs);
|
||||
|
||||
ASSERT_TRUE(static_setter_from_base);
|
||||
ASSERT_EQ(instance.value, 42);
|
||||
|
||||
static_setter_from_base.invoke(instance, 3);
|
||||
|
||||
ASSERT_EQ(instance.value, 3);
|
||||
}
|
||||
|
||||
TEST_F(MetaFunc, ExternalMemberFunction) {
|
||||
using namespace entt::literals;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user