From 39ecd1545cb439fbc321ee95fdb757368b18590a Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 13 Jan 2021 13:14:21 +0100 Subject: [PATCH] meta: support for dereferencing pointers to functions --- src/entt/meta/meta.hpp | 6 +++++- test/entt/meta/meta_pointer.cpp | 20 ++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 5f2e69da7..b6ff1f24b 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -357,7 +357,11 @@ class meta_any { case operation::DEREF: case operation::CDEREF: if constexpr(is_meta_pointer_like_v) { - if constexpr(!std::is_same_v::element_type>, void>) { + using element_type = std::remove_const_t::element_type>; + + if constexpr(std::is_function_v) { + *static_cast(to) = any_cast(from); + } else if constexpr(!std::is_same_v) { auto &&obj = adl_meta_pointer_like::dereference(any_cast(from)); *static_cast(to) = (op == operation::DEREF ? meta_any{std::reference_wrapper{obj}} : meta_any{std::cref(obj)}); } diff --git a/test/entt/meta/meta_pointer.cpp b/test/entt/meta/meta_pointer.cpp index cceb1cedf..51805c88b 100644 --- a/test/entt/meta/meta_pointer.cpp +++ b/test/entt/meta/meta_pointer.cpp @@ -40,6 +40,8 @@ struct entt::adl_meta_pointer_like> { } }; +void test_function() {} + struct not_copyable_t { not_copyable_t() = default; not_copyable_t(const not_copyable_t &) = delete; @@ -242,7 +244,7 @@ TEST(MetaPointerLike, DereferencePointerToConstOverload) { test(spec_wrapped_shared_ptr{42}); } -TEST(MetaPointerLike, PointerToVoidSupport) { +TEST(MetaPointerLike, DereferencePointerToVoid) { auto test = [](entt::meta_any any) { ASSERT_TRUE(any.type().is_pointer()); ASSERT_TRUE(any.type().is_pointer_like()); @@ -257,7 +259,7 @@ TEST(MetaPointerLike, PointerToVoidSupport) { test(static_cast(nullptr)); } -TEST(MetaPointerLike, SmartPointerToVoidSupport) { +TEST(MetaPointerLike, DereferenceSmartPointerToVoid) { auto test = [](entt::meta_any any) { ASSERT_TRUE(any.type().is_class()); ASSERT_FALSE(any.type().is_pointer()); @@ -271,3 +273,17 @@ TEST(MetaPointerLike, SmartPointerToVoidSupport) { test(std::shared_ptr{}); test(std::unique_ptr{nullptr, nullptr}); } + +TEST(MetaPointerLike, DereferencePointerToFunction) { + entt::meta_any any{&test_function}; + + ASSERT_TRUE(any.type().is_pointer()); + ASSERT_TRUE(any.type().is_pointer_like()); + ASSERT_EQ(any.type().remove_pointer(), entt::resolve()); + + auto deref = *any; + + ASSERT_TRUE(deref.type().is_pointer()); + ASSERT_TRUE(deref.type().is_pointer_like()); + ASSERT_EQ(deref.type().remove_pointer(), entt::resolve()); +}