Skip to content

Commit

Permalink
removed explictely destroy of wrapper objects in dtor of type_database
Browse files Browse the repository at this point in the history
All wrapper items will be stored as unique_ptr in general std::vector<T> 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.
  • Loading branch information
acki-m committed Apr 27, 2016
1 parent a5ee20b commit 7b31832
Show file tree
Hide file tree
Showing 18 changed files with 115 additions and 127 deletions.
17 changes: 2 additions & 15 deletions src/rttr/array_range.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,12 @@ class property;
class method;
class constructor;
class enumeration;
class type;
class parameter_info;

template<typename T, typename Predicate>
class array_range;

namespace detail
{
template<typename T>
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<typename T>
struct default_predicate;

} // end namespace detail

Expand Down
6 changes: 0 additions & 6 deletions src/rttr/constructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

/////////////////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 0 additions & 2 deletions src/rttr/constructor.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,6 @@ class RTTR_API constructor

template<typename T>
friend T detail::create_item(const detail::class_item_to_wrapper_t<T>* wrapper);
template<typename T>
friend void detail::destroy_item(T& item);

private:
const detail::constructor_wrapper_base* m_wrapper;
Expand Down
6 changes: 0 additions & 6 deletions src/rttr/destructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

/////////////////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 0 additions & 2 deletions src/rttr/destructor.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,6 @@ class RTTR_API destructor

template<typename T>
friend T detail::create_item(const detail::class_item_to_wrapper_t<T>* wrapper);
template<typename T>
friend void detail::destroy_item(T& item);

private:
const detail::destructor_wrapper_base* m_wrapper;
Expand Down
19 changes: 19 additions & 0 deletions src/rttr/detail/impl/array_range_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include "rttr/detail/base/core_prerequisites.h"
#include "rttr/property.h"
#include "rttr/type.h"
#include <memory>

namespace rttr
{
Expand Down Expand Up @@ -432,6 +434,23 @@ array_range<T, Predicate>::array_reverse_iterator<DataType>::operator++(int inde

/////////////////////////////////////////////////////////////////////////////////////////

namespace detail
{

template<typename T>
struct default_predicate
{
RTTR_FORCE_INLINE default_predicate() {}
RTTR_FORCE_INLINE default_predicate(std::function<bool(const T&)> func) : m_func(std::move(func)) {}
RTTR_FORCE_INLINE bool operator()(const T& obj) const { return (m_func ? m_func(obj) : true); }
std::function<bool(const T&)> m_func;
};


/////////////////////////////////////////////////////////////////////////////////////////

} // end namespace detail

} // end namespace rttr


Expand Down
2 changes: 0 additions & 2 deletions src/rttr/detail/misc/class_item_mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ using class_item_to_wrapper_t = conditional_t< std::is_same<T, property>::value,

template<typename T>
T create_item(const class_item_to_wrapper_t<T>* wrapper = nullptr);
template<typename T>
void destroy_item(T& item);

} // end namespace detail
} // end namespace rttr
Expand Down
4 changes: 2 additions & 2 deletions src/rttr/detail/misc/flat_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -199,7 +199,7 @@ class flat_map
m_value_list.clear();
}

std::vector<Value>& value_data()
const std::vector<Value>& value_data() const
{
return m_value_list;
}
Expand Down
4 changes: 2 additions & 2 deletions src/rttr/detail/misc/flat_multimap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -180,7 +180,7 @@ class flat_multimap
}
#endif

std::vector<Value>& value_data()
const std::vector<Value>& value_data() const
{
return m_value_list;
}
Expand Down
130 changes: 64 additions & 66 deletions src/rttr/detail/type/type_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,32 +115,6 @@ type_database::type_database()

type_database::~type_database()
{
for(auto& prop : m_global_properties.value_data())
detail::destroy_item<property>(prop);

for(auto& item : m_type_property_map)
{
for(auto& prop : item.second)
detail::destroy_item<property>(prop);
}

for(auto& meth : m_global_methods.value_data())
detail::destroy_item<method>(meth);

for(auto& item : m_type_method_map)
{
for(auto& prop : item.second)
detail::destroy_item<method>(prop);
}

for(auto& item : m_type_ctor_map)
{
for(auto& ctor : item.second)
detail::destroy_item<constructor>(ctor);
}

for(auto& itr : m_type_dtor_map)
detail::destroy_item<destructor>(itr.second);
}

