From 1d9248462df7d796a3da86b67606d374844ab00e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 18 Feb 2023 21:30:27 +0700 Subject: [PATCH] add uvalue::is --- develop/singles/headers/meta.hpp/meta_all.hpp | 119 +++++++++--------- .../untests/meta_utilities/value3_tests.cpp | 29 +++++ headers/.clangd | 1 + .../meta_detail/value_utilities/uarg.hpp | 24 ++-- .../meta_detail/value_utilities/uinst.hpp | 13 +- .../meta_detail/value_utilities/utraits.hpp | 40 +++--- headers/meta.hpp/meta_types/class_type.hpp | 2 - headers/meta.hpp/meta_uvalue.hpp | 3 + headers/meta.hpp/meta_uvalue/uvalue.hpp | 32 +++-- 9 files changed, 139 insertions(+), 124 deletions(-) diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index adcc87c..f111054 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -2928,6 +2928,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() &&; @@ -3020,6 +3023,7 @@ namespace meta_hpp [[nodiscard]] bool has_error() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; + [[nodiscard]] error_code operator*() const noexcept; [[nodiscard]] error_code get_error() const noexcept; void reset() noexcept; @@ -5422,12 +5426,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; } @@ -5442,35 +5459,30 @@ 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(ptr), from, to); + return pointer_upcast(const_cast(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(); const class_type& from_class = registry.resolve_type(); - return static_cast(pointer_upcast(registry, ptr, from_class, to_class)); + return static_cast(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(); const class_type& from_class = registry.resolve_type(); - return static_cast(pointer_upcast(registry, ptr, from_class, to_class)); + return static_cast(pointer_upcast(ptr, from_class, to_class)); } } @@ -5602,11 +5614,6 @@ namespace meta_hpp::detail const any_type& from_type = get_raw_type(); const any_type& to_type = registry.resolve_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; } @@ -5622,7 +5629,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; } } @@ -5639,7 +5646,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; } } @@ -5662,11 +5669,6 @@ namespace meta_hpp::detail const any_type& from_type = get_raw_type(); const any_type& to_type = registry.resolve_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](type_list) { switch ( get_ref_type() ) { case ref_types::lvalue: @@ -5696,13 +5698,13 @@ namespace meta_hpp::detail }; if constexpr ( std::is_reference_v ) { - if ( is_a(to_type, from_type) && is_convertible_to_ref(type_list{}) ) { + if ( is_base_of(to_type, from_type) && is_convertible_to_ref(type_list{}) ) { return true; } } if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - if ( is_a(to_type, from_type) && is_constructible_from_type(type_list{}) ) { + if ( is_base_of(to_type, from_type) && is_constructible_from_type(type_list{}) ) { return true; } } @@ -5743,7 +5745,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_ptr); } } @@ -5765,7 +5767,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_ptr); } } @@ -5791,7 +5793,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 ) { return *static_cast(to_ptr); @@ -6197,11 +6199,6 @@ namespace meta_hpp::detail const any_type& from_type = get_raw_type(); const any_type& to_type = registry.resolve_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_class() ) { const auto is_invocable = [this]() { switch ( get_ref_type() ) { @@ -6217,7 +6214,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() ) { @@ -6230,7 +6227,7 @@ namespace meta_hpp::detail : std::is_invocable_v; }; - return is_invocable() && is_a(to_type, from_data_type); + return is_invocable() && is_base_of(to_type, from_data_type); } return false; @@ -6253,7 +6250,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 ) { return *static_cast(to_ptr); @@ -6277,7 +6274,7 @@ namespace meta_hpp::detail const class_type& to_class = to_type.as_class(); void** from_data_ptr = static_cast(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 ) { return *static_cast(to_ptr); @@ -7858,7 +7855,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; @@ -7882,7 +7878,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; @@ -8978,6 +8973,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>); + return detail::is_base_of(resolve_type(), get_type()); + } + template < typename T > T uvalue::as() && { static_assert(std::is_same_v>); @@ -9057,11 +9058,6 @@ namespace meta_hpp const any_type& from_type = get_type(); const any_type& to_type = registry.resolve_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 constexpr ( detail::pointer_kind ) { if ( to_type.is_pointer() && from_type.is_nullptr() ) { return static_cast(nullptr); @@ -9085,11 +9081,11 @@ namespace meta_hpp return static_cast(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(to_ptr); } } @@ -9102,11 +9098,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(detail::pointer_upcast(registry, get_data(), from_class, to_class)); + T* to_ptr = static_cast(detail::pointer_upcast(get_data(), from_class, to_class)); return to_ptr; } } @@ -9125,11 +9121,6 @@ namespace meta_hpp const any_type& from_type = get_type(); const any_type& to_type = registry.resolve_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 constexpr ( detail::pointer_kind ) { if ( to_type.is_pointer() && from_type.is_nullptr() ) { return static_cast(nullptr); @@ -9153,11 +9144,11 @@ namespace meta_hpp return static_cast(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(to_ptr); } } @@ -9170,11 +9161,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(detail::pointer_upcast(registry, get_data(), from_class, to_class)); + const T* to_ptr = static_cast(detail::pointer_upcast(get_data(), from_class, to_class)); return to_ptr; } } @@ -9201,6 +9192,10 @@ namespace meta_hpp return has_error(); } + inline error_code uerror::operator*() const noexcept { + return error_; + } + inline error_code uerror::get_error() const noexcept { return error_; } diff --git a/develop/untests/meta_utilities/value3_tests.cpp b/develop/untests/meta_utilities/value3_tests.cpp index 4fd9bf9..009be4b 100644 --- a/develop/untests/meta_utilities/value3_tests.cpp +++ b/develop/untests/meta_utilities/value3_tests.cpp @@ -88,6 +88,35 @@ TEST_CASE("meta/meta_utilities/value3/get_type") { } } +TEST_CASE("meta/meta_utilities/value3/is") { + namespace meta = meta_hpp; + + { + CHECK(meta::uvalue{derived{}}.is()); + CHECK_FALSE(meta::uvalue{derived{}}.is()); + } + + { + CHECK(meta::uvalue{derived{}}.is()); + CHECK(meta::uvalue{derived{}}.is()); + } + + { + derived d{}; + meta::uvalue v{&d}; + CHECK(v.is()); + CHECK_FALSE(v.is()); + CHECK_FALSE(v.is()); + CHECK_FALSE(v.is()); + } + + { + meta::uvalue v{nullptr}; + CHECK(v.is()); + CHECK_FALSE(v.is()); + } +} + TEST_CASE("meta/meta_utilities/value3/as") { namespace meta = meta_hpp; diff --git a/headers/.clangd b/headers/.clangd index 2e16106..4d940db 100644 --- a/headers/.clangd +++ b/headers/.clangd @@ -23,6 +23,7 @@ Diagnostics: - readability-named-parameter - readability-redundant-access-specifiers - readability-simplify-boolean-expr + - readability-use-anyofallof CompileFlags: CompilationDatabase: ../develop/.cdb diff --git a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp index 83f12a6..32ab3ef 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp @@ -140,11 +140,6 @@ namespace meta_hpp::detail const any_type& from_type = get_raw_type(); const any_type& to_type = registry.resolve_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(); - 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](type_list) { switch ( get_ref_type() ) { case ref_types::lvalue: @@ -234,13 +224,13 @@ namespace meta_hpp::detail }; if constexpr ( std::is_reference_v ) { - if ( is_a(to_type, from_type) && is_convertible_to_ref(type_list{}) ) { + if ( is_base_of(to_type, from_type) && is_convertible_to_ref(type_list{}) ) { return true; } } if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - if ( is_a(to_type, from_type) && is_constructible_from_type(type_list{}) ) { + if ( is_base_of(to_type, from_type) && is_constructible_from_type(type_list{}) ) { 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_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_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 ) { return *static_cast(to_ptr); diff --git a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp index 526f2bc..969835d 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp @@ -134,11 +134,6 @@ namespace meta_hpp::detail const any_type& from_type = get_raw_type(); const any_type& to_type = registry.resolve_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_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; }; - 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 ) { return *static_cast(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(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 ) { return *static_cast(to_ptr); diff --git a/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp index 5063e4b..059913c 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp @@ -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(ptr), from, to); + return pointer_upcast(const_cast(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(); const class_type& from_class = registry.resolve_type(); - return static_cast(pointer_upcast(registry, ptr, from_class, to_class)); + return static_cast(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(); const class_type& from_class = registry.resolve_type(); - return static_cast(pointer_upcast(registry, ptr, from_class, to_class)); + return static_cast(pointer_upcast(ptr, from_class, to_class)); } } diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 25bb524..cbea19d 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -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; diff --git a/headers/meta.hpp/meta_uvalue.hpp b/headers/meta.hpp/meta_uvalue.hpp index b585b86..0a8d8a0 100644 --- a/headers/meta.hpp/meta_uvalue.hpp +++ b/headers/meta.hpp/meta_uvalue.hpp @@ -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() &&; diff --git a/headers/meta.hpp/meta_uvalue/uvalue.hpp b/headers/meta.hpp/meta_uvalue/uvalue.hpp index 95bcbff..0d21352 100644 --- a/headers/meta.hpp/meta_uvalue/uvalue.hpp +++ b/headers/meta.hpp/meta_uvalue/uvalue.hpp @@ -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>); + return detail::is_base_of(resolve_type(), get_type()); + } + template < typename T > T uvalue::as() && { static_assert(std::is_same_v>); @@ -511,11 +517,6 @@ namespace meta_hpp const any_type& from_type = get_type(); const any_type& to_type = registry.resolve_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 constexpr ( detail::pointer_kind ) { if ( to_type.is_pointer() && from_type.is_nullptr() ) { return static_cast(nullptr); @@ -539,11 +540,11 @@ namespace meta_hpp return static_cast(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(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(detail::pointer_upcast(registry, get_data(), from_class, to_class)); + T* to_ptr = static_cast(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(); - 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 ) { if ( to_type.is_pointer() && from_type.is_nullptr() ) { return static_cast(nullptr); @@ -607,11 +603,11 @@ namespace meta_hpp return static_cast(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(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(detail::pointer_upcast(registry, get_data(), from_class, to_class)); + const T* to_ptr = static_cast(detail::pointer_upcast(get_data(), from_class, to_class)); return to_ptr; } }