Open an enum description driven by an X-macro .inc file.
Declared in <mrdocs/Support/Reflection/Describe.hpp>
#define MRDOCS_DESCRIBE_ENUM_BEGIN(E)
Use it when the enumerators already live in an X-macro .inc file, one INFO(Name) line per enumerator, that also defines the enum. You then describe the enum from the same list instead of repeating every name in MRDOCS_DESCRIBE_ENUM, so the two can't drift apart.
Given this ShapeNodes.inc:
#ifndef INFO
#define INFO(Name)
#endif
INFO(Circle)
INFO(RoundedRect)
INFO(Triangle)
#undef INFO
include it once to define the enum and once more between MRDOCS_DESCRIBE_ENUM_BEGIN and MRDOCS_DESCRIBE_ENUM_END, with INFO pointed at MRDOCS_ENUM_ENTRY:
namespace shapes {
enum class ShapeKind
{
None = 0,
#define INFO(Name) Name,
#include "ShapeNodes.inc"
};
MRDOCS_DESCRIBE_ENUM_BEGIN(ShapeKind)
#define INFO(Name) MRDOCS_ENUM_ENTRY(ShapeKind, Name)
#include "ShapeNodes.inc"
MRDOCS_DESCRIBE_ENUM_END(ShapeKind)
} // namespace shapes
The .inc file #undefs INFO itself, so no cleanup line is needed. The three pieces together produce the same declaration as MRDOCS_DESCRIBE_ENUM(ShapeKind, Circle, RoundedRect, Triangle):
// Simplified: each lambda is a distinct closure type that returns the
// stringized name.
// MRDOCS_DESCRIBE_ENUM_BEGIN(ShapeKind)
static_assert(std::is_enum_v<ShapeKind>,
"MRDOCS_DESCRIBE_ENUM should only be used with enums");
[[maybe_unused]]
decltype(::mrdocs::describe::detail::enum_descriptor_fn_impl(0
// #include "ShapeNodes.inc": one MRDOCS_ENUM_ENTRY per INFO line
, ::mrdocs::describe::detail::enum_descriptor<
ShapeKind::Circle, []{ return "Circle"; }>{}
, ::mrdocs::describe::detail::enum_descriptor<
ShapeKind::RoundedRect, []{ return "RoundedRect"; }>{}
, ::mrdocs::describe::detail::enum_descriptor<
ShapeKind::Triangle, []{ return "Triangle"; }>{}
// MRDOCS_DESCRIBE_ENUM_END(ShapeKind)
)) mrdocs_enum_descriptor_fn(ShapeKind**);
Here None isn't in the .inc file, so it isn't described: toString(ShapeKind::None) is empty, while toString(ShapeKind::RoundedRect) is "rounded-rect".
Things to keep in mind:
The macro opens a parenthesized expression that MRDOCS_DESCRIBE_ENUM_END closes, so everything in between must expand to nothing but MRDOCS_ENUM_ENTRY calls (and preprocessor directives). Each entry starts with its own comma, so don't add separators.
Pass the same enum type to both macros.
The placement rules of MRDOCS_DESCRIBE_ENUM apply: namespace scope, in the namespace of the enum, never inside a class.
Don't put a ; after either macro. After this one it's a syntax error, and MRDOCS_DESCRIBE_ENUM_END already ends with one.
Unlike MRDOCS_DESCRIBE_ENUM, there's no limit on the number of enumerators.
| Name | Description |
|---|---|
| E | The enum type. |