meta: add meta_type::can_convert (close #1028)
This commit is contained in:
@@ -1333,6 +1333,14 @@ public:
|
||||
return internal::try_cast(internal::meta_context::from(*ctx), node, other.node, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a type supports conversion it to another type.
|
||||
* @return True if the conversion is allowed, false otherwise.
|
||||
*/
|
||||
[[nodiscard]] bool can_convert(const meta_type &other) const noexcept {
|
||||
return internal::can_convert(internal::meta_context::from(*ctx), node, other.node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a range to visit registered top-level base meta types.
|
||||
* @return An iterable range to visit registered top-level base meta types.
|
||||
|
||||
@@ -159,6 +159,26 @@ template<typename... Args>
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool can_convert(const meta_context &context, const meta_type_node &from, const meta_type_node &to) noexcept {
|
||||
if((from.info && *from.info == *to.info) || (from.conversion_helper && static_cast<bool>(to.traits & (meta_traits::is_arithmetic | meta_traits::is_enum)))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(from.details) {
|
||||
if(auto it = from.details->conv.find(to.info->hash()); it != from.details->conv.cend()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for(auto &&curr: from.details->base) {
|
||||
if(can_convert(context, curr.second.type(context), to)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline const meta_type_node *try_resolve(const meta_context &context, const type_info &info) noexcept {
|
||||
const auto it = context.value.find(info.hash());
|
||||
return it != context.value.end() ? &it->second : nullptr;
|
||||
|
||||
@@ -311,6 +311,24 @@ TEST_F(MetaType, CanCast) {
|
||||
ASSERT_TRUE(type.can_cast(entt::resolve<derived_t>()));
|
||||
}
|
||||
|
||||
TEST_F(MetaType, CanConvert) {
|
||||
auto clazz = entt::resolve<clazz_t>();
|
||||
auto derived = entt::resolve<derived_t>();
|
||||
auto arithmetic = entt::resolve<int>();
|
||||
|
||||
ASSERT_TRUE(clazz.can_convert(entt::resolve<clazz_t>()));
|
||||
ASSERT_TRUE(clazz.can_convert(entt::resolve<int>()));
|
||||
|
||||
ASSERT_TRUE(derived.can_convert(entt::resolve<derived_t>()));
|
||||
ASSERT_TRUE(derived.can_convert(entt::resolve<base_t>()));
|
||||
ASSERT_FALSE(derived.can_convert(entt::resolve<int>()));
|
||||
|
||||
ASSERT_TRUE(arithmetic.can_convert(entt::resolve<int>()));
|
||||
ASSERT_FALSE(arithmetic.can_convert(entt::resolve<clazz_t>()));
|
||||
ASSERT_TRUE(arithmetic.can_convert(entt::resolve<double>()));
|
||||
ASSERT_TRUE(arithmetic.can_convert(entt::resolve<float>()));
|
||||
}
|
||||
|
||||
TEST_F(MetaType, Base) {
|
||||
auto type = entt::resolve<derived_t>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user