MRDOCS_DESCRIBE_ENUM_UNDEFINED
Mark one enumerator as the enum's undefined (empty) state.
Description
Some enums have a value that means "not set", like None. Marking it makes the string helpers treat it as empty, and makes generators treat a field holding it as absent (an empty optional) instead of printing it. Place it at namespace scope, in the namespace of the enum, after the enum's MRDOCS_DESCRIBE_ENUM:
namespace shapes {
enum class Fill { None, Solid, Hatched };
MRDOCS_DESCRIBE_ENUM(Fill, None, Solid, Hatched)
MRDOCS_DESCRIBE_ENUM_UNDEFINED(Fill, None)
} // namespace shapes
It expands to a small function that ADL finds from the enum type:
// MRDOCS_DESCRIBE_ENUM_UNDEFINED(Fill, None)
[[maybe_unused]]
inline constexpr Fill
mrdocs_undefined_descriptor_fn(Fill**) noexcept { return Fill::None; }
Afterwards:
namespace describe = mrdocs::describe;
using shapes::Fill;
static_assert(describe::has_undefined_enumerator<Fill>);
static_assert(describe::undefined_enumerator<Fill> == Fill::None);
// The undefined state renders as the empty string
static_assert(mrdocs::toString(Fill::None).empty());
static_assert(describe::enum_to_string(Fill::None).empty());
static_assert(mrdocs::toString(Fill::Solid) == "solid");
void
demo()
{
// and the empty string parses back to it
Fill f = Fill::Solid;
describe::enum_from_string("", f); // returns true, f == Fill::None
}
Things to keep in mind:
-
Use it at most once per enum; a second use is a redefinition error.
-
Like
MRDOCS_DESCRIBE_ENUM, it must be in the namespace of the enum and not inside a class, or lookup won't find it. -
The function is
inline, so it's safe in headers. -
It ends with a closing brace, so don't add a semicolon.
Parameters
Name |
Description |
E |
The enum type. |
U |
The enumerator that represents the undefined state, written without the |
Created with MrDocs