diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index 41f1e20..f3c3da2 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -2570,10 +2570,18 @@ namespace meta_hpp [[nodiscard]] bool is_base_of() const noexcept; [[nodiscard]] bool is_base_of(const class_type& derived) const noexcept; + template < detail::class_kind Derived > + [[nodiscard]] bool is_direct_base_of() const noexcept; + [[nodiscard]] bool is_direct_base_of(const class_type& derived) const noexcept; + template < detail::class_kind Base > [[nodiscard]] bool is_derived_from() const noexcept; [[nodiscard]] bool is_derived_from(const class_type& base) const noexcept; + template < detail::class_kind Base > + [[nodiscard]] bool is_direct_derived_from() const noexcept; + [[nodiscard]] bool is_direct_derived_from(const class_type& base) const noexcept; + [[nodiscard]] function get_function(std::string_view name) const noexcept; [[nodiscard]] member get_member(std::string_view name) const noexcept; [[nodiscard]] method get_method(std::string_view name) const noexcept; @@ -8186,15 +8194,16 @@ namespace meta_hpp } inline bool class_type::is_base_of(const class_type& derived) const noexcept { - if ( !is_valid() || !derived.is_valid() ) { - return false; - } + return is_valid() && derived.is_valid() && derived.data_->deep_upcasts.contains(*this); + } - if ( derived.data_->deep_upcasts.contains(*this) ) { - return true; - } + template < detail::class_kind Derived > + bool class_type::is_direct_base_of() const noexcept { + return is_direct_base_of(resolve_type()); + } - return false; + inline bool class_type::is_direct_base_of(const class_type& derived) const noexcept { + return is_valid() && derived.is_valid() && derived.data_->base_upcasts.contains(*this); } template < detail::class_kind Base > @@ -8203,15 +8212,16 @@ namespace meta_hpp } inline bool class_type::is_derived_from(const class_type& base) const noexcept { - if ( !is_valid() || !base.is_valid() ) { - return false; - } + return is_valid() && base.is_valid() && data_->deep_upcasts.contains(base); + } - if ( data_->deep_upcasts.contains(base) ) { - return true; - } + template < detail::class_kind Base > + bool class_type::is_direct_derived_from() const noexcept { + return is_direct_derived_from(resolve_type()); + } - return false; + inline bool class_type::is_direct_derived_from(const class_type& base) const noexcept { + return is_valid() && base.is_valid() && data_->base_upcasts.contains(base); } inline function class_type::get_function(std::string_view name) const noexcept { diff --git a/develop/untests/meta_types/class_type_tests.cpp b/develop/untests/meta_types/class_type_tests.cpp index 7ab1db3..e31eb6a 100644 --- a/develop/untests/meta_types/class_type_tests.cpp +++ b/develop/untests/meta_types/class_type_tests.cpp @@ -248,40 +248,62 @@ TEST_CASE("meta/meta_types/class_type") { { CHECK_FALSE(base_clazz_1_type.is_base_of()); CHECK_FALSE(base_clazz_1_type.is_base_of(base_clazz_1_type)); + CHECK_FALSE(base_clazz_1_type.is_direct_base_of()); + CHECK_FALSE(base_clazz_1_type.is_direct_base_of(base_clazz_1_type)); CHECK_FALSE(base_clazz_1_type.is_base_of()); CHECK_FALSE(base_clazz_1_type.is_base_of(base_clazz_2_type)); + CHECK_FALSE(base_clazz_1_type.is_direct_base_of()); + CHECK_FALSE(base_clazz_1_type.is_direct_base_of(base_clazz_2_type)); CHECK(base_clazz_1_type.is_base_of()); CHECK(base_clazz_1_type.is_base_of(derived_clazz_type)); + CHECK(base_clazz_1_type.is_direct_base_of()); + CHECK(base_clazz_1_type.is_direct_base_of(derived_clazz_type)); CHECK(base_clazz_1_type.is_base_of()); CHECK(base_clazz_1_type.is_base_of(final_derived_clazz_type)); + CHECK_FALSE(base_clazz_1_type.is_direct_base_of()); + CHECK_FALSE(base_clazz_1_type.is_direct_base_of(final_derived_clazz_type)); } { CHECK_FALSE(base_clazz_2_type.is_base_of()); CHECK_FALSE(base_clazz_2_type.is_base_of(base_clazz_1_type)); + CHECK_FALSE(base_clazz_2_type.is_direct_base_of()); + CHECK_FALSE(base_clazz_2_type.is_direct_base_of(base_clazz_1_type)); CHECK_FALSE(base_clazz_2_type.is_base_of()); CHECK_FALSE(base_clazz_2_type.is_base_of(base_clazz_2_type)); + CHECK_FALSE(base_clazz_2_type.is_direct_base_of()); + CHECK_FALSE(base_clazz_2_type.is_direct_base_of(base_clazz_2_type)); CHECK(base_clazz_2_type.is_base_of()); CHECK(base_clazz_2_type.is_base_of(derived_clazz_type)); + CHECK(base_clazz_2_type.is_direct_base_of()); + CHECK(base_clazz_2_type.is_direct_base_of(derived_clazz_type)); CHECK(base_clazz_2_type.is_base_of()); CHECK(base_clazz_2_type.is_base_of(final_derived_clazz_type)); + CHECK_FALSE(base_clazz_2_type.is_direct_base_of()); + CHECK_FALSE(base_clazz_2_type.is_direct_base_of(final_derived_clazz_type)); } { CHECK_FALSE(derived_clazz_type.is_base_of()); CHECK_FALSE(derived_clazz_type.is_base_of(base_clazz_1_type)); + CHECK_FALSE(derived_clazz_type.is_direct_base_of()); + CHECK_FALSE(derived_clazz_type.is_direct_base_of(base_clazz_1_type)); CHECK_FALSE(derived_clazz_type.is_base_of()); CHECK_FALSE(derived_clazz_type.is_base_of(base_clazz_2_type)); + CHECK_FALSE(derived_clazz_type.is_direct_base_of()); + CHECK_FALSE(derived_clazz_type.is_direct_base_of(base_clazz_2_type)); CHECK_FALSE(derived_clazz_type.is_base_of()); CHECK_FALSE(derived_clazz_type.is_base_of(derived_clazz_type)); + CHECK_FALSE(derived_clazz_type.is_direct_base_of()); + CHECK_FALSE(derived_clazz_type.is_direct_base_of(derived_clazz_type)); } } @@ -289,45 +311,69 @@ TEST_CASE("meta/meta_types/class_type") { { CHECK_FALSE(base_clazz_1_type.is_derived_from()); CHECK_FALSE(base_clazz_1_type.is_derived_from(base_clazz_1_type)); + CHECK_FALSE(base_clazz_1_type.is_direct_derived_from()); + CHECK_FALSE(base_clazz_1_type.is_direct_derived_from(base_clazz_1_type)); CHECK_FALSE(base_clazz_1_type.is_derived_from()); CHECK_FALSE(base_clazz_1_type.is_derived_from(base_clazz_2_type)); + CHECK_FALSE(base_clazz_1_type.is_direct_derived_from()); + CHECK_FALSE(base_clazz_1_type.is_direct_derived_from(base_clazz_2_type)); CHECK_FALSE(base_clazz_1_type.is_derived_from()); CHECK_FALSE(base_clazz_1_type.is_derived_from(derived_clazz_type)); + CHECK_FALSE(base_clazz_1_type.is_direct_derived_from()); + CHECK_FALSE(base_clazz_1_type.is_direct_derived_from(derived_clazz_type)); } { CHECK_FALSE(base_clazz_2_type.is_derived_from()); CHECK_FALSE(base_clazz_2_type.is_derived_from(base_clazz_1_type)); + CHECK_FALSE(base_clazz_2_type.is_direct_derived_from()); + CHECK_FALSE(base_clazz_2_type.is_direct_derived_from(base_clazz_1_type)); CHECK_FALSE(base_clazz_2_type.is_derived_from()); CHECK_FALSE(base_clazz_2_type.is_derived_from(base_clazz_2_type)); + CHECK_FALSE(base_clazz_2_type.is_direct_derived_from()); + CHECK_FALSE(base_clazz_2_type.is_direct_derived_from(base_clazz_2_type)); CHECK_FALSE(base_clazz_2_type.is_derived_from()); CHECK_FALSE(base_clazz_2_type.is_derived_from(derived_clazz_type)); + CHECK_FALSE(base_clazz_2_type.is_direct_derived_from()); + CHECK_FALSE(base_clazz_2_type.is_direct_derived_from(derived_clazz_type)); } { CHECK(derived_clazz_type.is_derived_from()); CHECK(derived_clazz_type.is_derived_from(base_clazz_1_type)); + CHECK(derived_clazz_type.is_direct_derived_from()); + CHECK(derived_clazz_type.is_direct_derived_from(base_clazz_1_type)); CHECK(derived_clazz_type.is_derived_from()); CHECK(derived_clazz_type.is_derived_from(base_clazz_2_type)); + CHECK(derived_clazz_type.is_direct_derived_from()); + CHECK(derived_clazz_type.is_direct_derived_from(base_clazz_2_type)); CHECK_FALSE(derived_clazz_type.is_derived_from()); CHECK_FALSE(derived_clazz_type.is_derived_from(derived_clazz_type)); + CHECK_FALSE(derived_clazz_type.is_direct_derived_from()); + CHECK_FALSE(derived_clazz_type.is_direct_derived_from(derived_clazz_type)); } { CHECK(final_derived_clazz_type.is_derived_from()); CHECK(final_derived_clazz_type.is_derived_from(base_clazz_1_type)); + CHECK_FALSE(final_derived_clazz_type.is_direct_derived_from()); + CHECK_FALSE(final_derived_clazz_type.is_direct_derived_from(base_clazz_1_type)); CHECK(final_derived_clazz_type.is_derived_from()); CHECK(final_derived_clazz_type.is_derived_from(base_clazz_2_type)); + CHECK_FALSE(final_derived_clazz_type.is_direct_derived_from()); + CHECK_FALSE(final_derived_clazz_type.is_direct_derived_from(base_clazz_2_type)); CHECK(final_derived_clazz_type.is_derived_from()); CHECK(final_derived_clazz_type.is_derived_from(derived_clazz_type)); + CHECK(final_derived_clazz_type.is_direct_derived_from()); + CHECK(final_derived_clazz_type.is_direct_derived_from(derived_clazz_type)); } } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index f344832..26661ac 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -180,10 +180,18 @@ namespace meta_hpp [[nodiscard]] bool is_base_of() const noexcept; [[nodiscard]] bool is_base_of(const class_type& derived) const noexcept; + template < detail::class_kind Derived > + [[nodiscard]] bool is_direct_base_of() const noexcept; + [[nodiscard]] bool is_direct_base_of(const class_type& derived) const noexcept; + template < detail::class_kind Base > [[nodiscard]] bool is_derived_from() const noexcept; [[nodiscard]] bool is_derived_from(const class_type& base) const noexcept; + template < detail::class_kind Base > + [[nodiscard]] bool is_direct_derived_from() const noexcept; + [[nodiscard]] bool is_direct_derived_from(const class_type& base) const noexcept; + [[nodiscard]] function get_function(std::string_view name) const noexcept; [[nodiscard]] member get_member(std::string_view name) const noexcept; [[nodiscard]] method get_method(std::string_view name) const noexcept; diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index e9e05b8..bdff667 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -168,15 +168,16 @@ namespace meta_hpp } inline bool class_type::is_base_of(const class_type& derived) const noexcept { - if ( !is_valid() || !derived.is_valid() ) { - return false; - } + return is_valid() && derived.is_valid() && derived.data_->deep_upcasts.contains(*this); + } - if ( derived.data_->deep_upcasts.contains(*this) ) { - return true; - } + template < detail::class_kind Derived > + bool class_type::is_direct_base_of() const noexcept { + return is_direct_base_of(resolve_type()); + } - return false; + inline bool class_type::is_direct_base_of(const class_type& derived) const noexcept { + return is_valid() && derived.is_valid() && derived.data_->base_upcasts.contains(*this); } template < detail::class_kind Base > @@ -185,15 +186,16 @@ namespace meta_hpp } inline bool class_type::is_derived_from(const class_type& base) const noexcept { - if ( !is_valid() || !base.is_valid() ) { - return false; - } + return is_valid() && base.is_valid() && data_->deep_upcasts.contains(base); + } - if ( data_->deep_upcasts.contains(base) ) { - return true; - } + template < detail::class_kind Base > + bool class_type::is_direct_derived_from() const noexcept { + return is_direct_derived_from(resolve_type()); + } - return false; + inline bool class_type::is_direct_derived_from(const class_type& base) const noexcept { + return is_valid() && base.is_valid() && data_->base_upcasts.contains(base); } inline function class_type::get_function(std::string_view name) const noexcept {