mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 19:41:29 +07:00
add uvalue::is
This commit is contained in:
@@ -23,6 +23,7 @@ Diagnostics:
|
||||
- readability-named-parameter
|
||||
- readability-redundant-access-specifiers
|
||||
- readability-simplify-boolean-expr
|
||||
- readability-use-anyofallof
|
||||
|
||||
CompileFlags:
|
||||
CompilationDatabase: ../develop/.cdb
|
||||
|
||||
@@ -140,11 +140,6 @@ namespace meta_hpp::detail
|
||||
const any_type& from_type = get_raw_type();
|
||||
const any_type& to_type = registry.resolve_type<to_raw_type>();
|
||||
|
||||
const auto is_a = [](const any_type& base, const any_type& derived) {
|
||||
return (base == derived) //
|
||||
|| (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class()));
|
||||
};
|
||||
|
||||
if ( from_type.is_nullptr() && to_type.is_pointer() ) {
|
||||
return true;
|
||||
}
|
||||
@@ -160,7 +155,7 @@ namespace meta_hpp::detail
|
||||
const any_type& from_data_type = from_type_array.get_data_type();
|
||||
|
||||
if ( to_type_ptr_readonly >= from_type_array_readonly ) {
|
||||
if ( to_data_type.is_void() || is_a(to_data_type, from_data_type) ) {
|
||||
if ( to_data_type.is_void() || is_base_of(to_data_type, from_data_type) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -177,7 +172,7 @@ namespace meta_hpp::detail
|
||||
const any_type& from_data_type = from_type_ptr.get_data_type();
|
||||
|
||||
if ( to_type_ptr_readonly >= from_type_ptr_readonly ) {
|
||||
if ( to_data_type.is_void() || is_a(to_data_type, from_data_type) ) {
|
||||
if ( to_data_type.is_void() || is_base_of(to_data_type, from_data_type) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -200,11 +195,6 @@ namespace meta_hpp::detail
|
||||
const any_type& from_type = get_raw_type();
|
||||
const any_type& to_type = registry.resolve_type<to_raw_type>();
|
||||
|
||||
const auto is_a = [](const any_type& base, const any_type& derived) {
|
||||
return (base == derived) //
|
||||
|| (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class()));
|
||||
};
|
||||
|
||||
const auto is_convertible_to_ref = [this]<typename ToRef>(type_list<ToRef>) {
|
||||
switch ( get_ref_type() ) {
|
||||
case ref_types::lvalue:
|
||||
@@ -234,13 +224,13 @@ namespace meta_hpp::detail
|
||||
};
|
||||
|
||||
if constexpr ( std::is_reference_v<To> ) {
|
||||
if ( is_a(to_type, from_type) && is_convertible_to_ref(type_list<To>{}) ) {
|
||||
if ( is_base_of(to_type, from_type) && is_convertible_to_ref(type_list<To>{}) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr ( !std::is_pointer_v<To> && !std::is_reference_v<To> ) {
|
||||
if ( is_a(to_type, from_type) && is_constructible_from_type(type_list<to_raw_type>{}) ) {
|
||||
if ( is_base_of(to_type, from_type) && is_constructible_from_type(type_list<to_raw_type>{}) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -281,7 +271,7 @@ namespace meta_hpp::detail
|
||||
const class_type& to_data_class = to_data_type.as_class();
|
||||
const class_type& from_data_class = from_data_type.as_class();
|
||||
|
||||
void* to_ptr = pointer_upcast(registry, data_, from_data_class, to_data_class);
|
||||
void* to_ptr = pointer_upcast(data_, from_data_class, to_data_class);
|
||||
return static_cast<to_raw_type_cv>(to_ptr);
|
||||
}
|
||||
}
|
||||
@@ -303,7 +293,7 @@ namespace meta_hpp::detail
|
||||
const class_type& to_data_class = to_data_type.as_class();
|
||||
const class_type& from_data_class = from_data_type.as_class();
|
||||
|
||||
void* to_ptr = pointer_upcast(registry, *from_data_ptr, from_data_class, to_data_class);
|
||||
void* to_ptr = pointer_upcast(*from_data_ptr, from_data_class, to_data_class);
|
||||
return static_cast<to_raw_type_cv>(to_ptr);
|
||||
}
|
||||
}
|
||||
@@ -329,7 +319,7 @@ namespace meta_hpp::detail
|
||||
|
||||
void* to_ptr = to_type == from_type //
|
||||
? data_
|
||||
: pointer_upcast(registry, data_, from_type.as_class(), to_type.as_class());
|
||||
: pointer_upcast(data_, from_type.as_class(), to_type.as_class());
|
||||
|
||||
if constexpr ( std::is_lvalue_reference_v<To> ) {
|
||||
return *static_cast<to_raw_type_cv*>(to_ptr);
|
||||
|
||||
@@ -134,11 +134,6 @@ namespace meta_hpp::detail
|
||||
const any_type& from_type = get_raw_type();
|
||||
const any_type& to_type = registry.resolve_type<inst_class>();
|
||||
|
||||
const auto is_a = [](const any_type& base, const any_type& derived) {
|
||||
return (base == derived) //
|
||||
|| (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class()));
|
||||
};
|
||||
|
||||
if ( from_type.is_class() ) {
|
||||
const auto is_invocable = [this]() {
|
||||
switch ( get_ref_type() ) {
|
||||
@@ -154,7 +149,7 @@ namespace meta_hpp::detail
|
||||
return false;
|
||||
};
|
||||
|
||||
return is_invocable() && is_a(to_type, from_type);
|
||||
return is_invocable() && is_base_of(to_type, from_type);
|
||||
}
|
||||
|
||||
if ( from_type.is_pointer() ) {
|
||||
@@ -167,7 +162,7 @@ namespace meta_hpp::detail
|
||||
: std::is_invocable_v<inst_method, inst_class&>;
|
||||
};
|
||||
|
||||
return is_invocable() && is_a(to_type, from_data_type);
|
||||
return is_invocable() && is_base_of(to_type, from_data_type);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -190,7 +185,7 @@ namespace meta_hpp::detail
|
||||
const class_type& from_class = from_type.as_class();
|
||||
const class_type& to_class = to_type.as_class();
|
||||
|
||||
void* to_ptr = pointer_upcast(registry, data_, from_class, to_class);
|
||||
void* to_ptr = pointer_upcast(data_, from_class, to_class);
|
||||
|
||||
if constexpr ( !std::is_reference_v<Q> ) {
|
||||
return *static_cast<inst_class_cv*>(to_ptr);
|
||||
@@ -214,7 +209,7 @@ namespace meta_hpp::detail
|
||||
const class_type& to_class = to_type.as_class();
|
||||
|
||||
void** from_data_ptr = static_cast<void**>(data_);
|
||||
void* to_ptr = pointer_upcast(registry, *from_data_ptr, from_data_class, to_class);
|
||||
void* to_ptr = pointer_upcast(*from_data_ptr, from_data_class, to_class);
|
||||
|
||||
if constexpr ( !std::is_reference_v<Q> ) {
|
||||
return *static_cast<inst_class_cv*>(to_ptr);
|
||||
|
||||
@@ -110,12 +110,25 @@ namespace meta_hpp::detail
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
[[nodiscard]] inline void* pointer_upcast( //
|
||||
type_registry& registry,
|
||||
void* ptr,
|
||||
const class_type& from,
|
||||
const class_type& to
|
||||
) {
|
||||
[[nodiscard]] inline bool is_base_of(const any_type& base, const any_type& derived) noexcept {
|
||||
if ( base == derived ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const class_type& base_class = base.as_class();
|
||||
const class_type& derived_class = derived.as_class();
|
||||
|
||||
if ( base_class && derived_class && base_class.is_base_of(derived_class) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
[[nodiscard]] inline void* pointer_upcast(void* ptr, const class_type& from, const class_type& to) {
|
||||
if ( nullptr == ptr || !from || !to ) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -130,34 +143,29 @@ namespace meta_hpp::detail
|
||||
}
|
||||
|
||||
if ( base_type.is_derived_from(to) ) {
|
||||
return pointer_upcast(registry, base_info.upcast(ptr), base_type, to);
|
||||
return pointer_upcast(base_info.upcast(ptr), base_type, to);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline const void* pointer_upcast( //
|
||||
type_registry& registry,
|
||||
const void* ptr,
|
||||
const class_type& from,
|
||||
const class_type& to
|
||||
) {
|
||||
[[nodiscard]] inline const void* pointer_upcast(const void* ptr, const class_type& from, const class_type& to) {
|
||||
// NOLINTNEXTLINE(*-const-cast)
|
||||
return pointer_upcast(registry, const_cast<void*>(ptr), from, to);
|
||||
return pointer_upcast(const_cast<void*>(ptr), from, to);
|
||||
}
|
||||
|
||||
template < class_kind To, class_kind From >
|
||||
[[nodiscard]] To* pointer_upcast(type_registry& registry, From* ptr) {
|
||||
const class_type& to_class = registry.resolve_type<To>();
|
||||
const class_type& from_class = registry.resolve_type<From>();
|
||||
return static_cast<To*>(pointer_upcast(registry, ptr, from_class, to_class));
|
||||
return static_cast<To*>(pointer_upcast(ptr, from_class, to_class));
|
||||
}
|
||||
|
||||
template < class_kind To, class_kind From >
|
||||
[[nodiscard]] const To* pointer_upcast(type_registry& registry, const From* ptr) {
|
||||
const class_type& to_class = registry.resolve_type<To>();
|
||||
const class_type& from_class = registry.resolve_type<From>();
|
||||
return static_cast<const To*>(pointer_upcast(registry, ptr, from_class, to_class));
|
||||
return static_cast<const To*>(pointer_upcast(ptr, from_class, to_class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,6 @@ namespace meta_hpp
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(*-use-anyofallof)
|
||||
for ( const class_type& derived_base : derived.data_->bases ) {
|
||||
if ( is_base_of(derived_base) ) {
|
||||
return true;
|
||||
@@ -167,7 +166,6 @@ namespace meta_hpp
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(*-use-anyofallof)
|
||||
for ( const class_type& self_base : data_->bases ) {
|
||||
if ( self_base.is_derived_from(base) ) {
|
||||
return true;
|
||||
|
||||
@@ -80,6 +80,9 @@ namespace meta_hpp
|
||||
[[nodiscard]] uvalue unmap() const;
|
||||
[[nodiscard]] bool has_unmap_op() const noexcept;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] bool is() const noexcept;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] T as() &&;
|
||||
|
||||
|
||||
@@ -432,6 +432,12 @@ namespace meta_hpp
|
||||
return tag != storage_e::nothing && vtable->unmap != nullptr;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::is() const noexcept {
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
return detail::is_base_of(resolve_type<T>(), get_type());
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
T uvalue::as() && {
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
@@ -511,11 +517,6 @@ namespace meta_hpp
|
||||
const any_type& from_type = get_type();
|
||||
const any_type& to_type = registry.resolve_type<T>();
|
||||
|
||||
const auto is_a = [](const any_type& base, const any_type& derived) {
|
||||
return (base == derived) //
|
||||
|| (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class()));
|
||||
};
|
||||
|
||||
if constexpr ( detail::pointer_kind<T> ) {
|
||||
if ( to_type.is_pointer() && from_type.is_nullptr() ) {
|
||||
return static_cast<T>(nullptr);
|
||||
@@ -539,11 +540,11 @@ namespace meta_hpp
|
||||
return static_cast<T>(to_ptr);
|
||||
}
|
||||
|
||||
if ( is_a(to_data_type, from_data_type) ) {
|
||||
if ( detail::is_base_of(to_data_type, from_data_type) ) {
|
||||
const class_type& to_data_class = to_data_type.as_class();
|
||||
const class_type& from_data_class = from_data_type.as_class();
|
||||
|
||||
void* to_ptr = detail::pointer_upcast(registry, *from_data_ptr, from_data_class, to_data_class);
|
||||
void* to_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class);
|
||||
return static_cast<T>(to_ptr);
|
||||
}
|
||||
}
|
||||
@@ -556,11 +557,11 @@ namespace meta_hpp
|
||||
return to_ptr;
|
||||
}
|
||||
|
||||
if ( is_a(to_type, from_type) ) {
|
||||
if ( detail::is_base_of(to_type, from_type) ) {
|
||||
const class_type& to_class = to_type.as_class();
|
||||
const class_type& from_class = from_type.as_class();
|
||||
|
||||
T* to_ptr = static_cast<T*>(detail::pointer_upcast(registry, get_data(), from_class, to_class));
|
||||
T* to_ptr = static_cast<T*>(detail::pointer_upcast(get_data(), from_class, to_class));
|
||||
return to_ptr;
|
||||
}
|
||||
}
|
||||
@@ -579,11 +580,6 @@ namespace meta_hpp
|
||||
const any_type& from_type = get_type();
|
||||
const any_type& to_type = registry.resolve_type<T>();
|
||||
|
||||
const auto is_a = [](const any_type& base, const any_type& derived) {
|
||||
return (base == derived) //
|
||||
|| (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class()));
|
||||
};
|
||||
|
||||
if constexpr ( detail::pointer_kind<T> ) {
|
||||
if ( to_type.is_pointer() && from_type.is_nullptr() ) {
|
||||
return static_cast<T>(nullptr);
|
||||
@@ -607,11 +603,11 @@ namespace meta_hpp
|
||||
return static_cast<T>(to_ptr);
|
||||
}
|
||||
|
||||
if ( is_a(to_data_type, from_data_type) ) {
|
||||
if ( detail::is_base_of(to_data_type, from_data_type) ) {
|
||||
const class_type& to_data_class = to_data_type.as_class();
|
||||
const class_type& from_data_class = from_data_type.as_class();
|
||||
|
||||
void* to_ptr = detail::pointer_upcast(registry, *from_data_ptr, from_data_class, to_data_class);
|
||||
void* to_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class);
|
||||
return static_cast<T>(to_ptr);
|
||||
}
|
||||
}
|
||||
@@ -624,11 +620,11 @@ namespace meta_hpp
|
||||
return to_ptr;
|
||||
}
|
||||
|
||||
if ( is_a(to_type, from_type) ) {
|
||||
if ( detail::is_base_of(to_type, from_type) ) {
|
||||
const class_type& to_class = to_type.as_class();
|
||||
const class_type& from_class = from_type.as_class();
|
||||
|
||||
const T* to_ptr = static_cast<const T*>(detail::pointer_upcast(registry, get_data(), from_class, to_class));
|
||||
const T* to_ptr = static_cast<const T*>(detail::pointer_upcast(get_data(), from_class, to_class));
|
||||
return to_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user