Mask Trait
Exposing a bit mask type.
In this example, we'll explore how to expose a bit mask along with its bits using cubos::
#include <cubos/core/reflection/reflect.hpp> enum class Permissions { None = 0, Read = 1, Write = 2, Execute = 4 }; CUBOS_REFLECT_EXTERNAL_DECL(CUBOS_EMPTY, Permissions); inline Permissions operator~(Permissions p) { return static_cast<Permissions>(~static_cast<int>(p)); } inline Permissions operator|(Permissions a, Permissions b) { return static_cast<Permissions>(static_cast<int>(a) | static_cast<int>(b)); } inline Permissions operator&(Permissions a, Permissions b) { return static_cast<Permissions>(static_cast<int>(a) & static_cast<int>(b)); }
#include <cubos/core/reflection/traits/mask.hpp> #include <cubos/core/reflection/type.hpp> using cubos::core::reflection::MaskTrait; using cubos::core::reflection::Type; CUBOS_REFLECT_EXTERNAL_IMPL(Permissions) { return Type::create("Permissions") .with(MaskTrait{} .withBit<Permissions::Read>("Read") .withBit<Permissions::Write>("Write") .withBit<Permissions::Execute>("Execute")); }
Notice that we don't include the None
type in the trait, as it doesn't correspond to a bit.
int main() { using cubos::core::reflection::reflect; const auto& permissionsType = reflect<Permissions>(); CUBOS_ASSERT(permissionsType.has<MaskTrait>()); const auto& mask = permissionsType.get<MaskTrait>(); CUBOS_ASSERT(mask.contains("Read")); CUBOS_ASSERT(mask.contains("Write")); CUBOS_ASSERT(mask.contains("Execute")); CUBOS_ASSERT(!mask.contains("None")); auto p = Permissions::Read | Permissions::Write; CUBOS_ASSERT(mask.view(&p).test("Read")); CUBOS_ASSERT(mask.view(&p).test("Write")); CUBOS_ASSERT(!mask.view(&p).test("Execute")); for (const auto& b : mask) { CUBOS_INFO("Type has bit {}", b.name()); } for (const auto& b : mask.view(&p)) { CUBOS_INFO("Value has bit {} set", b.name()); } return 0; }
// Type has bit "Read" // Type has bit "Write" // Type has bit "Execute" // Value has bit "Read" set // Value has bit "Write" set