Skip to content

Commit

Permalink
add get_direct_base_classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Dees committed Oct 1, 2020
1 parent b16fccf commit ed37cfc
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 15 deletions.
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

0 comments on commit ed37cfc

Please sign in to comment.