meta: added support to self pointer in meta_any

This commit is contained in:
Michele Caini
2021-01-29 22:09:13 +01:00
parent a03a569534
commit 1c1c3eb271
2 changed files with 25 additions and 5 deletions

View File

@@ -378,7 +378,7 @@ class meta_any {
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));
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)});
}
}

View File

@@ -16,6 +16,12 @@ private:
std::shared_ptr<Type> ptr;
};
struct self {
using element_type = int;
const self & operator*() const { return *this; }
int value{};
};
template<typename Type>
struct adl_wrapped_shared_ptr: wrapped_shared_ptr<Type> {};
@@ -28,10 +34,8 @@ struct entt::is_meta_pointer_like<adl_wrapped_shared_ptr<Type>>: std::true_type
template<typename Type>
struct entt::is_meta_pointer_like<spec_wrapped_shared_ptr<Type>>: std::true_type {};
template<typename Type>
Type & dereference_meta_pointer_like(const adl_wrapped_shared_ptr<Type> &ptr) {
return ptr.deref();
}
template<>
struct entt::is_meta_pointer_like<self>: std::true_type {};
template<typename Type>
struct entt::adl_meta_pointer_like<spec_wrapped_shared_ptr<Type>> {
@@ -40,6 +44,11 @@ struct entt::adl_meta_pointer_like<spec_wrapped_shared_ptr<Type>> {
}
};
template<typename Type>
Type & dereference_meta_pointer_like(const adl_wrapped_shared_ptr<Type> &ptr) {
return ptr.deref();
}
int test_function() { return 42; }
struct not_copyable_t {
@@ -287,3 +296,14 @@ TEST(MetaPointerLike, DereferencePointerToFunction) {
test(*entt::meta_any{&test_function});
test(**entt::meta_any{&test_function});
}
TEST(MetaPointerLike, DereferenceSelfPointer) {
self obj{42};
entt::meta_any any{std::ref(obj)};
entt::meta_any deref = *any;
ASSERT_TRUE(deref);
ASSERT_TRUE(any.type().is_pointer_like());
ASSERT_FALSE(deref.try_cast<self>());
ASSERT_EQ(deref.cast<const self &>().value, obj.value);
}