/////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -153,37 +127,50 @@ type_database& type_database::instance()

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
static array_range<T> get_items_for_type(const type& t,
const std::unordered_map<type, std::vector<T>>& class_map)
{
const auto ret = class_map.find(t);
if (ret != class_map.end())
{
auto& vec = ret->second;
return array_range<T>(vec.data(), vec.size(),
default_predicate<T>([t](const T& item) { return (item.get_declaring_type() == t); }) );
}

return array_range<T>();
}

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
static void update_class_list(const type& t,
const std::unordered_map<type, std::vector<T>>& type_map,
std::unordered_map<type, std::vector<T>>& class_map)
std::unordered_map<type, std::vector<T>>& 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>(t, class_map);
std::vector<T> 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<T>(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<T>(derived_type, type_map, class_map);
update_class_list<T>(derived_type, class_map);
}

/////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -222,18 +209,18 @@ void type_database::register_property(const type& t, unique_ptr<property_wrapper
if (get_type_property(t, name))
return;

auto& type_prop_list = m_type_property_map[t];
type_prop_list.emplace_back(detail::create_item<property>(prop.release()));

update_class_list<property>(t, m_type_property_map, m_class_property_map);
m_class_property_map[t].emplace_back(detail::create_item<property>(prop.get()));
m_property_list.push_back(std::move(prop));
update_class_list<property>(t, m_class_property_map);
}
else
{
if (get_global_property(name))
return;

property p = detail::create_item<property>(prop.release());
property p = detail::create_item<property>(prop.get());
m_global_properties.insert(std::move(name), std::move(p));
m_property_list.push_back(std::move(prop));
}
}

Expand All @@ -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<property>(t, name, m_type_property_map);
for (const auto& prop : get_items_for_type<property>(t, m_class_property_map))
{
if (prop.get_name() == name)
return prop;
}

return create_item<property>();
}

/////////////////////////////////////////////////////////////////////////////////////////

array_range<property> type_database::get_class_properties(const type& t)
array_range<property> 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())
Expand Down Expand Up @@ -313,26 +306,34 @@ void type_database::register_method(const type& t, std::unique_ptr<method_wrappe
if (get_type_method(t, name, convert_param_list(meth->get_parameter_infos())))
return;

auto& type_meth_list = m_type_method_map[t];
type_meth_list.emplace_back(detail::create_item<method>(meth.release()));

update_class_list<method>(t, m_type_method_map, m_class_method_map);
m_class_method_map[t].emplace_back(detail::create_item<method>(meth.get()));
m_method_list.push_back(std::move(meth));
update_class_list<method>(t, m_class_method_map);
}
else
{
if (get_global_method(name, convert_param_list(meth->get_parameter_infos())))
return;

method m = detail::create_item<method>(meth.release());
method m = detail::create_item<method>(meth.get());
m_global_methods.insert(std::move(name), std::move(m));
m_method_list.push_back(std::move(meth));
}
}

/////////////////////////////////////////////////////////////////////////////////////////

method type_database::get_type_method(const type& t, string_view name) const
{
return get_class_item<method>(t, name, m_type_method_map);
for (const auto& meth : get_items_for_type<method>(t, m_class_method_map))
{
if (meth.get_name() == name)
{
return meth;
}
}

return detail::create_item<method>();
}

/////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -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>& 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<method>(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;
}
}

Expand Down Expand Up @@ -524,7 +521,8 @@ void type_database::register_constructor(const type& t, std::unique_ptr<construc
return;

// TO DO you cannot create constructor with the same argument type
m_type_ctor_map[t].emplace_back(detail::create_item<constructor>(ctor.release()));
m_type_ctor_map[t].emplace_back(detail::create_item<constructor>(ctor.get()));
m_constructor_list.push_back(std::move(ctor));
}

/////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -600,7 +598,7 @@ void type_database::register_destructor(const type& t, std::unique_ptr<destructo
auto d = detail::create_item<destructor>(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));
}

/////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit 7b31832

Please sign in to comment.