Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add rttr::type::get_direct_base_classes() #237

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/rttr/detail/registration/registration_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ template<typename Class_Type, typename Visitor_List>
registration::class_<Class_Type, Visitor_List>::~class_()
{
// make sure that all base classes are registered
detail::base_classes<Class_Type>::get_types();
detail::base_classes<Class_Type>::get_types(true);
}

/////////////////////////////////////////////////////////////////////////////////////////
Expand Down
32 changes: 21 additions & 11 deletions src/rttr/detail/type/base_classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ struct RTTR_LOCAL type_from_base_classes;
template<typename DerivedClass>
struct RTTR_LOCAL type_from_base_classes<DerivedClass>
{
static RTTR_INLINE void fill(info_container&)
static RTTR_INLINE void fill(info_container&, bool)
{
}
};
Expand All @@ -105,15 +105,25 @@ static void* rttr_cast_impl(void* ptr)
template<typename DerivedClass, typename BaseClass, typename... U>
struct RTTR_LOCAL type_from_base_classes<DerivedClass, BaseClass, U...>
{
static RTTR_INLINE void fill(info_container& vec)
static RTTR_INLINE void fill(info_container& vec, bool do_all_bases)
{
static_assert(has_base_class_list<BaseClass>::value, "The parent class has no base class list defined - please use the macro RTTR_ENABLE");
vec.emplace_back(type::get<BaseClass>(), &rttr_cast_impl<DerivedClass, BaseClass>);
// retrieve also the types of all base classes of the base classes; you will get an compile error here,
// when the base class has not defined the 'base_class_list' typedef
type_from_base_classes<DerivedClass, typename BaseClass::base_class_list>::fill(vec);
// continue with the rest
type_from_base_classes<DerivedClass, U...>::fill(vec);

// put away pair of "type" and cast to type
vec.emplace_back(
type::get<BaseClass>(),
&rttr_cast_impl<DerivedClass, BaseClass>
);

if ( do_all_bases ) {

// retrieve also the types of all base classes of the base classes; you will get an compile error here,
// when the base class has not defined the 'base_class_list' typedef
type_from_base_classes<DerivedClass, typename BaseClass::base_class_list>::fill(vec, do_all_bases);
}

// continue with the rest of the bases in struct
type_from_base_classes<DerivedClass, U...>::fill(vec, do_all_bases);
}
};

Expand All @@ -127,7 +137,7 @@ struct type_from_base_classes<DerivedClass, type_list<BaseClassList...>> : type_
template<typename T, typename Enable = void>
struct RTTR_LOCAL base_classes
{
static RTTR_INLINE info_container get_types()
static RTTR_INLINE info_container get_types(bool)
{
info_container result;
return result;
Expand All @@ -137,10 +147,10 @@ struct RTTR_LOCAL base_classes
template<typename T>
struct RTTR_LOCAL base_classes<T, typename std::enable_if<has_base_class_list<T>::value>::type>
{
static RTTR_INLINE info_container get_types()
static RTTR_INLINE info_container get_types(bool do_all_bases)
{
info_container result;
type_from_base_classes<T, typename T::base_class_list>::fill(result);
type_from_base_classes<T, typename T::base_class_list>::fill(result, do_all_bases);
return result;
}
};
Expand Down
6 changes: 3 additions & 3 deletions src/rttr/detail/type/type_register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ type_data* type_register_private::register_name_if_neccessary(type_data* info)

void type_register_private::register_base_class_info(type_data* info)
{
auto base_classes = info->get_base_types();
auto base_classes(info->get_base_types(true));

// remove double entries; can only be happen for virtual inheritance case
set<type> double_entries;
Expand All @@ -529,9 +529,9 @@ void type_register_private::register_base_class_info(type_data* info)

if (!base_classes.empty())
{
auto& class_data = info->m_class_data;
for (const auto& t : base_classes)
{
auto& class_data = info->m_class_data;
class_data.m_base_types.push_back(t.m_base_type);
class_data.m_conversion_list.push_back(t.m_rttr_cast_func);

Expand All @@ -546,7 +546,7 @@ void type_register_private::register_base_class_info(type_data* info)
type_data* type_register_private::register_type(type_data* info) RTTR_NOEXCEPT
{
// this will register the base types
info->get_base_types();
info->get_base_types(true);

using namespace detail;

Expand Down
11 changes: 11 additions & 0 deletions src/rttr/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,17 @@ array_range<type> type::get_base_classes() const RTTR_NOEXCEPT

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

std::vector<type> type::get_direct_base_classes() const RTTR_NOEXCEPT
{
std::vector<type> db_vec;
for ( auto&& t : m_type_data->get_base_types(false) ) {
db_vec.emplace_back(t.m_base_type); // transform...
}
return db_vec;
}

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

array_range<type> type::get_derived_classes() const RTTR_NOEXCEPT
{
return array_range<type>(m_type_data->m_class_data.m_derived_types.data(),
Expand Down
7 changes: 7 additions & 0 deletions src/rttr/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,13 @@ class RTTR_API type
*/
array_range<type> get_base_classes() const RTTR_NOEXCEPT;

/*!
* \brief Returns a range of direct base classes of this type in order declarad in RTTR_ENABLE.
*
* \return A range of types.
*/
std::vector<type> get_direct_base_classes() const RTTR_NOEXCEPT;

/*!
* \brief Returns a range of all derived classes of this type.
*
Expand Down
11 changes: 11 additions & 0 deletions src/unit_tests/type/test_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,17 @@ TEST_CASE("type - get_base_classes()", "[type]")
REQUIRE(base_list[2] == type::get<DiamondRight>());
}

TEST_CASE("type - get_direct_base_classes()", "[type]")
{
DiamondBottom d;
const auto& base_list_range = type::get(d).get_direct_base_classes();
REQUIRE(base_list_range.size() == 2);

std::vector<type> base_list(base_list_range.cbegin(), base_list_range.cend());
REQUIRE(base_list[0] == type::get<DiamondLeft>());
REQUIRE(base_list[1] == type::get<DiamondRight>());
}

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

TEST_CASE("type - is_base_of()", "[type]")
Expand Down