Fields Trait
Exposing the fields of a type.
For structured types, like classes and structs, you might want to expose its public fields using the FieldsTrait trait. In this example, we'll expose the fields of the following type:
#include <cubos/core/reflection/reflect.hpp> struct Person { CUBOS_REFLECT; int32_t age; float weight; bool dead; };
In its reflection definition, we'll add the FieldsTrait trait to it with each of the fields we want to expose:
#include <cubos/core/reflection/traits/fields.hpp> #include <cubos/core/reflection/type.hpp> // Since we're exposing fields of primitive types (int32_t, float and bool), its important to // include the header which defines their reflection. #include <cubos/core/reflection/external/primitives.hpp> using cubos::core::reflection::FieldsTrait; using cubos::core::reflection::Type; CUBOS_REFLECT_IMPL(Person) { return Type::create("Person").with(FieldsTrait() .withField("age", &Person::age) .withField("weight", &Person::weight) .withField("dead", &Person::dead)); }
Accessing this trait is the same as with any other trait:
int main() { using cubos::core::reflection::reflect; const auto& personType = reflect<Person>(); CUBOS_ASSERT(personType.has<FieldsTrait>()); const auto& fields = personType.get<FieldsTrait>();
We can iterate over the fields of the type with it:
for (const auto& field : fields) { CUBOS_INFO("Field {} of type {}", field.name(), field.type().name()); }
This should output:
// Field 'age' of type 'int32_t' // Field 'weight' of type 'float' // Field 'dead' of type 'bool'
Its also possible to access the fields of an instance of the type, and iterate over them:
Person person{.age = 21, .weight = 68.4F, .dead = false}; auto view = fields.view(&person); for (auto [field, value] : view) { if (field->type().is<int32_t>()) { CUBOS_INFO("Field {}: {}", field->name(), *static_cast<int32_t*>(value)); } else if (field->type().is<float>()) { CUBOS_INFO("Field {}: {}", field->name(), *static_cast<float*>(value)); } else { CUBOS_INFO("Field {}: unsupported type {}", field->name(), field->type().name()); } }
// Field 'age': 21 // Field 'weight': 68.4 // Field 'dead': unsupported type 'bool'
Its also possible to access the fields by name:
*static_cast<float*>(view.get("weight")) += 20.0F; CUBOS_INFO("New weight: {}", person.weight); // 88.4 }
// New weight: 88.4