Support references in ErrorOr (#4889)

### Context & Motivation

The error handling utilities in `//base/error.h` are very useful for
writing code with strong safety guarantees. While hardening the `Dump`
debug utilities (from review in #4866), I encountered a rough edge with
references and pointers. After a [brief Discord discussion in
#contributing-help](https://discord.com/channels/655572317891461132/1052653651895779359/1334675462877610038),
it was suggested that adding support for references to `ErrorOr` would
be a good candidate to move forward.

Using a reference type with the `ErrorOr` class (e.g. `ErrorOr<Node&>`)
produces two errors:

<ol>
<li><strong><code>variant can not have a reference type as an
alternative</code></strong>
<ul><li>From private field: <code>std::variant&lt;Error, T&gt;
val_;</code></li></ul>
</li>
<li><strong><code>'operator-&gt;' declared as a pointer to a
reference</code></strong>
<ul><li>From member function: <code>auto operator-&gt;() -&gt;
T*</code></li></ul>
</li>
</ol>

### Changes

To support reference types, both errors are resolved:

1. `std::reference_wrapper` is conditionally used for storage when `T`
is a reference type
2. type trait aliases like `using ValueT = std::remove_reference_t<T>`
are used to produce compatible types for methods like `auto operator->()
-> ValueT*`
This commit is contained in:
Calvin
2025-02-04 21:08:43 +00:00
committed by GitHub
parent 6803127ab0
commit dcfccd3187
2 changed files with 31 additions and 15 deletions
+6
View File
@@ -50,6 +50,12 @@ TEST(ErrorTest, ErrorOrArrowOp) {
EXPECT_EQ(err->val, 1);
}
TEST(ErrorTest, ErrorOrReference) {
Val val = {1};
ErrorOr<Val&> maybe_val(val);
EXPECT_EQ(maybe_val->val, 1);
}
auto IndirectErrorOrSuccessTest() -> ErrorOr<Success> { return Success(); }
TEST(ErrorTest, IndirectErrorOrSuccess) {