-1

I want to send a var to a function if is it a class. I try with std::is_class but this gave me an erros because std::is_class is run time and not a preprocessor. I can't make the preprocessor if to work. any suggestions? in the function 'toJson' in the loop I am adding the types to the json object. I need to check if the type is class, for recursive adding the classes fields to the json object.

source code: https://stackoverflow.com/a/34165367/13277578

template<typename Class, typename T>
struct PropertyImpl {
    constexpr PropertyImpl(T Class::* aMember, const char* aName) : member{ aMember }, name{ aName } {}

    using Type = T;

    T Class::* member;
    const char* name;
};

template<typename Class, typename T>
constexpr auto property(T Class::* member, const char* name) {
    return PropertyImpl<Class, T>{member, name};
}

template <typename T, T... S, typename F>
constexpr void for_sequence(std::integer_sequence<T, S...>, F&& f) {
    (static_cast<void>(f(std::integral_constant<T, S>{})), ...);
}

// the error in this function
template<typename T>
json toJson(const T& object)
{
    json data;

    // We first get the number of properties
    constexpr auto nbProperties = std::tuple_size<decltype(T::properties)>::value;

    // We iterate on the index sequence of size `nbProperties`
    for_sequence(std::make_index_sequence<nbProperties>{}, [&](auto i) {
        // get the property
        constexpr auto property = std::get<i>(T::properties);

        using Type = typename decltype(property)::Type;

        #if __is_class(Type) // C1017
        // data[property.name] = toJson(object.*(property.member))  // recursive add the object fields
        #else
        // addFind(data, object.*(property.member), property.name)) // add the object field (WORK)
        #endif
        });

    return data;
}

example of using toJson:

#define PROPERTY(CLASS, MEMBER) property(&CLASS::MEMBER, #MEMBER)

    struct GetRooms
    {
        unsigned int status = 0;
        RoomData roomData;
        string name;

        constexpr static auto properties = std::make_tuple(
            PROPERTY(GetRooms, status),
            PROPERTY(GetRooms, roomData),
            PROPERTY(GetRooms, name)
        );
    };

    GetRooms var;
    json varAsJson = toJson(var);
jacob galam
  • 781
  • 9
  • 21
  • 2
    Why do you want to do this using the preprocessor? What problem are you trying to solve? – HolyBlackCat Jun 11 '20 at 18:08
  • 3
    Types don't exist yet during preprocessing. There's no way this could work. – chris Jun 11 '20 at 18:09
  • You shouldn't need the preprocessor for this. Can you use some pseudo code to show what the code flow should look like? – NathanOliver Jun 11 '20 at 18:09
  • @HolyBlackCat I try to make object to json automatic. the code work but if I have class inside a class this is give me the error 'C2678', becuse the json object don't have = operator with my class. https://stackoverflow.com/questions/61732417/converting-any-struct-to-json-automatic-in-c – jacob galam Jun 11 '20 at 18:15
  • `std::is_class` is most certainly not computed at runtime. You appear to have many misconceptions. Please provide a [mcve] so we can understand the overall problem you're trying to solve. I suspect that your json problem can be solved with something as simple as function overloading. – alter_igel Jun 11 '20 at 18:17
  • @alterigel I try function overloading, but how can I do this with template? It is possible to have primitve types template and classes types template? – jacob galam Jun 11 '20 at 18:24
  • 1
    Please explain what you're trying to do, not how you think you should do it – Asteroids With Wings Jun 11 '20 at 18:27
  • Thank you for expanding on your code snippet. Could you add an example of how you would want to use `toJson`? Right now, we have no understanding of what `T::properties` is but it seems to be very important. – alter_igel Jun 11 '20 at 18:37
  • 1
    It's possible you're looking for `if constexpr` or tag dispatching. – chris Jun 11 '20 at 18:39
  • @AsteroidsWithWings I update the question I hope is what you wanted – jacob galam Jun 11 '20 at 18:40
  • Still, the point remains about the preprocessor being the wrong tool for this. The preprocessor runs on the raw source code before any parsing is done, and even if `#if __is_class(Type)` magically worked, it would necessarily produce the exact same code for every instantiation of `toJson` which is obviously not what you would want. Even so, it seems like you are writing something that is an insanely complicated workaround for static reflection when it would be far easier to write a single idiomatic `to_json` as in `nlohmann::json` for the types you intend to convert. – alter_igel Jun 11 '20 at 18:41
  • @chris It really it!!!! Thank you!! Also, this topic, of preprocessor, template, macro constexpr act. Have any special name in C++? Or can you give me a link or something for more info about this topic? I want to do more research about this. – jacob galam Jun 11 '20 at 18:57
  • 1
    Metaprogramming? That's a pretty broad list. – chris Jun 11 '20 at 19:02

1 Answers1

0

if constexpr Is exactly what I needed. It can compares the type at compile time, which allow me to call the right function and ignore completely the other function that is not compatible with this type.

if constexpr (std::is_class<Type>::value)
{
    // call the class function
}
else
{
    // not call the class function
}
jacob galam
  • 781
  • 9
  • 21