-
-
Notifications
You must be signed in to change notification settings - Fork 75
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
Reflect Inheritance hierarchy #14
Comments
Hello, Yes, that is entirely doable through a combination of an attribute of a variadic template type and Currently there is a bug in the built-in Instead, you could create your own attribute like so: template <typename... Ts>
struct Bases : public refl::attr::usage::type {
static constexpr refl::type_list<refl::type_descriptor<Ts>...> descriptors;
}; And use it like this: constexpr auto bases = refl::descriptor::get_attribute<Bases>(refl::reflect<T>());
if constexpr (bases.descriptors.size) {
for_each(bases.descriptors, [](auto t) {
std::cout << t.name << '\n';
});
}
Thanks. |
Many thanks, this library is more powerful than I expected :). If anyone needs something similar, here is a complete example: (Tested using v0.8.1) #include <iostream>
#include <refl.hpp>
#include <string>
template <typename... Ts>
struct Bases : public refl::attr::usage::type {
static constexpr refl::type_list<refl::type_descriptor<Ts>...> descriptors = {};
};
struct Base1_t{
std::string Base1A;
std::string Base1B;
};
REFL_TYPE(Base1_t)
REFL_FIELD(Base1A)
REFL_FIELD(Base1B)
REFL_END
struct Base2_t{
std::string Base2A;
std::string Base2B;
};
REFL_TYPE(Base2_t)
REFL_FIELD(Base2A)
REFL_FIELD(Base2B)
REFL_END
struct Sub_t : public Base1_t, public Base2_t{
std::string SubA;
};
REFL_TYPE(Sub_t, Bases<Base1_t, Base2_t>())
REFL_FIELD(SubA)
REFL_END
template<typename T>
void useIt(T *instance);
template<typename T>
void useIt(T *instance)
{
if constexpr(refl::descriptor::has_attribute<Bases>(refl::reflect<T>())){
constexpr auto bases = refl::descriptor::get_attribute<Bases>(refl::reflect<T>());
if constexpr (bases.descriptors.size) {
refl::util::for_each(bases.descriptors, [&](auto t) {
std::cout << "Base: " << t.name << std::endl;
useIt(static_cast<typename decltype(t)::type*>(instance));
});
}
}
std::cout << "Type: " << refl::reflect<T>().name << std::endl;
for_each(refl::reflect<T>().members, [&](auto member) {
std::cout << member.name << " = " << member(*instance) << std::endl;
});
}
int main(int argc, char* argv[])
{
Sub_t sub;
sub.SubA = "SubA";
sub.Base1A = "Base1A";
sub.Base1B = "Base1B";
sub.Base2A = "Base2A";
sub.Base2B = "Base2B";
std::cout << "TestReflCppBaseClass" << std::endl;
useIt(&sub);
std::cout << "TestReflCppBaseClass End" << std::endl;
return 0;
} Output:
|
Is it possible to iterate over the base classes in any way?
I'm thinking about something like this:
Or is this possible using attributes? I didn't find a solution for this, as "get_attribute" does not accept a template type like BaseClass.
If there is a ForEach for attributes, then it could be combined with this https://stackoverflow.com/a/21512908 to build something equivalent out of attributes. But I couldn't find a way to iterate over attributes either.
PS: You've build a great library.
The text was updated successfully, but these errors were encountered: