meta: deprecate meta_[any|handle]::operator*, use ::ref instead
This commit is contained in:
@@ -227,7 +227,7 @@ different type than the one contained, so as to be able to handle the new
|
||||
instance.
|
||||
|
||||
A particularly interesting feature of this class is that it can also be used as
|
||||
an opaque container for unmanaged objects:
|
||||
an opaque container for non-const unmanaged objects:
|
||||
|
||||
```cpp
|
||||
int value;
|
||||
@@ -238,33 +238,25 @@ In other words, whenever `meta_any` intercepts a `reference_wrapper`, it acts as
|
||||
a reference to the original instance rather than making a copy of it. The
|
||||
contained object is never destroyed and users must ensure that its lifetime
|
||||
exceeds that of the container.<br/>
|
||||
Similarly, to create a copy that works as a _light_ reference for the managed
|
||||
object, it's possible to _dereference_ a given `meta_any` so as to invoke its
|
||||
aliasing constructor:
|
||||
Similarly, it's possible to create non-owning copies of `meta_any` from existing
|
||||
ones:
|
||||
|
||||
```cpp
|
||||
// aliasing constructor
|
||||
entt::meta_any ref = any.ref();
|
||||
```
|
||||
|
||||
This is also equivalent to:
|
||||
|
||||
```cpp
|
||||
// indirection operator
|
||||
entt::meta_any ref = *any;
|
||||
```
|
||||
|
||||
In both cases, it doesn't matter if the starting container actually holds an
|
||||
object or acts as a reference for unmanaged elements, the new instance thus
|
||||
created won't create copies and will only serve as a reference for the original
|
||||
item.<br/>
|
||||
In this case, it doesn't matter if the starting container actually holds an
|
||||
object or acts already as a reference for unmanaged elements, the new instance
|
||||
thus created won't create copies and will only serve as a reference for the
|
||||
original item.<br/>
|
||||
It means that, starting from the example above, both `ref` and` any` will point
|
||||
to the same object, whether it's initially contained in `any` or already an
|
||||
unmanaged one. This is particularly useful for passing instances of `meta_any`
|
||||
belonging to the external context by reference to a function or a constructor
|
||||
rather than making copies of them.
|
||||
|
||||
The `meta_any` class has also a `type` member function that returns the meta
|
||||
The `meta_any` class also has a `type` member function that returns the meta
|
||||
type of the contained value, if any. The member functions `try_cast`, `cast` and
|
||||
`convert` are then used to know if the underlying object has a given type as a
|
||||
base or if it can be converted implicitly to it.
|
||||
|
||||
@@ -83,7 +83,7 @@ template<typename Type, auto Data>
|
||||
using helper_type = meta_function_helper_t<decltype(Data)>;
|
||||
using data_type = std::tuple_element_t<!std::is_member_function_pointer_v<decltype(Data)>, typename helper_type::args_type>;
|
||||
|
||||
if(auto * const clazz = (*instance).try_cast<Type>(); clazz) {
|
||||
if(auto * const clazz = instance.ref().try_cast<Type>(); clazz) {
|
||||
if(auto * const direct = value.try_cast<data_type>(); direct || value.convert<data_type>()) {
|
||||
std::invoke(Data, *clazz, direct ? *direct : value.cast<data_type>());
|
||||
accepted = true;
|
||||
@@ -93,7 +93,7 @@ template<typename Type, auto Data>
|
||||
using data_type = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Type>().*Data)>>;
|
||||
|
||||
if constexpr(!std::is_array_v<data_type>) {
|
||||
if(auto * const clazz = (*instance).try_cast<Type>(); clazz) {
|
||||
if(auto * const clazz = instance.ref().try_cast<Type>(); clazz) {
|
||||
if(auto * const direct = value.try_cast<data_type>(); direct || value.convert<data_type>()) {
|
||||
std::invoke(Data, clazz) = (direct ? *direct : value.cast<data_type>());
|
||||
accepted = true;
|
||||
@@ -129,13 +129,13 @@ template<typename Type, auto Data, typename Policy>
|
||||
};
|
||||
|
||||
if constexpr(std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>> || std::is_member_function_pointer_v<decltype(Data)>) {
|
||||
auto * const clazz = (*instance).try_cast<Type>();
|
||||
auto * const clazz = instance.ref().try_cast<Type>();
|
||||
return clazz ? dispatch(std::invoke(Data, *clazz)) : meta_any{};
|
||||
} else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
|
||||
if constexpr(std::is_array_v<std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Type>().*Data)>>>) {
|
||||
return meta_any{};
|
||||
} else {
|
||||
auto * const clazz = (*instance).try_cast<Type>();
|
||||
auto * const clazz = instance.ref().try_cast<Type>();
|
||||
return clazz ? dispatch(std::invoke(Data, clazz)) : meta_any{};
|
||||
}
|
||||
} else if constexpr(std::is_pointer_v<std::decay_t<decltype(Data)>>) {
|
||||
@@ -179,7 +179,7 @@ template<typename Type, auto Candidate, typename Policy, std::size_t... Indexes>
|
||||
if constexpr(std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Candidate)>>>) {
|
||||
return (std::get<Indexes>(direct) && ...) ? dispatch(std::get<Indexes>(direct)...) : meta_any{};
|
||||
} else {
|
||||
auto * const clazz = (*instance).try_cast<Type>();
|
||||
auto * const clazz = instance.ref().try_cast<Type>();
|
||||
return (clazz && (std::get<Indexes>(direct) && ...)) ? dispatch(clazz, std::get<Indexes>(direct)...) : meta_any{};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,6 +455,7 @@ public:
|
||||
* @brief Indirection operator for aliasing construction.
|
||||
* @return A meta any that shares a reference to an unmanaged object.
|
||||
*/
|
||||
[[deprecated("use ::ref instead")]]
|
||||
[[nodiscard]] meta_any operator*() const ENTT_NOEXCEPT {
|
||||
return ref();
|
||||
}
|
||||
@@ -575,7 +576,7 @@ struct meta_container::meta_iterator {
|
||||
* @return The actual iterator, properly wrapped.
|
||||
*/
|
||||
[[nodiscard]] meta_any handle() const ENTT_NOEXCEPT {
|
||||
return *it;
|
||||
return it.ref();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -703,7 +704,7 @@ struct meta_handle {
|
||||
: meta_handle{}
|
||||
{
|
||||
if constexpr(std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_any>) {
|
||||
any = *value;
|
||||
any = value.ref();
|
||||
} else {
|
||||
static_assert(std::is_lvalue_reference_v<Type>, "Lvalue reference required");
|
||||
any = std::ref(value);
|
||||
@@ -711,6 +712,12 @@ struct meta_handle {
|
||||
}
|
||||
|
||||
/*! @copydoc meta_any::operator* */
|
||||
[[nodiscard]] meta_any ref() const {
|
||||
return any;
|
||||
}
|
||||
|
||||
/*! @copydoc meta_any::operator* */
|
||||
[[deprecated("use ::ref instead")]]
|
||||
[[nodiscard]] meta_any operator*() const {
|
||||
return any;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ TEST_F(MetaAny, SBOInPlaceTypeConstruction) {
|
||||
ASSERT_NE(entt::meta_any{3}, any);
|
||||
}
|
||||
|
||||
TEST_F(MetaAny, SBOAsAliasConstruction) {
|
||||
TEST_F(MetaAny, SBOAsRefConstruction) {
|
||||
int value = 3;
|
||||
int other = 42;
|
||||
entt::meta_any any{std::ref(value)};
|
||||
@@ -190,7 +190,7 @@ TEST_F(MetaAny, NoSBOInPlaceTypeConstruction) {
|
||||
ASSERT_NE(entt::meta_any{fat_t{}}, any);
|
||||
}
|
||||
|
||||
TEST_F(MetaAny, NoSBOAsAliasConstruction) {
|
||||
TEST_F(MetaAny, NoSBOAsRefConstruction) {
|
||||
int value = 3;
|
||||
fat_t instance{&value};
|
||||
entt::meta_any any{std::ref(instance)};
|
||||
|
||||
@@ -295,7 +295,7 @@ TEST_F(MetaFunc, AsVoid) {
|
||||
ASSERT_EQ(instance.value, 42);
|
||||
}
|
||||
|
||||
TEST_F(MetaFunc, AsAlias) {
|
||||
TEST_F(MetaFunc, AsRef) {
|
||||
func_t instance{};
|
||||
auto func = entt::resolve<func_t>().func("a"_hs);
|
||||
func.invoke(instance).cast<int>() = 3;
|
||||
|
||||
Reference in New Issue
Block a user