[#MRDOCS_CHECK_OR] = MRDOCS_CHECK_OR :mrdocs: Check a value and return early if it failed. == Synopsis Declared in `<mrdocs/Support/Error/Expected.hpp>` [source,cpp,subs="verbatim,replacements,macros,-callouts"] ---- #define MRDOCS_CHECK_OR(...) ---- == Description Use this in functions that don't return an xref:mrdocs/Expected.adoc[`mrdocs::Expected`]. If the value failed, the enclosing function returns the second argument, or just returns when there's no second argument. No error is produced. See `MRDOCS_TRY` for what counts as failed. The macro takes one or two arguments. The equivalent code below is simplified: `failed` is `::mrdocs::detail::failed`. The examples use this type: [,cpp] ---- struct Node { Node* parent = nullptr; std::string name; int n = 0; }; ---- With one argument, it does a plain `return;`, so it only works in a function that returns `void`: [,cpp] ---- void rename(Node* node, std::string name) { MRDOCS_CHECK_OR(node); node->name = std::move(name); } ---- is equivalent to: [,cpp] ---- void rename(Node* node, std::string name) { if (failed(node)) { // !node, since it's a pointer return; } node->name = std::move(name); } ---- With two arguments, it returns the second argument instead: [,cpp] ---- Node const* grandparent(Node const& node) { MRDOCS_CHECK_OR(node.parent, nullptr); return node.parent->parent; } ---- is equivalent to: [,cpp] ---- Node const* grandparent(Node const& node) { if (failed(node.parent)) { return nullptr; } return node.parent->parent; } ---- The second argument can be anything convertible to the function's return type, including a braced `{}` for a default value: [,cpp] ---- std::optional count(Node const* node) { MRDOCS_CHECK_OR(node, std::nullopt); MRDOCS_CHECK_OR(node->n > 0, {}); // returns an empty optional return node->n; } ---- The checked value is evaluated once, so a call expression is fine here. The return value is only evaluated when the check fails. Things to keep in mind: * Use it only inside a function body, and end it with a semicolon. * The one‐argument form only works in a function that returns `void`. The two‐argument form needs a value convertible to the function's return type. * The expansion is two statements. Put braces around it when it's the body of an `if`, `else`, or loop. * Wrap an argument in parentheses if it has a top‐level comma, such as `(std::pair<int, int>{})`. [.small]#Created with https://www.mrdocs.com[MrDocs]#