Git Product home page Git Product logo

Comments (2)

veselink1 avatar veselink1 commented on May 20, 2024

Hello,

Yes, that is entirely doable through a combination of an attribute of a variadic template type and refl::util::for_each. There is no built-in way in C++ to get that information, so someone will have to provide it manually (proposal for it seems to have been rejected https://stackoverflow.com/a/33664204).

Currently there is a bug in the built-in refl::attr::base_types, so I would recommend not using it. I expect that it will end up being replaced by something more useful.

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';
    });
}

"get_attribute" does not accept a template type like BaseClass

get_attribute has an overload that accepts a variadic Attribute<Ts...> as well. It is not available unprefixed (like for_each) since ADL does not kick-in for names with explicitly specified types.

If there is a ForEach for attributes

for_each iterates over type_list<Ts...> only, but one could use refl::trait::as_type_list_t to convert any T<Ts..> (like std::tuple<Ts...>) into type_list<Ts...>.

PS: You've build a great library.

Thanks.

from refl-cpp.

ccvca avatar ccvca commented on May 20, 2024

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:

TestReflCppBaseClass
Base: Base1_t
Type: Base1_t
Base1A = Base1A
Base1B = Base1B
Base: Base2_t
Type: Base2_t
Base2A = Base2A
Base2B = Base2B
Type: Sub_t
SubA = SubA
TestReflCppBaseClass End

from refl-cpp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.