any_cast: review any_cast for better support to const references
This commit is contained in:
@@ -270,7 +270,7 @@ private:
|
||||
*/
|
||||
template<typename Type>
|
||||
Type any_cast(const any &data) ENTT_NOEXCEPT {
|
||||
auto * const instance = any_cast<std::remove_cv_t<std::remove_reference_t<Type>>>(&data);
|
||||
auto * const instance = any_cast<std::remove_reference_t<Type>>(&data);
|
||||
ENTT_ASSERT(instance);
|
||||
return static_cast<Type>(*instance);
|
||||
}
|
||||
@@ -279,23 +279,16 @@ Type any_cast(const any &data) ENTT_NOEXCEPT {
|
||||
/*! @copydoc any_cast */
|
||||
template<typename Type>
|
||||
Type any_cast(any &data) ENTT_NOEXCEPT {
|
||||
if constexpr(!std::is_reference_v<Type> || std::is_const_v<std::remove_reference_t<Type>>) {
|
||||
// last attempt to make wrappers for const references return their values
|
||||
auto * const instance = any_cast<std::remove_cv_t<std::remove_reference_t<Type>>>(&std::as_const(data));
|
||||
ENTT_ASSERT(instance);
|
||||
return static_cast<Type>(*instance);
|
||||
} else {
|
||||
auto * const instance = any_cast<std::remove_cv_t<std::remove_reference_t<Type>>>(&data);
|
||||
ENTT_ASSERT(instance);
|
||||
return static_cast<Type>(*instance);
|
||||
}
|
||||
auto * const instance = any_cast<std::conditional_t<std::is_reference_v<Type>, std::remove_reference_t<Type>, const Type>>(&data);
|
||||
ENTT_ASSERT(instance);
|
||||
return static_cast<Type>(*instance);
|
||||
}
|
||||
|
||||
|
||||
/*! @copydoc any_cast */
|
||||
template<typename Type>
|
||||
Type any_cast(any &&data) ENTT_NOEXCEPT {
|
||||
auto * const instance = any_cast<std::remove_cv_t<std::remove_reference_t<Type>>>(&data);
|
||||
auto * const instance = any_cast<std::conditional_t<std::is_reference_v<Type>, std::remove_reference_t<Type>, const Type>>(&data);
|
||||
ENTT_ASSERT(instance);
|
||||
return static_cast<Type>(std::move(*instance));
|
||||
}
|
||||
@@ -311,7 +304,12 @@ const Type * any_cast(const any *data) ENTT_NOEXCEPT {
|
||||
/*! @copydoc any_cast */
|
||||
template<typename Type>
|
||||
Type * any_cast(any *data) ENTT_NOEXCEPT {
|
||||
return (data->type() == type_id<Type>() ? static_cast<Type *>(data->data()) : nullptr);
|
||||
if constexpr(std::is_const_v<Type>) {
|
||||
// last attempt to make wrappers for const references return their values
|
||||
return any_cast<std::remove_const_t<Type>>(&std::as_const(*data));
|
||||
} else {
|
||||
return (data->type() == type_id<Type>() ? static_cast<Type *>(data->data()) : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -68,9 +68,18 @@ TEST(Any, SBOAsRefConstruction) {
|
||||
|
||||
ASSERT_TRUE(any);
|
||||
ASSERT_EQ(any.type(), entt::type_id<int>());
|
||||
|
||||
ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
|
||||
ASSERT_EQ(entt::any_cast<const int>(&any), &value);
|
||||
ASSERT_EQ(entt::any_cast<int>(&any), &value);
|
||||
ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
|
||||
ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
|
||||
|
||||
ASSERT_EQ(entt::any_cast<const int &>(any), 42);
|
||||
ASSERT_EQ(entt::any_cast<int>(any), 42);
|
||||
|
||||
ASSERT_EQ(any.data(), &value);
|
||||
ASSERT_EQ(std::as_const(any).data(), &value);
|
||||
|
||||
auto other = as_ref(any);
|
||||
|
||||
@@ -86,10 +95,16 @@ TEST(Any, SBOAsConstRefConstruction) {
|
||||
|
||||
ASSERT_TRUE(any);
|
||||
ASSERT_EQ(any.type(), entt::type_id<int>());
|
||||
|
||||
ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
|
||||
ASSERT_EQ(entt::any_cast<const int>(&any), &value);
|
||||
ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
|
||||
ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
|
||||
ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
|
||||
|
||||
ASSERT_EQ(entt::any_cast<const int &>(any), 42);
|
||||
ASSERT_EQ(entt::any_cast<int>(any), 42);
|
||||
|
||||
ASSERT_EQ(any.data(), nullptr);
|
||||
ASSERT_EQ(std::as_const(any).data(), &value);
|
||||
|
||||
@@ -186,9 +201,18 @@ TEST(Any, NoSBOAsRefConstruction) {
|
||||
|
||||
ASSERT_TRUE(any);
|
||||
ASSERT_EQ(any.type(), entt::type_id<fat>());
|
||||
|
||||
ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
|
||||
ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
|
||||
ASSERT_EQ(entt::any_cast<fat>(&any), &instance);
|
||||
ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
|
||||
ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
|
||||
|
||||
ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
|
||||
ASSERT_EQ(entt::any_cast<fat>(any), instance);
|
||||
|
||||
ASSERT_EQ(any.data(), &instance);
|
||||
ASSERT_EQ(std::as_const(any).data(), &instance);
|
||||
|
||||
auto other = as_ref(any);
|
||||
|
||||
@@ -204,10 +228,16 @@ TEST(Any, NoSBOAsConstRefConstruction) {
|
||||
|
||||
ASSERT_TRUE(any);
|
||||
ASSERT_EQ(any.type(), entt::type_id<fat>());
|
||||
|
||||
ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
|
||||
ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
|
||||
ASSERT_EQ(entt::any_cast<fat>(&any), nullptr);
|
||||
ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
|
||||
ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
|
||||
|
||||
ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
|
||||
ASSERT_EQ(entt::any_cast<fat>(any), instance);
|
||||
|
||||
ASSERT_EQ(any.data(), nullptr);
|
||||
ASSERT_EQ(std::as_const(any).data(), &instance);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user