meta: support for dereferencing pointers to functions
This commit is contained in:
@@ -357,7 +357,11 @@ class meta_any {
|
||||
case operation::DEREF:
|
||||
case operation::CDEREF:
|
||||
if constexpr(is_meta_pointer_like_v<Type>) {
|
||||
if constexpr(!std::is_same_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>, void>) {
|
||||
using element_type = std::remove_const_t<typename std::pointer_traits<Type>::element_type>;
|
||||
|
||||
if constexpr(std::is_function_v<element_type>) {
|
||||
*static_cast<meta_any *>(to) = any_cast<const Type>(from);
|
||||
} else if constexpr(!std::is_same_v<element_type, void>) {
|
||||
auto &&obj = adl_meta_pointer_like<Type>::dereference(any_cast<const Type>(from));
|
||||
*static_cast<meta_any *>(to) = (op == operation::DEREF ? meta_any{std::reference_wrapper{obj}} : meta_any{std::cref(obj)});
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ struct entt::adl_meta_pointer_like<spec_wrapped_shared_ptr<Type>> {
|
||||
}
|
||||
};
|
||||
|
||||
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<const int>{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<const void *>(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<void>{});
|
||||
test(std::unique_ptr<void, void(*)(void *)>{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<void()>());
|
||||
|
||||
auto deref = *any;
|
||||
|
||||
ASSERT_TRUE(deref.type().is_pointer());
|
||||
ASSERT_TRUE(deref.type().is_pointer_like());
|
||||
ASSERT_EQ(deref.type().remove_pointer(), entt::resolve<void()>());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user