[#MRDOCS_DESCRIBE_ENUM] = MRDOCS_DESCRIBE_ENUM :mrdocs: Describe the enumerators of an enum. == Synopsis Declared in `<mrdocs/Support/Reflection/Describe.hpp>` [source,cpp,subs="verbatim,replacements,macros,-callouts"] ---- #define MRDOCS_DESCRIBE_ENUM(E, ...) ---- == Description Pass the enum type followed by the enumerators you want to describe, up to 128 of them. Place it at namespace scope, in the same namespace as the enum, after the enum definition: [,cpp] ---- namespace shapes { enum class Shape { Circle, RoundedRect, Triangle }; MRDOCS_DESCRIBE_ENUM(Shape, Circle, RoundedRect, Triangle) } // namespace shapes ---- The macro declares a function that is found by argument‐dependent lookup and whose return type lists one descriptor per enumerator: [,cpp] ---- // Simplified: whitespace changed; each lambda is a distinct closure // type that only returns the stringized enumerator name. // MRDOCS_DESCRIBE_ENUM(Shape, Circle, RoundedRect, Triangle) static_assert(std::is_enum_v, "MRDOCS_DESCRIBE_ENUM should only be used with enums"); [[maybe_unused]] decltype(::mrdocs::describe::detail::enum_descriptor_fn_impl(0 , ::mrdocs::describe::detail::enum_descriptor< Shape::Circle, []{ return "Circle"; }>{} , ::mrdocs::describe::detail::enum_descriptor< Shape::RoundedRect, []{ return "RoundedRect"; }>{} , ::mrdocs::describe::detail::enum_descriptor< Shape::Triangle, []{ return "Triangle"; }>{} )) mrdocs_enum_descriptor_fn(Shape**); // The return type is describe::list, where each Di has // `static constexpr Shape value` and `static constexpr char const* // name`. The function is declared only; it's never called. ---- Afterwards the enum works with the describe queries and the string helpers, all usable in constant expressions: [,cpp] ---- namespace describe = mrdocs::describe; using shapes::Shape; static_assert(describe::has_describe_enumerators::value); // Kebab-case name, as used in the generated output static_assert(mrdocs::toString(Shape::RoundedRect) == "rounded-rect"); // Declared name static_assert( describe::enum_to_string(Shape::RoundedRect) == "RoundedRect"); void demo() { // Declared name back to the enumerator Shape s{}; bool ok = describe::enum_from_string("Triangle", s); // ok == true, s == Shape::Triangle // Visit every described enumerator describe::for_each( describe::describe_enumerators{}, [](auto d) { // d.value: Shape::Circle, then RoundedRect, then Triangle // d.name: "Circle", then "RoundedRect", then "Triangle" }); } ---- Things to keep in mind: * Don't put it inside a class, even for a nested enum. There it declares a member function that lookup never finds, so the enum silently stays undescribed. For a nested enum, write it at namespace scope after the class and qualify the type: `MRDOCS_DESCRIBE_ENUM(Canvas::Layer, background, foreground)`. * Writing it in a different namespace also leaves the enum undescribed, for the same reason. * It already ends with a semicolon, so don't add one. * Enumerators you leave out are unknown to the helpers: `toString` and `describe::enum_to_string` return an empty string for them, and `describe::enum_from_string` never produces them. * Works for scoped and unscoped enums, since each entry is spelled `E::name`. * When the enumerators already live in an X‐macro `.inc` file, use `MRDOCS_DESCRIBE_ENUM_BEGIN` and `MRDOCS_DESCRIBE_ENUM_END` instead. They also have no limit on the number of enumerators. * To mark one enumerator as the empty state, follow it with `MRDOCS_DESCRIBE_ENUM_UNDEFINED`. == Parameters [cols="1,4"] |=== | Name| Description | *E* | The enum type. |=== [.small]#Created with https://www.mrdocs.com[MrDocs]#