diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 674eaca23..600043470 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -215,7 +215,7 @@ public: template meta_any(std::reference_wrapper value) : storage{value}, - vtable{&basic_vtable>}, + vtable{&basic_vtable}, node{internal::meta_info::resolve()} {} diff --git a/src/entt/meta/type_traits.hpp b/src/entt/meta/type_traits.hpp index edb8d94e2..7f0632227 100644 --- a/src/entt/meta/type_traits.hpp +++ b/src/entt/meta/type_traits.hpp @@ -105,6 +105,15 @@ template struct is_meta_pointer_like: std::false_type {}; +/** + * @brief Partial specialization to ensure that const pointer-like types are + * also accepted. + * @tparam Type Potentially pointer-like type. + */ +template +struct is_meta_pointer_like: is_meta_pointer_like {}; + + /** * @brief Helper variable template. * @tparam Type Potentially pointer-like type. diff --git a/test/entt/meta/meta_pointer.cpp b/test/entt/meta/meta_pointer.cpp index 0c8f258ce..47f388a02 100644 --- a/test/entt/meta/meta_pointer.cpp +++ b/test/entt/meta/meta_pointer.cpp @@ -42,7 +42,7 @@ TEST(MetaPointerLike, DereferenceOperatorConstType) { ASSERT_EQ(deref.try_cast(), nullptr); ASSERT_EQ(deref.try_cast(), &value); - ASSERT_DEATH(deref.cast(), ".*"); + ASSERT_DEATH(deref.cast() = 0, ".*"); ASSERT_EQ(deref.cast(), 42); } @@ -96,7 +96,51 @@ TEST(MetaPointerLike, PointerToConstMoveOnlyType) { ASSERT_TRUE(any); ASSERT_TRUE(deref); - ASSERT_DEATH(deref.cast(), ".*"); + ASSERT_DEATH(deref.cast() = {}, ".*"); ASSERT_EQ(deref.try_cast(), nullptr); ASSERT_NE(deref.try_cast(), nullptr); } + +TEST(MetaPointerLike, AsRef) { + int value = 0; + int * ptr = &value; + entt::meta_any any{std::ref(ptr)}; + + ASSERT_TRUE(any.type().is_pointer()); + ASSERT_TRUE(any.type().is_pointer_like()); + ASSERT_EQ(any.type(), entt::resolve()); + + auto deref = *any; + + ASSERT_TRUE(deref); + ASSERT_FALSE(deref.type().is_pointer()); + ASSERT_FALSE(deref.type().is_pointer_like()); + ASSERT_EQ(deref.type(), entt::resolve()); + + deref.cast() = 42; + + ASSERT_EQ(*any.cast(), 42); + ASSERT_EQ(value, 42); +} + +TEST(MetaPointerLike, AsConstRef) { + int value = 42; + int * ptr = &value; + entt::meta_any any{std::cref(ptr)}; + + ASSERT_TRUE(any.type().is_pointer()); + ASSERT_TRUE(any.type().is_pointer_like()); + ASSERT_EQ(any.type(), entt::resolve()); + + auto deref = *any; + + ASSERT_TRUE(deref); + ASSERT_FALSE(deref.type().is_pointer()); + ASSERT_FALSE(deref.type().is_pointer_like()); + ASSERT_EQ(deref.type(), entt::resolve()); + + deref.cast() = 42; + + ASSERT_EQ(*any.cast(), 42); + ASSERT_EQ(value, 42); +}