From 5a909841de32e21a819fee7fbb122720a91c6743 Mon Sep 17 00:00:00 2001 From: Axel Menzel Date: Fri, 31 Mar 2017 19:00:07 +0200 Subject: [PATCH] added support for register base class property, while only register the derived class. it used the same appraoch like for the member functions closes #29 --- src/rttr/detail/misc/misc_type_traits.h | 12 +++ src/rttr/detail/registration/bind_impl.h | 4 + .../register_base_class_from_accessor.h | 78 ++++++++++++------- .../property/property_class_inheritance.cpp | 37 +++++++++ 4 files changed, 101 insertions(+), 30 deletions(-) diff --git a/src/rttr/detail/misc/misc_type_traits.h b/src/rttr/detail/misc/misc_type_traits.h index 03ed051a..e5b67451 100644 --- a/src/rttr/detail/misc/misc_type_traits.h +++ b/src/rttr/detail/misc/misc_type_traits.h @@ -972,6 +972,18 @@ namespace detail struct is_copy_constructible> : std::false_type {}; ///////////////////////////////////////////////////////////////////////////////////////// + + template + struct property_traits; + + template + struct property_traits + { + using class_type = C; + }; + + ///////////////////////////////////////////////////////////////////////////////////////// + } // end namespace detail } // end namespace rttr diff --git a/src/rttr/detail/registration/bind_impl.h b/src/rttr/detail/registration/bind_impl.h index 96a155ed..02658feb 100644 --- a/src/rttr/detail/registration/bind_impl.h +++ b/src/rttr/detail/registration/bind_impl.h @@ -392,6 +392,7 @@ class registration::bind : public regist bind(const std::shared_ptr& reg_exec, string_view name, A acc) : registration_derived_t(reg_exec), m_reg_exec(reg_exec), m_name(name), m_acc(acc) { + detail::register_accessor_class_type_when_needed(); m_reg_exec->add_registration_func(this); } @@ -481,6 +482,8 @@ class registration::bind : public r bind(const std::shared_ptr& reg_exec, string_view name, A1 getter, A2 setter) : registration_derived_t(reg_exec), m_reg_exec(reg_exec), m_name(name), m_getter(getter), m_setter(setter) { + detail::register_accessor_class_type_when_needed(); + detail::register_accessor_class_type_when_needed(); m_reg_exec->add_registration_func(this); } @@ -569,6 +572,7 @@ class registration::bind : publ bind(const std::shared_ptr& reg_exec, string_view name, A acc) : registration_derived_t(reg_exec), m_reg_exec(reg_exec), m_name(name), m_acc(acc) { + detail::register_accessor_class_type_when_needed(); m_reg_exec->add_registration_func(this); } diff --git a/src/rttr/detail/registration/register_base_class_from_accessor.h b/src/rttr/detail/registration/register_base_class_from_accessor.h index 9d9d0e72..a8a37673 100644 --- a/src/rttr/detail/registration/register_base_class_from_accessor.h +++ b/src/rttr/detail/registration/register_base_class_from_accessor.h @@ -32,6 +32,7 @@ #include "rttr/detail/type/base_classes.h" #include "rttr/detail/type/type_register.h" +#include "rttr/detail/misc/misc_type_traits.h" #include @@ -40,75 +41,92 @@ namespace rttr namespace detail { -template -enable_if_t::value, void> -register_member_func_class_type_when_needed_3() +template +enable_if_t::value, void> +register_member_accessor_class_type_when_needed_3() { } -template -enable_if_t::value, void> -register_member_func_class_type_when_needed_3() +template +enable_if_t::value, void> +register_member_accessor_class_type_when_needed_3() { - base_class_info baseClassInfo = { type::get(), &rttr_cast_impl }; + base_class_info baseClassInfo = { type::get(), &rttr_cast_impl }; type_register::register_base_class(type::get(), baseClassInfo); } -template +template enable_if_t::value, void> -register_member_func_class_type_when_needed_2() +register_member_accessor_class_type_when_needed_2() { - register_member_func_class_type_when_needed_3(); + register_member_accessor_class_type_when_needed_3(); } -template +template enable_if_t::value, void> -register_member_func_class_type_when_needed_2() +register_member_accessor_class_type_when_needed_2() { - base_class_info baseClassInfo = { type::get(), &rttr_cast_impl }; + base_class_info baseClassInfo = { type::get(), &rttr_cast_impl }; type_register::register_base_class(type::get(), baseClassInfo); +} + +template +enable_if_t::value, void> +register_member_accessor_class_type_when_needed_1() +{ + register_member_accessor_class_type_when_needed_2(); +} +template +enable_if_t::value, void> +register_member_accessor_class_type_when_needed_1() +{ } -template -enable_if_t::value, void> -register_member_func_class_type_when_needed_1() +template +enable_if_t::value, void> +register_member_accessor_class_type_when_needed() { - register_member_func_class_type_when_needed_2(); + register_member_accessor_class_type_when_needed_1(); } -template -enable_if_t::value, void> -register_member_func_class_type_when_needed_1() +template +enable_if_t::value, void> +register_member_accessor_class_type_when_needed() { } -template -enable_if_t::value, void> -register_member_func_class_type_when_needed() +///////////////////////////////////////////////////////////////////////////////////////// + +template +enable_if_t::value && !std::is_member_object_pointer::value, void> +register_accessor_class_type_when_needed() { - register_member_func_class_type_when_needed_1(); + register_member_accessor_class_type_when_needed::class_type>(); } -template -enable_if_t::value, void> -register_member_func_class_type_when_needed() +template +enable_if_t::value && std::is_member_object_pointer::value, void> +register_accessor_class_type_when_needed() { + register_member_accessor_class_type_when_needed::class_type>(); } template -enable_if_t::value, void> +enable_if_t::value && std::is_member_object_pointer::value, void> register_accessor_class_type_when_needed() { - register_member_func_class_type_when_needed::class_type>(); } template -enable_if_t::value, void> +enable_if_t::value && !std::is_member_object_pointer::value, void> register_accessor_class_type_when_needed() { } +///////////////////////////////////////////////////////////////////////////////////////// + + } // end namespace detail } // end namespace rttr diff --git a/src/unit_tests/property/property_class_inheritance.cpp b/src/unit_tests/property/property_class_inheritance.cpp index 4f426cf2..c2c3ad1e 100644 --- a/src/unit_tests/property/property_class_inheritance.cpp +++ b/src/unit_tests/property/property_class_inheritance.cpp @@ -95,6 +95,17 @@ struct bottom : left, right, right_2 } +struct base_prop_not_registered +{ + base_prop_not_registered() : value(100) {} + int value; +}; + +struct derived_registered_prop : base_prop_not_registered +{ + +}; + static double g_name; ///////////////////////////////////////////////////////////////////////////////////////// @@ -145,6 +156,9 @@ RTTR_REGISTRATION .property("bottom-static", &g_name) // double property .property("bottom-static-protected", &g_name, registration::protected_access) ; + + registration::class_("derived_registered_prop") + .property("value", &derived_registered_prop::value); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -475,3 +489,26 @@ TEST_CASE("property - class - inheritance - invoke", "[property]") } ///////////////////////////////////////////////////////////////////////////////////////// + +TEST_CASE("property - base class not registered", "[property]") +{ + type t_prop = type::get(); + property prop = t_prop.get_property("value"); + derived_registered_prop obj; + + auto ret = prop.set_value(obj, 23); + + CHECK(ret == true); + CHECK(obj.value == 23); + + auto base_type = type::get(); + + CHECK(t_prop.is_derived_from(base_type) == true); + + auto range = base_type.get_derived_classes(); + + REQUIRE(range.size() == 1); + CHECK(*range.begin() == t_prop); +} + +/////////////////////////////////////////////////////////////////////////////////////////