Skip to content

Commit ed37cfc

Browse files
author
Dan Dees
committed
add get_direct_base_classes
1 parent b16fccf commit ed37cfc

File tree

6 files changed

+54
-15
lines changed

6 files changed

+54
-15
lines changed

src/rttr/detail/registration/registration_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ template<typename Class_Type, typename Visitor_List>
115115
registration::class_<Class_Type, Visitor_List>::~class_()
116116
{
117117
// make sure that all base classes are registered
118-
detail::base_classes<Class_Type>::get_types();
118+
detail::base_classes<Class_Type>::get_types(true);
119119
}
120120

121121
/////////////////////////////////////////////////////////////////////////////////////////

src/rttr/detail/type/base_classes.h

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ struct RTTR_LOCAL type_from_base_classes;
8282
template<typename DerivedClass>
8383
struct RTTR_LOCAL type_from_base_classes<DerivedClass>
8484
{
85-
static RTTR_INLINE void fill(info_container&)
85+
static RTTR_INLINE void fill(info_container&, bool)
8686
{
8787
}
8888
};
@@ -105,15 +105,25 @@ static void* rttr_cast_impl(void* ptr)
105105
template<typename DerivedClass, typename BaseClass, typename... U>
106106
struct RTTR_LOCAL type_from_base_classes<DerivedClass, BaseClass, U...>
107107
{
108-
static RTTR_INLINE void fill(info_container& vec)
108+
static RTTR_INLINE void fill(info_container& vec, bool do_all_bases)
109109
{
110110
static_assert(has_base_class_list<BaseClass>::value, "The parent class has no base class list defined - please use the macro RTTR_ENABLE");
111-
vec.emplace_back(type::get<BaseClass>(), &rttr_cast_impl<DerivedClass, BaseClass>);
112-
// retrieve also the types of all base classes of the base classes; you will get an compile error here,
113-
// when the base class has not defined the 'base_class_list' typedef
114-
type_from_base_classes<DerivedClass, typename BaseClass::base_class_list>::fill(vec);
115-
// continue with the rest
116-
type_from_base_classes<DerivedClass, U...>::fill(vec);
111+
112+
// put away pair of "type" and cast to type
113+
vec.emplace_back(
114+
type::get<BaseClass>(),
115+
&rttr_cast_impl<DerivedClass, BaseClass>
116+
);
117+
118+
if ( do_all_bases ) {
119+
120+
// retrieve also the types of all base classes of the base classes; you will get an compile error here,
121+
// when the base class has not defined the 'base_class_list' typedef
122+
type_from_base_classes<DerivedClass, typename BaseClass::base_class_list>::fill(vec, do_all_bases);
123+
}
124+
125+
// continue with the rest of the bases in struct
126+
type_from_base_classes<DerivedClass, U...>::fill(vec, do_all_bases);
117127
}
118128
};
119129

@@ -127,7 +137,7 @@ struct type_from_base_classes<DerivedClass, type_list<BaseClassList...>> : type_
127137
template<typename T, typename Enable = void>
128138
struct RTTR_LOCAL base_classes
129139
{
130-
static RTTR_INLINE info_container get_types()
140+
static RTTR_INLINE info_container get_types(bool)
131141
{
132142
info_container result;
133143
return result;
@@ -137,10 +147,10 @@ struct RTTR_LOCAL base_classes
137147
template<typename T>
138148
struct RTTR_LOCAL base_classes<T, typename std::enable_if<has_base_class_list<T>::value>::type>
139149
{
140-
static RTTR_INLINE info_container get_types()
150+
static RTTR_INLINE info_container get_types(bool do_all_bases)
141151
{
142152
info_container result;
143-
type_from_base_classes<T, typename T::base_class_list>::fill(result);
153+
type_from_base_classes<T, typename T::base_class_list>::fill(result, do_all_bases);
144154
return result;
145155
}
146156
};

src/rttr/detail/type/type_register.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ type_data* type_register_private::register_name_if_neccessary(type_data* info)
505505

506506
void type_register_private::register_base_class_info(type_data* info)
507507
{
508-
auto base_classes = info->get_base_types();
508+
auto base_classes(info->get_base_types(true));
509509

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

530530
if (!base_classes.empty())
531531
{
532-
auto& class_data = info->m_class_data;
533532
for (const auto& t : base_classes)
534533
{
534+
auto& class_data = info->m_class_data;
535535
class_data.m_base_types.push_back(t.m_base_type);
536536
class_data.m_conversion_list.push_back(t.m_rttr_cast_func);
537537

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

551551
using namespace detail;
552552

src/rttr/type.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ array_range<type> type::get_base_classes() const RTTR_NOEXCEPT
161161

162162
/////////////////////////////////////////////////////////////////////////////////////////
163163

164+
std::vector<type> type::get_direct_base_classes() const RTTR_NOEXCEPT
165+
{
166+
std::vector<type> db_vec;
167+
for ( auto&& t : m_type_data->get_base_types(false) ) {
168+
db_vec.emplace_back(t.m_base_type); // transform...
169+
}
170+
return db_vec;
171+
}
172+
173+
/////////////////////////////////////////////////////////////////////////////////////////
174+
164175
array_range<type> type::get_derived_classes() const RTTR_NOEXCEPT
165176
{
166177
return array_range<type>(m_type_data->m_class_data.m_derived_types.data(),

src/rttr/type.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,13 @@ class RTTR_API type
573573
*/
574574
array_range<type> get_base_classes() const RTTR_NOEXCEPT;
575575

576+
/*!
577+
* \brief Returns a range of direct base classes of this type in order declarad in RTTR_ENABLE.
578+
*
579+
* \return A range of types.
580+
*/
581+
std::vector<type> get_direct_base_classes() const RTTR_NOEXCEPT;
582+
576583
/*!
577584
* \brief Returns a range of all derived classes of this type.
578585
*

src/unit_tests/type/test_type.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,17 @@ TEST_CASE("type - get_base_classes()", "[type]")
287287
REQUIRE(base_list[2] == type::get<DiamondRight>());
288288
}
289289

290+
TEST_CASE("type - get_direct_base_classes()", "[type]")
291+
{
292+
DiamondBottom d;
293+
const auto& base_list_range = type::get(d).get_direct_base_classes();
294+
REQUIRE(base_list_range.size() == 2);
295+
296+
std::vector<type> base_list(base_list_range.cbegin(), base_list_range.cend());
297+
REQUIRE(base_list[0] == type::get<DiamondLeft>());
298+
REQUIRE(base_list[1] == type::get<DiamondRight>());
299+
}
300+
290301
/////////////////////////////////////////////////////////////////////////////////////////
291302

292303
TEST_CASE("type - is_base_of()", "[type]")

0 commit comments

Comments
 (0)