meta: deprecate meta_[any|handle]::operator*, use ::ref instead

This commit is contained in:
Michele Caini
2020-06-18 17:37:07 +02:00
parent 932e681d22
commit 1d450ef27e
5 changed files with 25 additions and 26 deletions

View File

@@ -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.

View File

@@ -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{};
}
}

View File

@@ -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;
}

View File

@@ -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)};

View File

@@ -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;