MRDOCS_DESCRIBE_KINDS_BEGIN
Open a kinds description driven by an X‐macro .inc file.
Description
When the derived kinds already live in an X‐macro .inc file (one INFO(Name) per kind, often the same file that builds the kind enum), this registers them without repeating the list in MRDOCS_DESCRIBE_KINDS. Point INFO at MRDOCS_KIND_ENTRY, then bracket the include with this macro and MRDOCS_DESCRIBE_KINDS_END. Given this ShapeNodes.inc:
#ifndef INFO
#define INFO(Name)
#endif
INFO(Circle)
INFO(Square)
#undef INFO
a header can build both the enum and the kind list from it:
namespace shapes {
enum class ShapeKind
{
#define INFO(Name) Name,
#include "ShapeNodes.inc"
};
struct Shape { ShapeKind Kind; };
struct CircleShape : Shape
{
static constexpr ShapeKind kind_id = ShapeKind::Circle;
CircleShape() : Shape{kind_id} {}
};
struct SquareShape : Shape
{
static constexpr ShapeKind kind_id = ShapeKind::Square;
SquareShape() : Shape{kind_id} {}
};
#define INFO(Name) MRDOCS_KIND_ENTRY(Shape, Name##Shape)
MRDOCS_DESCRIBE_KINDS_BEGIN(Shape)
#include "ShapeNodes.inc"
MRDOCS_DESCRIBE_KINDS_END(Shape)
} // namespace shapes
The entries can also be written by hand, and an empty pair registers a base with no kinds:
MRDOCS_DESCRIBE_KINDS_BEGIN(Node)
MRDOCS_KIND_ENTRY(Node, Leaf)
MRDOCS_KIND_ENTRY(Node, Branch)
MRDOCS_DESCRIBE_KINDS_END(Node)
MRDOCS_DESCRIBE_KINDS_BEGIN(Empty)
MRDOCS_DESCRIBE_KINDS_END(Empty)
After preprocessing, the Shape block becomes the following (simplified: the ::mrdocs::describe::detail:: qualification is dropped and the assertion message is shortened):
// MRDOCS_DESCRIBE_KINDS_BEGIN(Shape): leaves the call open
static_assert(std::is_class_v<Shape>, "...");
[[maybe_unused]]
inline decltype(kind_descriptor_fn_impl(0
// #include "ShapeNodes.inc": one MRDOCS_KIND_ENTRY per INFO line
, kind_descriptor<Shape, CircleShape>{} // INFO(Circle)
, kind_descriptor<Shape, SquareShape>{} // INFO(Square)
// MRDOCS_DESCRIBE_KINDS_END(Shape): closes the call
)) mrdocs_kind_descriptor_fn(Shape**) { return {}; }
That's the same declaration MRDOCS_DESCRIBE_KINDS(Shape, CircleShape, SquareShape) produces, so the same queries (describe::describe_kinds, describe::has_describe_kinds, mrdocs::visit) work afterwards.
Things to keep in mind:
-
This macro leaves a call open, so only
MRDOCS_KIND_ENTRYexpansions and preprocessor directives may come before the matchingMRDOCS_DESCRIBE_KINDS_END. Anything else, including a stray;, is a syntax error. -
Pass the same base to this macro, to every entry, and to
MRDOCS_DESCRIBE_KINDS_END. -
Place the block at namespace scope, in the namespace of the base.
-
Define
INFObefore the include. The.incfile is expected to#undefit at the end; if yours doesn't, add the#undefyourself.
Parameters
Name |
Description |
C |
The polymorphic base class. |
Created with MrDocs