Constructible Trait
Exposing the destructor and constructors of a type.
You may find it useful while working with type-erased data to be able to create copies of the data, destroy it, or move it around. The ConstructibleTrait trait exposes the size, alignment, destructor and constructors of a type.
Lets say you have a type Scale
, which you want to be able to reflect, with a default value of 1.0
:
#include <cubos/core/reflection/reflect.hpp> struct Scale { CUBOS_REFLECT; float value = 1.0F; };
We're going to add the ConstructibleTrait trait to it, so that we can create instances of it at runtime:
#include <cubos/core/reflection/traits/constructible.hpp> #include <cubos/core/reflection/type.hpp> using cubos::core::reflection::ConstructibleTrait; using cubos::core::reflection::Type; CUBOS_REFLECT_IMPL(Scale) { return Type::create("Scale").with(ConstructibleTrait::typed<Scale>().withDefaultConstructor().build()); }
Now, we can access the trait from the reflected type:
int main() { using cubos::core::reflection::reflect; const auto& scaleType = reflect<Scale>(); CUBOS_ASSERT(scaleType.has<ConstructibleTrait>()); const auto& constructible = scaleType.get<ConstructibleTrait>();
Imagine for a moment that you don't know the type of the data you're working, and you only have access to its reflection data through scaleType
. If you want to create a default instance of the type, you can call the default constructor stored in the trait:
// Allocate memory for the instance and default-construct it. void* instance = operator new(constructible.size()); constructible.defaultConstruct(instance); CUBOS_ASSERT(static_cast<Scale*>(instance)->value == 1.0F);
Don't forget to destroy the instance manually when you're done with it:
// Destroy the instance and deallocate its memory. constructible.destruct(instance); operator delete(instance); }