diff --git a/docs/md/meta.md b/docs/md/meta.md index 4f487ef36..9faab0833 100644 --- a/docs/md/meta.md +++ b/docs/md/meta.md @@ -712,33 +712,30 @@ There are a few alternatives available at the moment: * The _as-void_ policy, associated with the type `entt::as_void_t`.
Its purpose is to discard the return value of a meta object, whatever it is, - thus making it appear as if its type were `void`.
+ thus making it appear as if its type were `void`: + ```cpp + entt::meta().func<&my_type::member_function, entt::as_void_t>("member"_hs); + ``` If the use with functions is obvious, it must be said that it's also possible to use this policy with constructors and data members. In the first case, the constructor will be invoked but the returned wrapper will actually be empty. In the second case, instead, the property will not be accessible for reading. - As an example of use: - - ```cpp - entt::meta().func<&my_type::member_function, entt::as_void_t>("member"_hs); - ``` - * The _as-ref_ and _as-cref_ policies, associated with the types `entt::as_ref_t` and `entt::as_cref_t`.
They allow to build wrappers that act as references to unmanaged objects. Accessing the object contained in the wrapper for which the _reference_ was requested will make it possible to directly access the instance used to - initialize the wrapper itself.
- These policies work with constructors (for example, when objects are taken - from an external container rather than created on demand), data members and - functions in general (as long as their return types are lvalue references). - - As an example of use: - + initialize the wrapper itself: ```cpp entt::meta().data<&my_type::data_member, entt::as_ref_t>("member"_hs); ``` + These policies work with constructors (for example, when objects are taken + from an external container rather than created on demand), data members and + functions in general.
+ If on the one hand `as_cref_t` always forces the return type to be const, + `as_ref_t` _adapts_ to the constness of the passed object and to that of the + return type if any. Some uses are rather trivial, but it's useful to note that there are some less obvious corner cases that can in turn be solved with the use of policies. @@ -763,8 +760,8 @@ Exporting constant values or elements from an enum is as simple as ever: ```cpp entt::meta() - .data("a_value"_hs) - .data("another_value"_hs); + .data("a_value"_hs) + .data("another_value"_hs); entt::meta().data<2048>("max_int"_hs); ``` diff --git a/src/entt/meta/factory.hpp b/src/entt/meta/factory.hpp index ec8b836b9..53a99740d 100644 --- a/src/entt/meta/factory.hpp +++ b/src/entt/meta/factory.hpp @@ -123,7 +123,7 @@ template if constexpr(std::is_same_v) { return meta_any{std::in_place_type, std::forward(value)}; } else if constexpr(std::is_same_v) { - return meta_any{std::ref(std::forward(value))}; + return meta_any{std::reference_wrapper{std::forward(value)}}; } else if constexpr(std::is_same_v) { return meta_any{std::cref(std::forward(value))}; } else { @@ -139,8 +139,12 @@ template if constexpr(std::is_array_v().*Data)>>>) { return meta_any{}; } else { - auto * const clazz = instance->try_cast, Type, const Type>>(); - return clazz ? dispatch(std::invoke(Data, clazz)) : meta_any{}; + if(auto * clazz = instance->try_cast(); clazz) { + return dispatch(std::invoke(Data, *clazz)); + } else { + auto * fallback = instance->try_cast(); + return fallback ? dispatch(std::invoke(Data, *fallback)) : meta_any{}; + } } } else if constexpr(std::is_pointer_v>) { if constexpr(std::is_array_v>) { @@ -163,7 +167,7 @@ template std::invoke(Candidate, std::forward(params)...); return meta_any{std::in_place_type}; } else if constexpr(std::is_same_v) { - return meta_any{std::ref(std::invoke(Candidate, std::forward(params)...))}; + return meta_any{std::reference_wrapper{std::invoke(Candidate, std::forward(params)...)}}; } else if constexpr(std::is_same_v) { return meta_any{std::cref(std::invoke(Candidate, std::forward(params)...))}; } else { diff --git a/test/entt/meta/meta_data.cpp b/test/entt/meta/meta_data.cpp index f4c96cc5a..f35add512 100644 --- a/test/entt/meta/meta_data.cpp +++ b/test/entt/meta/meta_data.cpp @@ -418,9 +418,15 @@ TEST_F(MetaData, ConstInstance) { clazz_t instance{}; + ASSERT_NE(entt::resolve().data("i"_hs).get(instance).try_cast(), nullptr); + ASSERT_NE(entt::resolve().data("i"_hs).get(instance).try_cast(), nullptr); + ASSERT_EQ(entt::resolve().data("i"_hs).get(std::as_const(instance)).try_cast(), nullptr); + // as_ref_t adapts to the constness of the passed object and returns const references in case + ASSERT_NE(entt::resolve().data("i"_hs).get(std::as_const(instance)).try_cast(), nullptr); + ASSERT_TRUE(entt::resolve().data("i"_hs).get(instance)); ASSERT_TRUE(entt::resolve().data("i"_hs).set(instance, 3)); - ASSERT_FALSE(entt::resolve().data("i"_hs).get(std::as_const(instance))); + ASSERT_TRUE(entt::resolve().data("i"_hs).get(std::as_const(instance))); ASSERT_FALSE(entt::resolve().data("i"_hs).set(std::as_const(instance), 3)); ASSERT_TRUE(entt::resolve().data("ci"_hs).get(instance));