From 7b31832300457d0f1d4acfd3a3ee5dc6a76ea17c Mon Sep 17 00:00:00 2001 From: Axel Menzel Date: Wed, 27 Apr 2016 23:25:37 +0200 Subject: [PATCH] removed explictely destroy of wrapper objects in dtor of type_database All wrapper items will be stored as unique_ptr in general std::vector object, that means the memory will be automatically freed, when it goes out of scope. Removed destroy_item function templates. Adjusted getter value_data() in flat_map & multi_map to return const reference to inside vector. --- src/rttr/array_range.h | 17 +-- src/rttr/constructor.cpp | 6 -- src/rttr/constructor.h | 2 - src/rttr/destructor.cpp | 6 -- src/rttr/destructor.h | 2 - src/rttr/detail/impl/array_range_impl.h | 19 ++++ src/rttr/detail/misc/class_item_mapper.h | 2 - src/rttr/detail/misc/flat_map.h | 4 +- src/rttr/detail/misc/flat_multimap.h | 4 +- src/rttr/detail/type/type_database.cpp | 130 +++++++++++------------ src/rttr/detail/type/type_database_p.h | 17 +-- src/rttr/enumeration.cpp | 11 ++ src/rttr/enumeration.h | 4 + src/rttr/method.cpp | 6 -- src/rttr/method.h | 2 - src/rttr/property.cpp | 6 -- src/rttr/property.h | 3 +- src/rttr/type.h | 1 + 18 files changed, 115 insertions(+), 127 deletions(-) diff --git a/src/rttr/array_range.h b/src/rttr/array_range.h index c147a632..92d10fcb 100644 --- a/src/rttr/array_range.h +++ b/src/rttr/array_range.h @@ -39,25 +39,12 @@ class property; class method; class constructor; class enumeration; -class type; class parameter_info; -template -class array_range; - namespace detail { - template - struct default_predicate - { - using predicate_func = bool(*)(const T&); - - RTTR_FORCE_INLINE default_predicate() : m_func([](const T&){ return true; }) {} - RTTR_FORCE_INLINE default_predicate(const predicate_func& func) : m_func(func) {} - RTTR_FORCE_INLINE bool operator()(const T& obj) const { return m_func(obj); } - - predicate_func m_func; - }; +template +struct default_predicate; } // end namespace detail diff --git a/src/rttr/constructor.cpp b/src/rttr/constructor.cpp index 83ae82da..839e360a 100644 --- a/src/rttr/constructor.cpp +++ b/src/rttr/constructor.cpp @@ -45,12 +45,6 @@ constructor create_item(const constructor_wrapper_base* wrapper) return constructor(wrapper); } -template<> - void destroy_item(constructor& ctor) - { - delete ctor.m_wrapper; - } - } // end namespace detail ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/rttr/constructor.h b/src/rttr/constructor.h index 5e88705d..514de428 100644 --- a/src/rttr/constructor.h +++ b/src/rttr/constructor.h @@ -265,8 +265,6 @@ class RTTR_API constructor template friend T detail::create_item(const detail::class_item_to_wrapper_t* wrapper); - template - friend void detail::destroy_item(T& item); private: const detail::constructor_wrapper_base* m_wrapper; diff --git a/src/rttr/destructor.cpp b/src/rttr/destructor.cpp index 8d75bffc..8ce6f515 100644 --- a/src/rttr/destructor.cpp +++ b/src/rttr/destructor.cpp @@ -42,12 +42,6 @@ destructor create_item(const destructor_wrapper_base* wrapper) return destructor(wrapper); } -template<> - void destroy_item(destructor& dtor) - { - delete dtor.m_wrapper; - } - } // end namespace detail ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/rttr/destructor.h b/src/rttr/destructor.h index 083758ad..bc760675 100644 --- a/src/rttr/destructor.h +++ b/src/rttr/destructor.h @@ -121,8 +121,6 @@ class RTTR_API destructor template friend T detail::create_item(const detail::class_item_to_wrapper_t* wrapper); - template - friend void detail::destroy_item(T& item); private: const detail::destructor_wrapper_base* m_wrapper; diff --git a/src/rttr/detail/impl/array_range_impl.h b/src/rttr/detail/impl/array_range_impl.h index 7562d660..92e007d0 100644 --- a/src/rttr/detail/impl/array_range_impl.h +++ b/src/rttr/detail/impl/array_range_impl.h @@ -30,6 +30,8 @@ #include "rttr/detail/base/core_prerequisites.h" #include "rttr/property.h" +#include "rttr/type.h" +#include namespace rttr { @@ -432,6 +434,23 @@ array_range::array_reverse_iterator::operator++(int inde ///////////////////////////////////////////////////////////////////////////////////////// +namespace detail +{ + +template +struct default_predicate +{ + RTTR_FORCE_INLINE default_predicate() {} + RTTR_FORCE_INLINE default_predicate(std::function func) : m_func(std::move(func)) {} + RTTR_FORCE_INLINE bool operator()(const T& obj) const { return (m_func ? m_func(obj) : true); } + std::function m_func; +}; + + +///////////////////////////////////////////////////////////////////////////////////////// + +} // end namespace detail + } // end namespace rttr diff --git a/src/rttr/detail/misc/class_item_mapper.h b/src/rttr/detail/misc/class_item_mapper.h index 8177c456..2c4460d0 100644 --- a/src/rttr/detail/misc/class_item_mapper.h +++ b/src/rttr/detail/misc/class_item_mapper.h @@ -72,8 +72,6 @@ using class_item_to_wrapper_t = conditional_t< std::is_same::value, template T create_item(const class_item_to_wrapper_t* wrapper = nullptr); -template -void destroy_item(T& item); } // end namespace detail } // end namespace rttr diff --git a/src/rttr/detail/misc/flat_map.h b/src/rttr/detail/misc/flat_map.h index 2b25af08..c2c30d96 100644 --- a/src/rttr/detail/misc/flat_map.h +++ b/src/rttr/detail/misc/flat_map.h @@ -120,7 +120,7 @@ class flat_map if (found_key != m_key_list.cend()) { const auto index = std::distance(m_key_list.cbegin(), found_key); - m_value_list.insert(m_value_list.begin() + index, value); + m_value_list.insert(m_value_list.begin() + index, std::move(value)); } } @@ -199,7 +199,7 @@ class flat_map m_value_list.clear(); } - std::vector& value_data() + const std::vector& value_data() const { return m_value_list; } diff --git a/src/rttr/detail/misc/flat_multimap.h b/src/rttr/detail/misc/flat_multimap.h index 8c57406e..a9d58557 100644 --- a/src/rttr/detail/misc/flat_multimap.h +++ b/src/rttr/detail/misc/flat_multimap.h @@ -126,7 +126,7 @@ class flat_multimap } const auto index = std::distance(m_key_list.cbegin(), found_key); - m_value_list.insert(m_value_list.begin() + index, value); + m_value_list.insert(m_value_list.begin() + index, std::move(value)); } } @@ -180,7 +180,7 @@ class flat_multimap } #endif - std::vector& value_data() + const std::vector& value_data() const { return m_value_list; } diff --git a/src/rttr/detail/type/type_database.cpp b/src/rttr/detail/type/type_database.cpp index 89f4ad73..576b814e 100644 --- a/src/rttr/detail/type/type_database.cpp +++ b/src/rttr/detail/type/type_database.cpp @@ -115,32 +115,6 @@ type_database::type_database() type_database::~type_database() { - for(auto& prop : m_global_properties.value_data()) - detail::destroy_item(prop); - - for(auto& item : m_type_property_map) - { - for(auto& prop : item.second) - detail::destroy_item(prop); - } - - for(auto& meth : m_global_methods.value_data()) - detail::destroy_item(meth); - - for(auto& item : m_type_method_map) - { - for(auto& prop : item.second) - detail::destroy_item(prop); - } - - for(auto& item : m_type_ctor_map) - { - for(auto& ctor : item.second) - detail::destroy_item(ctor); - } - - for(auto& itr : m_type_dtor_map) - detail::destroy_item(itr.second); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -153,37 +127,50 @@ type_database& type_database::instance() ///////////////////////////////////////////////////////////////////////////////////////// +template +static array_range get_items_for_type(const type& t, + const std::unordered_map>& class_map) +{ + const auto ret = class_map.find(t); + if (ret != class_map.end()) + { + auto& vec = ret->second; + return array_range(vec.data(), vec.size(), + default_predicate([t](const T& item) { return (item.get_declaring_type() == t); }) ); + } + + return array_range(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + template static void update_class_list(const type& t, - const std::unordered_map>& type_map, - std::unordered_map>& class_map) + std::unordered_map>& class_map) { // update type "t" with all items from the base classes - const auto& type_list_itr = type_map.find(t); auto& all_items_list = class_map[t]; + auto item_range = get_items_for_type(t, class_map); + std::vector item_vec(item_range.begin(), item_range.end()); all_items_list.reserve(all_items_list.size() + 1); all_items_list.clear(); // this will not reduce the capacity, i.e. new memory allocation may not necessary - for (const auto& base_type : t.get_base_classes()) { - auto ret = type_map.find(base_type); - if (ret != type_map.end()) - { - auto& base_propery_list = ret->second; - all_items_list.reserve(all_items_list.size() + base_propery_list.size()); - all_items_list.insert(all_items_list.end(), base_propery_list.begin(), base_propery_list.end()); - } + auto base_item_range = get_items_for_type(base_type, class_map); + if (base_item_range.empty()) + continue; + + all_items_list.reserve(all_items_list.size() + base_item_range.size()); + all_items_list.insert(all_items_list.end(), base_item_range.begin(), base_item_range.end()); } + // insert own class items - if (type_list_itr != type_map.end()) - { - all_items_list.reserve(all_items_list.size() + type_list_itr->second.size()); - all_items_list.insert(all_items_list.end(), type_list_itr->second.begin(), type_list_itr->second.end()); - } + all_items_list.reserve(all_items_list.size() + item_vec.size()); + all_items_list.insert(all_items_list.end(), item_vec.begin(), item_vec.end()); // update derived types for (const auto& derived_type : t.get_derived_classes()) - update_class_list(derived_type, type_map, class_map); + update_class_list(derived_type, class_map); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -222,18 +209,18 @@ void type_database::register_property(const type& t, unique_ptr(prop.release())); - - update_class_list(t, m_type_property_map, m_class_property_map); + m_class_property_map[t].emplace_back(detail::create_item(prop.get())); + m_property_list.push_back(std::move(prop)); + update_class_list(t, m_class_property_map); } else { if (get_global_property(name)) return; - property p = detail::create_item(prop.release()); + property p = detail::create_item(prop.get()); m_global_properties.insert(std::move(name), std::move(p)); + m_property_list.push_back(std::move(prop)); } } @@ -248,12 +235,18 @@ property type_database::get_class_property(const type& t, string_view name) cons property type_database::get_type_property(const type& t, string_view name) const { - return get_class_item(t, name, m_type_property_map); + for (const auto& prop : get_items_for_type(t, m_class_property_map)) + { + if (prop.get_name() == name) + return prop; + } + + return create_item(); } ///////////////////////////////////////////////////////////////////////////////////////// -array_range type_database::get_class_properties(const type& t) +array_range type_database::get_class_properties(const type& t) const { const auto ret = m_class_property_map.find(t); if (ret != m_class_property_map.end()) @@ -313,18 +306,18 @@ void type_database::register_method(const type& t, std::unique_ptrget_parameter_infos()))) return; - auto& type_meth_list = m_type_method_map[t]; - type_meth_list.emplace_back(detail::create_item(meth.release())); - - update_class_list(t, m_type_method_map, m_class_method_map); + m_class_method_map[t].emplace_back(detail::create_item(meth.get())); + m_method_list.push_back(std::move(meth)); + update_class_list(t, m_class_method_map); } else { if (get_global_method(name, convert_param_list(meth->get_parameter_infos()))) return; - method m = detail::create_item(meth.release()); + method m = detail::create_item(meth.get()); m_global_methods.insert(std::move(name), std::move(m)); + m_method_list.push_back(std::move(meth)); } } @@ -332,7 +325,15 @@ void type_database::register_method(const type& t, std::unique_ptr(t, name, m_type_method_map); + for (const auto& meth : get_items_for_type(t, m_class_method_map)) + { + if (meth.get_name() == name) + { + return meth; + } + } + + return detail::create_item(); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -347,16 +348,12 @@ method type_database::get_class_method(const type& t, string_view name) const method type_database::get_type_method(const type& t, string_view name, const std::vector& type_list) const { - const auto ret = m_type_method_map.find(t); - if (ret != m_type_method_map.end()) + for (const auto& meth : get_items_for_type(t, m_class_method_map)) { - for (const auto& meth : ret->second) + if (meth.get_name() == name && + detail::compare_with_type_list::compare(meth.get_parameter_infos(), type_list)) { - if ( meth.get_name() == name && - detail::compare_with_type_list::compare(meth.get_parameter_infos(), type_list)) - { - return meth; - } + return meth; } } @@ -524,7 +521,8 @@ void type_database::register_constructor(const type& t, std::unique_ptr(ctor.release())); + m_type_ctor_map[t].emplace_back(detail::create_item(ctor.get())); + m_constructor_list.push_back(std::move(ctor)); } ///////////////////////////////////////////////////////////////////////////////////// @@ -600,7 +598,7 @@ void type_database::register_destructor(const type& t, std::unique_ptr(dtor.get()); const auto ret = m_type_dtor_map.insert(std::make_pair(t, d)); if (ret.second) - dtor.release(); + m_destructor_list.push_back(std::move(dtor)); } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/rttr/detail/type/type_database_p.h b/src/rttr/detail/type/type_database_p.h index 76909340..c2adf941 100644 --- a/src/rttr/detail/type/type_database_p.h +++ b/src/rttr/detail/type/type_database_p.h @@ -106,7 +106,7 @@ class RTTR_LOCAL type_database ///////////////////////////////////////////////////////////////////////////////////// property get_type_property(const type& t, string_view name) const; property get_class_property(const type& t, string_view name) const; - array_range get_class_properties(const type& t); + array_range get_class_properties(const type& t) const; property get_global_property(string_view name) const; array_range get_global_properties(); @@ -232,9 +232,9 @@ class RTTR_LOCAL type_database std::vector m_orig_names; //!< Contains all the raw names provied by 'type::register_type'; The type id is the index in this container std::vector m_custom_names; //!< Contains all the names of m_orig_names, but the names are cleaned up (garbage strings are removed) - //!< and also custom names, provided during manual register (e.g. class_) - flat_map m_orig_name_to_id; //!< This is a sorted vector which contains hash values of the names in \p m_orig_names - flat_map m_custom_name_to_id; //!< This is a sorted vector which contains hash values of the names in \p m_custom_names + + flat_map m_orig_name_to_id; + flat_map m_custom_name_to_id; std::vector m_base_class_list; //!< This list contains for every type the id's of it's base classes (a.k.a. parent class) std::vector m_derived_class_list; //!< This list contains for every type the id's of it's derived classes (a.k.a child class) @@ -261,12 +261,13 @@ class RTTR_LOCAL type_database flat_multimap m_global_methods; flat_multimap m_global_properties; - std::unordered_map> m_type_property_map; - std::unordered_map> m_class_property_map; + std::vector > m_property_list; + std::vector > m_method_list; + std::vector > m_constructor_list; + std::vector > m_destructor_list; - std::unordered_map> m_type_method_map; + std::unordered_map> m_class_property_map; std::unordered_map> m_class_method_map; - std::unordered_map> m_type_ctor_map; std::unordered_map m_type_dtor_map; diff --git a/src/rttr/enumeration.cpp b/src/rttr/enumeration.cpp index c174081e..824635b7 100644 --- a/src/rttr/enumeration.cpp +++ b/src/rttr/enumeration.cpp @@ -36,6 +36,17 @@ using namespace std; namespace rttr { +namespace detail +{ + +template<> +enumeration create_item(const enumeration_wrapper_base* wrapper) +{ + return enumeration(wrapper); +} + +} // end namespace detail + ///////////////////////////////////////////////////////////////////////////////////////// enumeration::enumeration(const detail::enumeration_wrapper_base* wrapper) diff --git a/src/rttr/enumeration.h b/src/rttr/enumeration.h index 74a97f73..953c5df5 100644 --- a/src/rttr/enumeration.h +++ b/src/rttr/enumeration.h @@ -31,6 +31,7 @@ #include "rttr/detail/base/core_prerequisites.h" #include "rttr/type.h" #include "rttr/string_view.h" +#include "rttr/detail/misc/class_item_mapper.h" #include #include @@ -209,6 +210,9 @@ class RTTR_API enumeration friend class type; // to prevent creation of this class //! Constructs a valid MetaProperty from a PropertyContainerBase. enumeration(const detail::enumeration_wrapper_base* wrapper = nullptr); + + template + friend T detail::create_item(const detail::class_item_to_wrapper_t* wrapper); private: const detail::enumeration_wrapper_base* m_wrapper; }; diff --git a/src/rttr/method.cpp b/src/rttr/method.cpp index c49bc176..d3d70c19 100644 --- a/src/rttr/method.cpp +++ b/src/rttr/method.cpp @@ -44,12 +44,6 @@ method create_item(const method_wrapper_base* wrapper) return method(wrapper); } -template<> - void destroy_item(method& meth) - { - delete meth.m_wrapper; - } - } // end namespace detail; ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/rttr/method.h b/src/rttr/method.h index 0a4798e3..b5b3e950 100644 --- a/src/rttr/method.h +++ b/src/rttr/method.h @@ -298,8 +298,6 @@ class RTTR_API method template friend T detail::create_item(const detail::class_item_to_wrapper_t* wrapper); - template - friend void detail::destroy_item(T& item); private: const detail::method_wrapper_base* m_wrapper; diff --git a/src/rttr/property.cpp b/src/rttr/property.cpp index 4985efed..97879605 100644 --- a/src/rttr/property.cpp +++ b/src/rttr/property.cpp @@ -47,12 +47,6 @@ property create_item(const property_wrapper_base* wrapper) return property(wrapper); } -template<> - void destroy_item(property& prop) - { - delete prop.m_wrapper; - } - } // end namespace detail; ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/rttr/property.h b/src/rttr/property.h index 173cbd04..51491f42 100644 --- a/src/rttr/property.h +++ b/src/rttr/property.h @@ -272,8 +272,7 @@ class RTTR_API property template friend T detail::create_item(const detail::class_item_to_wrapper_t* wrapper); - template - friend void detail::destroy_item(T& item); + private: const detail::property_wrapper_base* m_wrapper; }; diff --git a/src/rttr/type.h b/src/rttr/type.h index 569b0ece..eebf4dcd 100644 --- a/src/rttr/type.h +++ b/src/rttr/type.h @@ -29,6 +29,7 @@ #define RTTR_TYPE_H_ #include "rttr/detail/base/core_prerequisites.h" +#include "rttr/string_view.h" #include "rttr/array_range.h" #include