From ca8fd075cdcd3596f6de88b665568d7cd93d191e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 28 Dec 2023 01:19:37 +0700 Subject: [PATCH] polish base info filling --- develop/singles/headers/meta.hpp/meta_all.hpp | 97 ++++++++++--------- headers/meta.hpp/meta_detail/base_info.hpp | 4 +- headers/meta.hpp/meta_registry.hpp | 2 +- headers/meta.hpp/meta_types/class_type.hpp | 89 +++++++++-------- headers/meta.hpp/meta_ucast/ucast.hpp | 2 +- 5 files changed, 104 insertions(+), 90 deletions(-) diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index 185589c..fa33b94 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -4258,7 +4258,7 @@ namespace meta_hpp::detail template < typename T > concept check_poly_info_enabled // = requires(type_registry& r, const T& v) { - { v.get_most_derived_poly_info(r) } -> std::convertible_to; + { v.get_most_derived_meta_poly_info(r) } -> std::convertible_to; }; } @@ -4272,7 +4272,7 @@ private: META_HPP_ENABLE_BASE_INFO(__VA_ARGS__) \ public: \ META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \ - virtual ::meta_hpp::detail::poly_info get_most_derived_poly_info(::meta_hpp::detail::type_registry& registry) const { \ + virtual ::meta_hpp::detail::poly_info get_most_derived_meta_poly_info(::meta_hpp::detail::type_registry& registry) const { \ using self_type = std::remove_cvref_t; \ return ::meta_hpp::detail::poly_info{.ptr = this, .type = registry.resolve_class_type()}; \ } \ @@ -4409,7 +4409,7 @@ namespace meta_hpp detail::check_poly_info_enabled, "The class doesn't support polymorphic type resolving. Use the META_HPP_ENABLE_POLY_INFO macro to fix it." ); - return from.get_most_derived_poly_info(registry).type; + return from.get_most_derived_meta_poly_info(registry).type; } else { (void)from; return registry.resolve_type(); @@ -8294,6 +8294,50 @@ namespace meta_hpp } } +namespace meta_hpp::detail::class_type_data_impl +{ + struct new_base_info_t final { + class_list base_classes; + class_type_data::deep_upcasts_t deep_upcasts; + }; + + template < class_kind Class, class_kind Target > + void add_upcast_info(new_base_info_t& info) { + const class_type_data::upcast_func_t::upcast_t class_to_target = []() { + if constexpr ( requires { static_cast(std::declval()); } ) { + return +[](void* from) -> void* { // + return static_cast(static_cast(from)); + }; + } else { + return nullptr; + } + }(); + + info.deep_upcasts.push_back(class_type_data::upcast_func_t{ + .target{resolve_type().get_id()}, + .upcast{class_to_target}, + }); + + if constexpr ( check_base_info_enabled ) { + using target_base_info = typename Target::meta_base_info; + target_base_info::for_each([&info]() { // + add_upcast_info(info); + }); + } + } + + template < class_kind Class > + void fill_upcast_info(new_base_info_t& info) { + if constexpr ( check_base_info_enabled ) { + using class_base_info = typename Class::meta_base_info; + class_base_info::for_each([&info]() { + info.base_classes.push_back(resolve_type()); + add_upcast_info(info); + }); + } + } +} + namespace meta_hpp::detail { template < class_kind Class > @@ -8303,47 +8347,10 @@ namespace meta_hpp::detail , size{class_traits::size} , align{class_traits::align} , argument_types{resolve_types(typename class_traits::argument_types{})} { - class_list new_base_classes; - deep_upcasts_t new_deep_upcasts; - - const auto add_new_base = [&](auto&& recur) { - const class_type& base_class = resolve_type(); - - new_deep_upcasts.push_back(upcast_func_t{ - .target{base_class.get_id()}, - .upcast{[]() { - if constexpr ( requires { static_cast(std::declval()); } ) { - return +[](void* from) -> void* { // - return static_cast(static_cast(from)); - }; - } else { - return nullptr; - } - }()}, - }); - - if constexpr ( std::is_same_v ) { - new_base_classes.push_back(base_class); - } - - recur.template operator()(recur); - }; - - const auto add_new_bases = [&](auto&& recur) { - if constexpr ( check_base_info_enabled ) { - using meta_base_info = typename Derived::meta_base_info; - meta_base_info::for_each([&]() { // - add_new_base.template operator()(recur); - }); - } else { - (void)recur; - } - }; - - add_new_bases.template operator()(add_new_bases); - - base_classes.swap(new_base_classes); - deep_upcasts.swap(new_deep_upcasts); + class_type_data_impl::new_base_info_t new_base_info; + class_type_data_impl::fill_upcast_info(new_base_info); + base_classes.swap(new_base_info.base_classes); + deep_upcasts.swap(new_base_info.deep_upcasts); } } @@ -9190,7 +9197,7 @@ namespace meta_hpp return from; } else { detail::type_registry& registry{detail::type_registry::instance()}; - const detail::poly_info& meta_info{from->get_most_derived_poly_info(registry)}; + const detail::poly_info& meta_info{from->get_most_derived_meta_poly_info(registry)}; // NOLINTNEXTLINE(*-const-cast) void* most_derived_object_ptr = const_cast(meta_info.ptr); diff --git a/headers/meta.hpp/meta_detail/base_info.hpp b/headers/meta.hpp/meta_detail/base_info.hpp index 3f4e79d..e1fb44a 100644 --- a/headers/meta.hpp/meta_detail/base_info.hpp +++ b/headers/meta.hpp/meta_detail/base_info.hpp @@ -25,7 +25,7 @@ namespace meta_hpp::detail template < typename T > concept check_poly_info_enabled // = requires(type_registry& r, const T& v) { - { v.get_most_derived_poly_info(r) } -> std::convertible_to; + { v.get_most_derived_meta_poly_info(r) } -> std::convertible_to; }; } @@ -39,7 +39,7 @@ private: META_HPP_ENABLE_BASE_INFO(__VA_ARGS__) \ public: \ META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \ - virtual ::meta_hpp::detail::poly_info get_most_derived_poly_info(::meta_hpp::detail::type_registry& registry) const { \ + virtual ::meta_hpp::detail::poly_info get_most_derived_meta_poly_info(::meta_hpp::detail::type_registry& registry) const { \ using self_type = std::remove_cvref_t; \ return ::meta_hpp::detail::poly_info{.ptr = this, .type = registry.resolve_class_type()}; \ } \ diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 42a6857..533e3c6 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -73,7 +73,7 @@ namespace meta_hpp detail::check_poly_info_enabled, "The class doesn't support polymorphic type resolving. Use the META_HPP_ENABLE_POLY_INFO macro to fix it." ); - return from.get_most_derived_poly_info(registry).type; + return from.get_most_derived_meta_poly_info(registry).type; } else { (void)from; return registry.resolve_type(); diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 9bdbab9..7d42506 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -18,6 +18,50 @@ #include "../meta_detail/type_traits/class_traits.hpp" +namespace meta_hpp::detail::class_type_data_impl +{ + struct new_base_info_t final { + class_list base_classes; + class_type_data::deep_upcasts_t deep_upcasts; + }; + + template < class_kind Class, class_kind Target > + void add_upcast_info(new_base_info_t& info) { + const class_type_data::upcast_func_t::upcast_t class_to_target = []() { + if constexpr ( requires { static_cast(std::declval()); } ) { + return +[](void* from) -> void* { // + return static_cast(static_cast(from)); + }; + } else { + return nullptr; + } + }(); + + info.deep_upcasts.push_back(class_type_data::upcast_func_t{ + .target{resolve_type().get_id()}, + .upcast{class_to_target}, + }); + + if constexpr ( check_base_info_enabled ) { + using target_base_info = typename Target::meta_base_info; + target_base_info::for_each([&info]() { // + add_upcast_info(info); + }); + } + } + + template < class_kind Class > + void fill_upcast_info(new_base_info_t& info) { + if constexpr ( check_base_info_enabled ) { + using class_base_info = typename Class::meta_base_info; + class_base_info::for_each([&info]() { + info.base_classes.push_back(resolve_type()); + add_upcast_info(info); + }); + } + } +} + namespace meta_hpp::detail { template < class_kind Class > @@ -27,47 +71,10 @@ namespace meta_hpp::detail , size{class_traits::size} , align{class_traits::align} , argument_types{resolve_types(typename class_traits::argument_types{})} { - class_list new_base_classes; - deep_upcasts_t new_deep_upcasts; - - const auto add_new_base = [&](auto&& recur) { - const class_type& base_class = resolve_type(); - - new_deep_upcasts.push_back(upcast_func_t{ - .target{base_class.get_id()}, - .upcast{[]() { - if constexpr ( requires { static_cast(std::declval()); } ) { - return +[](void* from) -> void* { // - return static_cast(static_cast(from)); - }; - } else { - return nullptr; - } - }()}, - }); - - if constexpr ( std::is_same_v ) { - new_base_classes.push_back(base_class); - } - - recur.template operator()(recur); - }; - - const auto add_new_bases = [&](auto&& recur) { - if constexpr ( check_base_info_enabled ) { - using meta_base_info = typename Derived::meta_base_info; - meta_base_info::for_each([&]() { // - add_new_base.template operator()(recur); - }); - } else { - (void)recur; - } - }; - - add_new_bases.template operator()(add_new_bases); - - base_classes.swap(new_base_classes); - deep_upcasts.swap(new_deep_upcasts); + class_type_data_impl::new_base_info_t new_base_info; + class_type_data_impl::fill_upcast_info(new_base_info); + base_classes.swap(new_base_info.base_classes); + deep_upcasts.swap(new_base_info.deep_upcasts); } } diff --git a/headers/meta.hpp/meta_ucast/ucast.hpp b/headers/meta.hpp/meta_ucast/ucast.hpp index b3d4a75..813a71c 100644 --- a/headers/meta.hpp/meta_ucast/ucast.hpp +++ b/headers/meta.hpp/meta_ucast/ucast.hpp @@ -34,7 +34,7 @@ namespace meta_hpp return from; } else { detail::type_registry& registry{detail::type_registry::instance()}; - const detail::poly_info& meta_info{from->get_most_derived_poly_info(registry)}; + const detail::poly_info& meta_info{from->get_most_derived_meta_poly_info(registry)}; // NOLINTNEXTLINE(*-const-cast) void* most_derived_object_ptr = const_cast(meta_info.ptr);