meta: allow read-only data registration in meta (close #496)

This commit is contained in:
Michele Caini
2020-05-29 00:54:39 +02:00
parent c8a6465688
commit 52faa1bec5
2 changed files with 41 additions and 3 deletions

View File

@@ -705,7 +705,6 @@ public:
template<auto Setter, auto Getter, typename Policy = as_is_t>
auto data(const id_type id) ENTT_NOEXCEPT {
using underlying_type = std::invoke_result_t<decltype(Getter), Type &>;
static_assert(std::is_invocable_v<decltype(Setter), Type &, underlying_type>, "Invalid setter and/or getter");
auto * const type = internal::meta_info<Type>::resolve();
static internal::meta_data_node node{
@@ -715,7 +714,14 @@ public:
nullptr,
false,
&internal::meta_info<underlying_type>::resolve,
&internal::setter<Type, Setter>,
[]() -> decltype(internal::meta_data_node::set) {
if constexpr(Setter == nullptr) {
return Setter;
} else {
static_assert(std::is_invocable_v<decltype(Setter), Type &, underlying_type>, "Invalid setter");
return &internal::setter<Type, Setter>;
}
}(),
&internal::getter<Type, Getter, Policy>
};

View File

@@ -241,7 +241,9 @@ struct Meta: ::testing::Test {
.data<&setter_getter_type::static_setter, &setter_getter_type::static_getter>("x"_hs)
.data<&setter_getter_type::setter, &setter_getter_type::getter>("y"_hs)
.data<&setter_getter_type::static_setter, &setter_getter_type::getter>("z"_hs)
.data<&setter_getter_type::setter_with_ref, &setter_getter_type::getter_with_ref>("w"_hs);
.data<&setter_getter_type::setter_with_ref, &setter_getter_type::getter_with_ref>("w"_hs)
.data<nullptr, &setter_getter_type::getter>("z_ro"_hs)
.data<nullptr, &setter_getter_type::value>("value"_hs);
entt::meta<an_abstract_type>()
.type("an_abstract_type"_hs)
@@ -1257,6 +1259,36 @@ TEST_F(Meta, MetaDataSetterGetterMixed) {
ASSERT_EQ(data.get(instance).cast<int>(), 42);
}
TEST_F(Meta, MetaDataSetterGetterReadOnly) {
auto data = entt::resolve<setter_getter_type>().data("z_ro"_hs);
setter_getter_type instance{};
ASSERT_TRUE(data);
ASSERT_EQ(data.parent(), entt::resolve_id("setter_getter"_hs));
ASSERT_EQ(data.type(), entt::resolve<int>());
ASSERT_EQ(data.id(), "z_ro"_hs);
ASSERT_TRUE(data.is_const());
ASSERT_FALSE(data.is_static());
ASSERT_EQ(data.get(instance).cast<int>(), 0);
ASSERT_FALSE(data.set(instance, 42));
ASSERT_EQ(data.get(instance).cast<int>(), 0);
}
TEST_F(Meta, MetaDataSetterGetterReadOnlyDataMember) {
auto data = entt::resolve<setter_getter_type>().data("value"_hs);
setter_getter_type instance{};
ASSERT_TRUE(data);
ASSERT_EQ(data.parent(), entt::resolve_id("setter_getter"_hs));
ASSERT_EQ(data.type(), entt::resolve<int>());
ASSERT_EQ(data.id(), "value"_hs);
ASSERT_TRUE(data.is_const());
ASSERT_FALSE(data.is_static());
ASSERT_EQ(data.get(instance).cast<int>(), 0);
ASSERT_FALSE(data.set(instance, 42));
ASSERT_EQ(data.get(instance).cast<int>(), 0);
}
TEST_F(Meta, MetaDataArrayStatic) {
auto data = entt::resolve<array_type>().data("global"_hs);