Check a value and return early if it failed.
Declared in <mrdocs/Support/Error/Expected.hpp>
#define MRDOCS_CHECK_OR(...)
Use this in functions that don't return an 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:
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:
void
rename(Node* node, std::string name)
{
MRDOCS_CHECK_OR(node);
node->name = std::move(name);
}
is equivalent to:
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:
Node const*
grandparent(Node const& node)
{
MRDOCS_CHECK_OR(node.parent, nullptr);
return node.parent->parent;
}
is equivalent to:
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:
std::optional<int>
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>{}).