Skip to content

Commit c30a8ce

Browse files
author
Dan Dees
committed
add get_direct_base_classes
1 parent b3a131c commit c30a8ce

File tree

7 files changed

+59
-15
lines changed

7 files changed

+59
-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_data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct RTTR_LOCAL class_data
7777

7878
get_derived_info_func m_derived_info_func;
7979
std::vector<type> m_base_types;
80+
std::vector<type> m_direct_base_types;
8081
std::vector<type> m_derived_types;
8182
std::vector<rttr_cast_func> m_conversion_list;
8283
std::vector<property> m_properties;

src/rttr/detail/type/type_register.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,8 @@ 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& class_data = info->m_class_data;
509+
auto base_classes(info->get_base_types(true));
509510

510511
// remove double entries; can only be happen for virtual inheritance case
511512
set<type> double_entries;
@@ -529,7 +530,6 @@ void type_register_private::register_base_class_info(type_data* info)
529530

530531
if (!base_classes.empty())
531532
{
532-
auto& class_data = info->m_class_data;
533533
for (const auto& t : base_classes)
534534
{
535535
class_data.m_base_types.push_back(t.m_base_type);
@@ -539,14 +539,20 @@ void type_register_private::register_base_class_info(type_data* info)
539539
r_type.m_type_data->m_class_data.m_derived_types.push_back(type(info));
540540
}
541541
}
542+
543+
// base classes which directly inherit
544+
for (const auto& t : info->get_base_types(false) )
545+
{
546+
class_data.m_direct_base_types.emplace_back(t.m_base_type);
547+
}
542548
}
543549

544550
/////////////////////////////////////////////////////////////////////////////////////////
545551

546552
type_data* type_register_private::register_type(type_data* info) RTTR_NOEXCEPT
547553
{
548554
// this will register the base types
549-
info->get_base_types();
555+
info->get_base_types(true);
550556

551557
using namespace detail;
552558

src/rttr/type.cpp

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

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

164+
array_range<type> type::get_direct_base_classes() const RTTR_NOEXCEPT
165+
{
166+
return array_range<type>(
167+
m_type_data->m_class_data.m_direct_base_types.data(),
168+
m_type_data->m_class_data.m_direct_base_types.size());
169+
}
170+
171+
/////////////////////////////////////////////////////////////////////////////////////////
172+
164173
array_range<type> type::get_derived_classes() const RTTR_NOEXCEPT
165174
{
166175
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+
array_range<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)