getml / reflect-cpp

A C++20 library for fast serialization, deserialization and validation using reflection. Supports JSON, BSON, CBOR, flexbuffers, msgpack, TOML, XML, YAML / msgpack.org[C++20]
https://getml.github.io/reflect-cpp/
MIT License
783 stars 63 forks source link

Enum values inside classes #95

Closed sjkrb closed 2 months ago

sjkrb commented 2 months ago

If i have some class like this :

struct SomeClass
{
    enum hass : uint8_t {j1 = 0, j2 = 1, j3 = 2, j4 = 3};
    std::string name{"foo"};
    std::string last_name {"bar"};
    uint64_t age {0};
    hass has{hass::j1};
    bool valid {false};
};

how can i get the value of this struct members. and if i use to_view and apply i still cant get the enum values correctly

and if i want to use enum class inside my class i have the same problem.

sorry i want to use it but there is not much documents about this topic.

can you help me with this ?

liuzicheng1987 commented 2 months ago

Hi @sjkrb , I have added a new test case for this:

https://github.com/getml/reflect-cpp/blob/f/enums_inside_struct/tests/json/test_enum8.cpp

You certainly will have to use a scoped enumeration ("enum class" instead of "enum"), but other than that it shouldn't be a problem.

But I am a bit unclear what it is you are trying to do...can you provide a bit more detail how you want to use to_view and apply, what you are getting and what you are expecting to get?

sjkrb commented 2 months ago

Thanks for your support.

I have a project that i want to use the values of a class by its string names and types. It perfectly match my needs but in case that i want to use enum or enum class in my code i cant use the to_view

for example look at this code :

SomeClass sj{"sajjad", "karbasi", 26, Sajjad::hass::j2, true};

std::string parameter_name {"has"};

const auto view = rfl::to_view(sj);
view.apply([&](const auto& f) {
            if (parameter_name == f.name())
            {
 //               if constexpr (rfl::internal::enums::is_scoped_enum<decltype(*f.value())>)
 //                   std::cout << rfl::enum_to_string(*f.value()) << std::endl;
 //               else
                    std::cout << *f.value() << std::endl;
            }
});

and i this gives me nothing or if I uncomment above code it gives me error . can you tell me how to fix this problem and use some code like this.

liuzicheng1987 commented 2 months ago

@sjkrb, here's the fix:

  SomeClass sj{"sajjad", "karbasi", 26, SomeClass::hass::j2, true};

  const auto view = rfl::to_view(sj);

  view.apply([&](const auto& f) {
    if constexpr (f.name() == "has") {
      std::cout << rfl::enum_to_string(*f.value()) << std::endl;
    } else {
      std::cout << *f.value() << std::endl;
    }
  });

I get the following output:

sajjad
karbasi
26
j2
1

I have checked the documentation, it is documented in here:

https://github.com/getml/reflect-cpp/blob/main/docs/named_tuple.md

How to use .name() is documented in the section on .transform and .and_then, but maybe we should write in in .apply as well. Would that have clarified things for you?

sjkrb commented 2 months ago

thanks that works for me. best regards.