• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_TYPES_EXPECTED_H_
6 #define BASE_TYPES_EXPECTED_H_
7 
8 #include <concepts>
9 #include <type_traits>
10 #include <utility>
11 
12 #include "base/check.h"
13 #include "base/strings/strcat.h"
14 #include "base/strings/to_string.h"
15 #include "base/types/expected_internal.h"  // IWYU pragma: export
16 #include "third_party/abseil-cpp/absl/utility/utility.h"
17 
18 // Class template `expected<T, E>` is a vocabulary type which contains an
19 // expected value of type `T`, or an error `E`. The class skews towards behaving
20 // like a `T`, because its intended use is when the expected type is contained.
21 // When something unexpected occurs, more typing is required. When all is good,
22 // code mostly looks as if a `T` were being handled.
23 //
24 // Class template `expected<T, E>` contains either:
25 // * A value of type `T`, the expected value type; or
26 // * A value of type `E`, an error type used when an unexpected outcome
27 // occurred.
28 //
29 // The interface can be queried as to whether the underlying value is the
30 // expected value (of type `T`) or an unexpected value (of type `E`). The
31 // interface and the rational are based on `std::optional`. We consider
32 // `expected<T, E>` as a supplement to `optional<T>`, expressing why an expected
33 // value isn’t contained in the object.
34 //
35 // Example Usage:
36 //
37 // Before:
38 //   bool ParseInt32(base::StringPiece input,
39 //                   int32_t* output,
40 //                   ParseIntError* error);
41 //   ...
42 //
43 //   int32_t output;
44 //   ParseIntError error;
45 //   if (ParseInt32("...". &output, &error)) {
46 //     // process `output`
47 //   } else {
48 //     // process `error`
49 //   }
50 //
51 // After:
52 //
53 //   base::expected<int32_t, ParseIntError> ParseInt32(base::StringPiece input);
54 //   ...
55 //
56 //   if (auto parsed = ParseInt32("..."); parsed.has_value()) {
57 //     // process `parsed.value()`
58 //   } else {
59 //     // process `parsed.error()`
60 //   }
61 //
62 // For even less boilerplate, see expected_macros.h.
63 //
64 // Note that there are various transformation member functions. To avoid having
65 // to puzzle through the standard-ese on their documentation, here's a quick
66 // reference table, assuming a source `expected<T, E> ex;` and types U and G
67 // convertible from T and E, respectively:
68 //
69 //                        Return type     Val when ex = t  Val when ex = e
70 //                        -----------     ---------------  ---------------
71 // ex.value_or(t2)        T               t                t2
72 // ex.and_then(f)         expected<U, E>  f(t)             unexpected(e)
73 // ex.transform(f)        expected<U, E>  expected(f(t))   unexpected(e)
74 // ex.or_else(f)          expected<T, G>  expected(t)      f(e)
75 // ex.transform_error(f)  expected<T, G>  expected(t)      unexpected(f(e))
76 //
77 // References:
78 // * https://wg21.link/P0323
79 // * https://eel.is/c++draft/expected
80 namespace base {
81 
82 // Note: base::unexpected and base::expected are C++17 compatible backports of
83 // C++23's std::unexpected and std::expected. They differ from the standard in
84 // the following ways:
85 //
86 // * Not all member functions can be used in a constexpr context. This is due to
87 //   limitations in both the C++17 language and the Abseil library used for the
88 //   implementation.
89 // * Since Chromium does not support exceptions, there is no bad_expected_access
90 //   exception and the program will just terminate when the exception would have
91 //   been thrown. Furthermore, all member functions are marked noexcept.
92 // * C++23 allows an implicit conversion from U to expected<T, E> if U is
93 //   implicitly convertible to T; the Chromium version only allows an implicit
94 //   conversion if U is implicitly convertible to T *and* U is *not* implicitly
95 //   convertible to E, to guard against bug-prone patterns such as:
96 //     // creates an expected value containing true, not an unexpected value
97 //     // containing 123L.
98 //     expected<bool, long> e = 123L;
99 // * Because of the above restriction, the Chromium version also introduces
100 //   `base::ok` as a complement to `base::unexpected` to simplify returning
101 //   success values when the implicit conversion above is disallowed.
102 // * Calling operator* or operator-> on an unexpected value results in program
103 //   termination, and not UB.
104 // * There is no operator bool due to bug-prone usage when the value type is
105 //   convertible to bool, see e.g. https://abseil.io/tips/141.
106 // * Moving out of an expected object will put it into a moved-from state.
107 //   Trying to use it before re-initializing it will result in program
108 //   termination.
109 // * The expected<void> specialization is done via a defaulted boolean template
110 //   parameter, due to the lack of requires clauses in C++17.
111 // * Since equality operators can not be defaulted in C++17, equality and
112 //   inequality operators are specified explicitly.
113 // * base::expected implements the monadic interface proposal
114 //   (https://wg21.link/P2505), which is currently only on track for C++26.
115 
116 // Class template used as a type hint for constructing a `base::expected`
117 // containing a value (i.e. success). Useful when implicit conversion
118 // construction of `base::expected` is disallowed, e.g. due to ambiguity.
119 // Example usage:
120 //
121 //   base::expected<std::string, std::string> RunOp() {
122 //     std::string error;
123 //     std::string result = RunOpImpl(..., &error);
124 //     if (!error.empty()) {
125 //       return base::unexpected(std::move(error));
126 //
127 //     // The C++23 std::expected proposal allows this to be simply written as
128 //     //   return result;
129 //     //
130 //     // However, the Chromium version disallows this if E implicitly converts
131 //     // to T, so without base::ok(), this would have to be written as:
132 //     //   return base::expected<std::string, std::string>(std::move(result));
133 //
134 //     return base::ok(std::move(result));
135 //   }
136 template <typename T>
137 class ok final {
138  public:
139   template <typename U = T>
requires(internal::IsOkValueConstruction<T,U>)140     requires(internal::IsOkValueConstruction<T, U>)
141   constexpr explicit ok(U&& val) noexcept : value_(std::forward<U>(val)) {}
142 
143   template <typename... Args>
ok(absl::in_place_t,Args &&...args)144   constexpr explicit ok(absl::in_place_t, Args&&... args) noexcept
145       : value_(std::forward<Args>(args)...) {}
146 
147   template <typename U, typename... Args>
ok(absl::in_place_t,std::initializer_list<U> il,Args &&...args)148   constexpr explicit ok(absl::in_place_t,
149                         std::initializer_list<U> il,
150                         Args&&... args) noexcept
151       : value_(il, std::forward<Args>(args)...) {}
152 
value()153   constexpr T& value() & noexcept { return value_; }
value()154   constexpr const T& value() const& noexcept { return value_; }
value()155   constexpr T&& value() && noexcept { return std::move(value()); }
value()156   constexpr const T&& value() const&& noexcept { return std::move(value()); }
157 
swap(ok & other)158   constexpr void swap(ok& other) noexcept {
159     using std::swap;
160     swap(value(), other.value());
161   }
162 
swap(ok & x,ok & y)163   friend constexpr void swap(ok& x, ok& y) noexcept { x.swap(y); }
164 
ToString()165   std::string ToString() const {
166     return StrCat({"ok(", base::ToString(value()), ")"});
167   }
168 
169  private:
170   T value_;
171 };
172 
173 template <typename T>
requires(std::is_void_v<T>)174   requires(std::is_void_v<T>)
175 class ok<T> final {
176  public:
177   constexpr explicit ok() noexcept = default;
178 
179   std::string ToString() const { return "ok()"; }
180 };
181 
182 template <typename T, typename U>
183 constexpr bool operator==(const ok<T>& lhs, const ok<U>& rhs) noexcept {
184   if constexpr (std::is_void_v<T> && std::is_void_v<U>) {
185     return true;
186   } else if constexpr (std::is_void_v<T> || std::is_void_v<U>) {
187     return false;
188   } else {
189     return lhs.value() == rhs.value();
190   }
191 }
192 
193 template <typename T, typename U>
194 constexpr bool operator!=(const ok<T>& lhs, const ok<U>& rhs) noexcept {
195   return !(lhs == rhs);
196 }
197 
198 template <typename T>
199 ok(T) -> ok<T>;
200 
201 ok()->ok<void>;
202 
203 // [expected.un.object], class template unexpected
204 // https://eel.is/c++draft/expected#un.object
205 template <typename E>
206 class unexpected final {
207  public:
208   // [expected.un.ctor] Constructors
209   template <typename Err = E>
requires(internal::IsUnexpectedValueConstruction<E,Err>)210     requires(internal::IsUnexpectedValueConstruction<E, Err>)
211   constexpr explicit unexpected(Err&& err) noexcept
212       : error_(std::forward<Err>(err)) {}
213 
214   template <typename... Args>
unexpected(absl::in_place_t,Args &&...args)215   constexpr explicit unexpected(absl::in_place_t, Args&&... args) noexcept
216       : error_(std::forward<Args>(args)...) {}
217 
218   template <typename U, typename... Args>
unexpected(absl::in_place_t,std::initializer_list<U> il,Args &&...args)219   constexpr explicit unexpected(absl::in_place_t,
220                                 std::initializer_list<U> il,
221                                 Args&&... args) noexcept
222       : error_(il, std::forward<Args>(args)...) {}
223 
224   // [expected.un.obs] Observers
error()225   constexpr E& error() & noexcept { return error_; }
error()226   constexpr const E& error() const& noexcept { return error_; }
error()227   constexpr E&& error() && noexcept { return std::move(error()); }
error()228   constexpr const E&& error() const&& noexcept { return std::move(error()); }
229 
230   // [expected.un.swap] Swap
swap(unexpected & other)231   constexpr void swap(unexpected& other) noexcept {
232     using std::swap;
233     swap(error(), other.error());
234   }
235 
swap(unexpected & x,unexpected & y)236   friend constexpr void swap(unexpected& x, unexpected& y) noexcept {
237     x.swap(y);
238   }
239 
240   // Deviation from the Standard: stringification support.
241   //
242   // If we move to `std::unexpected` someday, we would need to either forego
243   // nice formatted output or move to `std::format` or similar, which can have
244   // customized output for STL types.
ToString()245   std::string ToString() const noexcept {
246     return StrCat({"Unexpected(", base::ToString(error()), ")"});
247   }
248 
249  private:
250   E error_;
251 };
252 
253 // [expected.un.eq] Equality operator
254 template <typename E, typename G>
255 constexpr bool operator==(const unexpected<E>& lhs,
256                           const unexpected<G>& rhs) noexcept {
257   return lhs.error() == rhs.error();
258 }
259 
260 template <typename E, typename G>
261 constexpr bool operator!=(const unexpected<E>& lhs,
262                           const unexpected<G>& rhs) noexcept {
263   return !(lhs == rhs);
264 }
265 
266 template <typename E>
267 unexpected(E) -> unexpected<E>;
268 
269 // [expected.expected], class template expected
270 // https://eel.is/c++draft/expected#expected
271 template <typename T, typename E>
272 class [[nodiscard]] expected final {
273   // Note: A partial specialization for void value types follows below.
274   static_assert(!std::is_void_v<T>, "Error: T must not be void");
275 
276  public:
277   using value_type = T;
278   using error_type = E;
279   using unexpected_type = unexpected<E>;
280 
281   // Alias template to explicitly opt into the std::pointer_traits machinery.
282   // See e.g. https://en.cppreference.com/w/cpp/memory/pointer_traits#Notes
283   template <typename U>
284   using rebind = expected<U, E>;
285 
286   template <typename U, typename G>
287   friend class expected;
288 
289   // [expected.object.ctor], constructors
290   constexpr expected() noexcept = default;
291 
292   // Converting copy and move constructors. These constructors are explicit if
293   // either the value or error type is not implicitly convertible from `rhs`'s
294   // corresponding type.
295   template <typename U, typename G>
requires(internal::IsValidConversion<T,E,const U &,const G &>)296     requires(internal::IsValidConversion<T, E, const U&, const G&>)
297   explicit(!std::convertible_to<const U&, T> ||
298            !std::convertible_to<const G&, E>)
299       // NOLINTNEXTLINE(google-explicit-constructor)
300       constexpr expected(const expected<U, G>& rhs) noexcept
301       : impl_(rhs.impl_) {}
302 
303   template <typename U, typename G>
requires(internal::IsValidConversion<T,E,U,G>)304     requires(internal::IsValidConversion<T, E, U, G>)
305   explicit(!std::convertible_to<U, T> || !std::convertible_to<G, E>)
306       // NOLINTNEXTLINE(google-explicit-constructor)
307       constexpr expected(expected<U, G>&& rhs) noexcept
308       : impl_(std::move(rhs.impl_)) {}
309 
310   // Deviation from the Standard, which allows implicit conversions as long as U
311   // is implicitly convertible to T: Chromium additionally requires that U is
312   // not implicitly convertible to E.
313   template <typename U = T>
requires(internal::IsValidValueConstruction<T,E,U>)314     requires(internal::IsValidValueConstruction<T, E, U>)
315   explicit(!std::convertible_to<U, T> || std::convertible_to<U, E>)
316       // NOLINTNEXTLINE(google-explicit-constructor)
317       constexpr expected(U&& v) noexcept
318       : impl_(kValTag, std::forward<U>(v)) {}
319 
320   template <typename U>
requires(std::constructible_from<T,const U &>)321     requires(std::constructible_from<T, const U&>)
322   explicit(!std::convertible_to<const U&, T>)
323       // NOLINTNEXTLINE(google-explicit-constructor)
324       constexpr expected(const ok<U>& o) noexcept
325       : impl_(kValTag, o.value()) {}
326 
327   template <typename U>
requires(std::constructible_from<T,U>)328     requires(std::constructible_from<T, U>)
329   explicit(!std::convertible_to<U, T>)
330       // NOLINTNEXTLINE(google-explicit-constructor)
331       constexpr expected(ok<U>&& o) noexcept
332       : impl_(kValTag, std::move(o.value())) {}
333 
334   template <typename G>
requires(std::constructible_from<E,const G &>)335     requires(std::constructible_from<E, const G&>)
336   explicit(!std::convertible_to<const G&, E>)
337       // NOLINTNEXTLINE(google-explicit-constructor)
338       constexpr expected(const unexpected<G>& e) noexcept
339       : impl_(kErrTag, e.error()) {}
340 
341   template <typename G>
requires(std::constructible_from<E,G>)342     requires(std::constructible_from<E, G>)
343   explicit(!std::convertible_to<G, E>)
344       // NOLINTNEXTLINE(google-explicit-constructor)
345       constexpr expected(unexpected<G>&& e) noexcept
346       : impl_(kErrTag, std::move(e.error())) {}
347 
348   template <typename... Args>
expected(absl::in_place_t,Args &&...args)349   constexpr explicit expected(absl::in_place_t, Args&&... args) noexcept
350       : impl_(kValTag, std::forward<Args>(args)...) {}
351 
352   template <typename U, typename... Args>
expected(absl::in_place_t,std::initializer_list<U> il,Args &&...args)353   constexpr explicit expected(absl::in_place_t,
354                               std::initializer_list<U> il,
355                               Args&&... args) noexcept
356       : impl_(kValTag, il, std::forward<Args>(args)...) {}
357 
358   template <typename... Args>
expected(unexpect_t,Args &&...args)359   constexpr explicit expected(unexpect_t, Args&&... args) noexcept
360       : impl_(kErrTag, std::forward<Args>(args)...) {}
361 
362   template <typename U, typename... Args>
expected(unexpect_t,std::initializer_list<U> il,Args &&...args)363   constexpr explicit expected(unexpect_t,
364                               std::initializer_list<U> il,
365                               Args&&... args) noexcept
366       : impl_(kErrTag, il, std::forward<Args>(args)...) {}
367 
368   // [expected.object.assign], assignment
369   template <typename U = T>
requires(internal::IsValueAssignment<T,E,U>)370     requires(internal::IsValueAssignment<T, E, U>)
371   constexpr expected& operator=(U&& v) noexcept {
372     emplace(std::forward<U>(v));
373     return *this;
374   }
375 
376   template <typename U>
377   constexpr expected& operator=(const ok<U>& o) noexcept {
378     emplace(o.value());
379     return *this;
380   }
381 
382   template <typename U>
383   constexpr expected& operator=(ok<U>&& o) noexcept {
384     emplace(std::move(o.value()));
385     return *this;
386   }
387 
388   template <typename G>
389   constexpr expected& operator=(const unexpected<G>& e) noexcept {
390     impl_.emplace_error(e.error());
391     return *this;
392   }
393 
394   template <typename G>
395   constexpr expected& operator=(unexpected<G>&& e) noexcept {
396     impl_.emplace_error(std::move(e.error()));
397     return *this;
398   }
399 
400   template <typename... Args>
emplace(Args &&...args)401   constexpr T& emplace(Args&&... args) noexcept {
402     return impl_.emplace_value(std::forward<Args>(args)...);
403   }
404 
405   template <typename U, typename... Args>
emplace(std::initializer_list<U> il,Args &&...args)406   constexpr T& emplace(std::initializer_list<U> il, Args&&... args) noexcept {
407     return impl_.emplace_value(il, std::forward<Args>(args)...);
408   }
409 
410   // [expected.object.swap], swap
swap(expected & rhs)411   constexpr void swap(expected& rhs) noexcept { impl_.swap(rhs.impl_); }
swap(expected & x,expected & y)412   friend constexpr void swap(expected& x, expected& y) noexcept { x.swap(y); }
413 
414   // [expected.object.obs], observers
415   constexpr T* operator->() noexcept { return std::addressof(value()); }
416   constexpr const T* operator->() const noexcept {
417     return std::addressof(value());
418   }
419 
420   constexpr T& operator*() & noexcept { return value(); }
421   constexpr const T& operator*() const& noexcept { return value(); }
422   constexpr T&& operator*() && noexcept { return std::move(value()); }
423   constexpr const T&& operator*() const&& noexcept {
424     return std::move(value());
425   }
426 
427   // Note: Deviation from the Standard: No operator bool due to bug-prone
428   // patterns when the value type is convertible to bool, see e.g.
429   // https://abseil.io/tips/141.
has_value()430   constexpr bool has_value() const noexcept { return impl_.has_value(); }
431 
value()432   constexpr T& value() & noexcept { return impl_.value(); }
value()433   constexpr const T& value() const& noexcept { return impl_.value(); }
value()434   constexpr T&& value() && noexcept { return std::move(value()); }
value()435   constexpr const T&& value() const&& noexcept { return std::move(value()); }
436 
error()437   constexpr E& error() & noexcept { return impl_.error(); }
error()438   constexpr const E& error() const& noexcept { return impl_.error(); }
error()439   constexpr E&& error() && noexcept { return std::move(error()); }
error()440   constexpr const E&& error() const&& noexcept { return std::move(error()); }
441 
442   template <typename U>
value_or(U && v)443   constexpr T value_or(U&& v) const& noexcept {
444     static_assert(std::copy_constructible<T>,
445                   "expected<T, E>::value_or: T must be copy constructible");
446     static_assert(std::convertible_to<U&&, T>,
447                   "expected<T, E>::value_or: U must be convertible to T");
448     return has_value() ? value() : static_cast<T>(std::forward<U>(v));
449   }
450 
451   template <typename U>
value_or(U && v)452   constexpr T value_or(U&& v) && noexcept {
453     static_assert(std::move_constructible<T>,
454                   "expected<T, E>::value_or: T must be move constructible");
455     static_assert(std::convertible_to<U&&, T>,
456                   "expected<T, E>::value_or: U must be convertible to T");
457     return has_value() ? std::move(value())
458                        : static_cast<T>(std::forward<U>(v));
459   }
460 
461   template <typename G>
error_or(G && e)462   constexpr E error_or(G&& e) const& noexcept {
463     static_assert(std::copy_constructible<E>,
464                   "expected<T, E>::error_or: E must be copy constructible");
465     static_assert(std::convertible_to<G&&, E>,
466                   "expected<T, E>::error_or: G must be convertible to E");
467     return has_value() ? static_cast<E>(std::forward<G>(e)) : error();
468   }
469 
470   template <typename G>
error_or(G && e)471   constexpr E error_or(G&& e) && noexcept {
472     static_assert(std::move_constructible<E>,
473                   "expected<T, E>::error_or: E must be move constructible");
474     static_assert(std::convertible_to<G&&, E>,
475                   "expected<T, E>::error_or: G must be convertible to E");
476     return has_value() ? static_cast<E>(std::forward<G>(e))
477                        : std::move(error());
478   }
479 
480   // [expected.object.monadic], monadic operations
481   //
482   // This section implements the monadic interface consisting of `and_then`,
483   // `or_else`, `transform` and `transform_error`.
484 
485   // `and_then`: This methods accepts a callable `f` that is invoked with
486   // `value()` in case `has_value()` is true.
487   //
488   // `f`'s return type is required to be a (cvref-qualified) specialization of
489   // base::expected with a matching error_type, i.e. it needs to be of the form
490   // base::expected<U, E> cv ref for some U.
491   //
492   // If `has_value()` is false, this is effectively a no-op, and the function
493   // returns base::expected<U, E>(unexpect, std::forward<E>(error()));
494   //
495   // `and_then` is overloaded for all possible forms of const and ref
496   // qualifiers.
497   template <typename F>
requires(std::copy_constructible<E>)498     requires(std::copy_constructible<E>)
499   constexpr auto and_then(F&& f) & noexcept {
500     return internal::AndThen(*this, std::forward<F>(f));
501   }
502 
503   template <typename F>
requires(std::copy_constructible<E>)504     requires(std::copy_constructible<E>)
505   constexpr auto and_then(F&& f) const& noexcept {
506     return internal::AndThen(*this, std::forward<F>(f));
507   }
508 
509   template <typename F>
requires(std::move_constructible<E>)510     requires(std::move_constructible<E>)
511   constexpr auto and_then(F&& f) && noexcept {
512     return internal::AndThen(std::move(*this), std::forward<F>(f));
513   }
514 
515   template <typename F>
requires(std::move_constructible<E>)516     requires(std::move_constructible<E>)
517   constexpr auto and_then(F&& f) const&& noexcept {
518     return internal::AndThen(std::move(*this), std::forward<F>(f));
519   }
520 
521   // `or_else`: This methods accepts a callable `f` that is invoked with
522   // `error()` in case `has_value()` is false.
523   //
524   // `f`'s return type is required to be a (cvref-qualified) specialization of
525   // base::expected with a matching value_type, i.e. it needs to be of the form
526   // base::expected<T, G> cv ref for some G.
527   //
528   // If `has_value()` is true, this is effectively a no-op, and the function
529   // returns base::expected<T, G>(std::forward<T>(value()));
530   //
531   // `or_else` is overloaded for all possible forms of const and ref
532   // qualifiers.
533   template <typename F>
requires(std::copy_constructible<T>)534     requires(std::copy_constructible<T>)
535   constexpr auto or_else(F&& f) & noexcept {
536     return internal::OrElse(*this, std::forward<F>(f));
537   }
538 
539   template <typename F>
requires(std::copy_constructible<T>)540     requires(std::copy_constructible<T>)
541   constexpr auto or_else(F&& f) const& noexcept {
542     return internal::OrElse(*this, std::forward<F>(f));
543   }
544 
545   template <typename F>
requires(std::move_constructible<T>)546     requires(std::move_constructible<T>)
547   constexpr auto or_else(F&& f) && noexcept {
548     return internal::OrElse(std::move(*this), std::forward<F>(f));
549   }
550 
551   template <typename F>
requires(std::move_constructible<T>)552     requires(std::move_constructible<T>)
553   constexpr auto or_else(F&& f) const&& noexcept {
554     return internal::OrElse(std::move(*this), std::forward<F>(f));
555   }
556 
557   // `transform`: This methods accepts a callable `f` that is invoked with
558   // `value()` in case `has_value()` is true.
559   //
560   // `f`'s return type U needs to be a valid value_type for expected, i.e. any
561   // type for which `remove_cv_t` is either void, or a complete non-array object
562   // type that is not `absl::in_place_t`, `base::unexpect_t`, or a
563   // specialization of `base::ok` or `base::unexpected`.
564   //
565   // Returns an instance of base::expected<remove_cv_t<U>, E> that is
566   // constructed with f(value()) if there is a value, or unexpected(error())
567   // otherwise.
568   //
569   // `transform` is overloaded for all possible forms of const and ref
570   // qualifiers.
571   template <typename F>
requires(std::copy_constructible<E>)572     requires(std::copy_constructible<E>)
573   constexpr auto transform(F&& f) & noexcept {
574     return internal::Transform(*this, std::forward<F>(f));
575   }
576 
577   template <typename F>
requires(std::copy_constructible<E>)578     requires(std::copy_constructible<E>)
579   constexpr auto transform(F&& f) const& noexcept {
580     return internal::Transform(*this, std::forward<F>(f));
581   }
582 
583   template <typename F>
requires(std::move_constructible<E>)584     requires(std::move_constructible<E>)
585   constexpr auto transform(F&& f) && noexcept {
586     return internal::Transform(std::move(*this), std::forward<F>(f));
587   }
588 
589   template <typename F>
requires(std::move_constructible<E>)590     requires(std::move_constructible<E>)
591   constexpr auto transform(F&& f) const&& noexcept {
592     return internal::Transform(std::move(*this), std::forward<F>(f));
593   }
594 
595   // `transform_error`: This methods accepts a callable `f` that is invoked with
596   // `error()` in case `has_value()` is false.
597   //
598   // `f`'s return type G needs to be a valid error_type for expected, i.e. any
599   // type for which `remove_cv_t` is a complete non-array object type that is
600   // not `absl::in_place_t`, `base::unexpect_t`, or a specialization of
601   // `base::ok` or `base::unexpected`.
602   //
603   // Returns an instance of base::expected<T, remove_cv_t<G>> that is
604   // constructed with unexpected(f(error())) if there is no value, or value()
605   // otherwise.
606   //
607   // `transform_error` is overloaded for all possible forms of const and ref
608   // qualifiers.
609   template <typename F>
requires(std::copy_constructible<T>)610     requires(std::copy_constructible<T>)
611   constexpr auto transform_error(F&& f) & noexcept {
612     return internal::TransformError(*this, std::forward<F>(f));
613   }
614 
615   template <typename F>
requires(std::copy_constructible<T>)616     requires(std::copy_constructible<T>)
617   constexpr auto transform_error(F&& f) const& noexcept {
618     return internal::TransformError(*this, std::forward<F>(f));
619   }
620 
621   template <typename F>
requires(std::move_constructible<T>)622     requires(std::move_constructible<T>)
623   constexpr auto transform_error(F&& f) && noexcept {
624     return internal::TransformError(std::move(*this), std::forward<F>(f));
625   }
626 
627   template <typename F>
requires(std::move_constructible<T>)628     requires(std::move_constructible<T>)
629   constexpr auto transform_error(F&& f) const&& noexcept {
630     return internal::TransformError(std::move(*this), std::forward<F>(f));
631   }
632 
633   // Deviation from the Standard: stringification support.
634   //
635   // If we move to `std::expected` someday, we would need to either forego nice
636   // formatted output or move to `std::format` or similar, which can have
637   // customized output for STL types.
ToString()638   std::string ToString() const {
639     return has_value() ? StrCat({"Expected(", base::ToString(value()), ")"})
640                        : StrCat({"Unexpected(", base::ToString(error()), ")"});
641   }
642 
643  private:
644   using Impl = internal::ExpectedImpl<T, E>;
645   static constexpr auto kValTag = Impl::kValTag;
646   static constexpr auto kErrTag = Impl::kErrTag;
647 
648   Impl impl_;
649 };
650 
651 // [expected.void], partial specialization of expected for void types
652 template <typename T, typename E>
requires(std::is_void_v<T>)653   requires(std::is_void_v<T>)
654 class [[nodiscard]] expected<T, E> final {
655   // Note: A partial specialization for non-void value types can be found above.
656   static_assert(std::is_void_v<T>, "Error: T must be void");
657 
658  public:
659   using value_type = T;
660   using error_type = E;
661   using unexpected_type = unexpected<E>;
662 
663   // Alias template to explicitly opt into the std::pointer_traits machinery.
664   // See e.g. https://en.cppreference.com/w/cpp/memory/pointer_traits#Notes
665   template <typename U>
666   using rebind = expected<U, E>;
667 
668   template <typename U, typename G>
669   friend class expected;
670 
671   // [expected.void.ctor], constructors
672   constexpr expected() noexcept = default;
673 
674   // Converting copy and move constructors. These constructors are explicit if
675   // the error type is not implicitly convertible from `rhs`'s error type.
676   template <typename U, typename G>
677     requires(internal::IsValidVoidConversion<E, U, const G&>)
678   explicit(!std::convertible_to<const G&, E>)
679       // NOLINTNEXTLINE(google-explicit-constructor)
680       constexpr expected(const expected<U, G>& rhs) noexcept
681       : impl_(rhs.impl_) {}
682 
683   template <typename U, typename G>
684     requires(internal::IsValidVoidConversion<E, U, G>)
685   explicit(!std::convertible_to<G, E>)
686       // NOLINTNEXTLINE(google-explicit-constructor)
687       constexpr expected(expected<U, G>&& rhs) noexcept
688       : impl_(std::move(rhs.impl_)) {}
689 
690   // NOLINTNEXTLINE(google-explicit-constructor)
691   constexpr /* implicit */ expected(base::ok<T>) noexcept {}
692 
693   template <typename G>
694     requires(std::constructible_from<E, const G&>)
695   explicit(!std::convertible_to<const G&, E>)
696       // NOLINTNEXTLINE(google-explicit-constructor)
697       constexpr expected(const unexpected<G>& e) noexcept
698       : impl_(kErrTag, e.error()) {}
699 
700   template <typename G>
701     requires(std::constructible_from<E, G>)
702   explicit(!std::convertible_to<G, E>)
703       // NOLINTNEXTLINE(google-explicit-constructor)
704       constexpr expected(unexpected<G>&& e) noexcept
705       : impl_(kErrTag, std::move(e.error())) {}
706 
707   constexpr explicit expected(absl::in_place_t) noexcept {}
708 
709   template <typename... Args>
710   constexpr explicit expected(unexpect_t, Args&&... args) noexcept
711       : impl_(kErrTag, std::forward<Args>(args)...) {}
712 
713   template <typename U, typename... Args>
714   constexpr explicit expected(unexpect_t,
715                               std::initializer_list<U> il,
716                               Args&&... args) noexcept
717       : impl_(kErrTag, il, std::forward<Args>(args)...) {}
718 
719   // [expected.void.assign], assignment
720   template <typename G>
721   constexpr expected& operator=(const unexpected<G>& e) noexcept {
722     impl_.emplace_error(e.error());
723     return *this;
724   }
725 
726   template <typename G>
727   constexpr expected& operator=(unexpected<G>&& e) noexcept {
728     impl_.emplace_error(std::move(e.error()));
729     return *this;
730   }
731 
732   constexpr void emplace() noexcept { impl_.emplace_value(); }
733 
734   // [expected.void.swap], swap
735   constexpr void swap(expected& rhs) noexcept { impl_.swap(rhs.impl_); }
736   friend constexpr void swap(expected& x, expected& y) noexcept { x.swap(y); }
737 
738   // [expected.void.obs], observers
739   // Note: Deviation from the Standard: No operator bool due to consistency with
740   // non-void expected types.
741   constexpr bool has_value() const noexcept { return impl_.has_value(); }
742 
743   constexpr void operator*() const { CHECK(has_value()); }
744   constexpr void value() const { CHECK(has_value()); }
745 
746   constexpr E& error() & { return impl_.error(); }
747   constexpr const E& error() const& { return impl_.error(); }
748   constexpr E&& error() && { return std::move(error()); }
749   constexpr const E&& error() const&& { return std::move(error()); }
750 
751   template <typename G>
752   constexpr E error_or(G&& e) const& noexcept {
753     static_assert(std::copy_constructible<E>,
754                   "expected<T, E>::error_or: E must be copy constructible");
755     static_assert(std::convertible_to<G&&, E>,
756                   "expected<T, E>::error_or: G must be convertible to E");
757     return has_value() ? static_cast<E>(std::forward<G>(e)) : error();
758   }
759 
760   template <typename G>
761   constexpr E error_or(G&& e) && noexcept {
762     static_assert(std::move_constructible<E>,
763                   "expected<T, E>::error_or: E must be move constructible");
764     static_assert(std::convertible_to<G&&, E>,
765                   "expected<T, E>::error_or: G must be convertible to E");
766     return has_value() ? static_cast<E>(std::forward<G>(e))
767                        : std::move(error());
768   }
769 
770   // [expected.void.monadic], monadic operations
771   //
772   // This section implements the monadic interface consisting of `and_then`,
773   // `or_else`, `transform` and `transform_error`. In contrast to the non void
774   // specialization it is mandated that the callables for `and_then` and
775   // `transform`don't take any arguments.
776 
777   // `and_then`: This methods accepts a callable `f` that is invoked with
778   // no arguments in case `has_value()` is true.
779   //
780   // `f`'s return type is required to be a (cvref-qualified) specialization of
781   // base::expected with a matching error_type, i.e. it needs to be of the form
782   // base::expected<U, E> cv ref for some U.
783   //
784   // If `has_value()` is false, this is effectively a no-op, and the function
785   // returns base::expected<U, E>(unexpect, std::forward<E>(error()));
786   //
787   // `and_then` is overloaded for all possible forms of const and ref
788   // qualifiers.
789   template <typename F>
790     requires(std::copy_constructible<E>)
791   constexpr auto and_then(F&& f) & noexcept {
792     return internal::AndThen(*this, std::forward<F>(f));
793   }
794 
795   template <typename F>
796     requires(std::copy_constructible<E>)
797   constexpr auto and_then(F&& f) const& noexcept {
798     return internal::AndThen(*this, std::forward<F>(f));
799   }
800 
801   template <typename F>
802     requires(std::move_constructible<E>)
803   constexpr auto and_then(F&& f) && noexcept {
804     return internal::AndThen(std::move(*this), std::forward<F>(f));
805   }
806 
807   template <typename F>
808     requires(std::move_constructible<E>)
809   constexpr auto and_then(F&& f) const&& noexcept {
810     return internal::AndThen(std::move(*this), std::forward<F>(f));
811   }
812 
813   // `or_else`: This methods accepts a callable `f` that is invoked with
814   // `error()` in case `has_value()` is false.
815   //
816   // `f`'s return type is required to be a (cvref-qualified) specialization of
817   // base::expected with a matching value_type, i.e. it needs to be cv void.
818   //
819   // If `has_value()` is true, this is effectively a no-op, and the function
820   // returns base::expected<cv void, G>().
821   //
822   // `or_else` is overloaded for all possible forms of const and ref
823   // qualifiers.
824   template <typename F>
825   constexpr auto or_else(F&& f) & noexcept {
826     return internal::OrElse(*this, std::forward<F>(f));
827   }
828 
829   template <typename F>
830   constexpr auto or_else(F&& f) const& noexcept {
831     return internal::OrElse(*this, std::forward<F>(f));
832   }
833 
834   template <typename F>
835   constexpr auto or_else(F&& f) && noexcept {
836     return internal::OrElse(std::move(*this), std::forward<F>(f));
837   }
838 
839   template <typename F>
840   constexpr auto or_else(F&& f) const&& noexcept {
841     return internal::OrElse(std::move(*this), std::forward<F>(f));
842   }
843 
844   // `transform`: This methods accepts a callable `f` that is invoked with no
845   // arguments in case `has_value()` is true.
846   //
847   // `f`'s return type U needs to be a valid value_type for expected, i.e. any
848   // type for which `remove_cv_t` is either void, or a complete non-array object
849   // type that is not `absl::in_place_t`, `base::unexpect_t`, or a
850   // specialization of `base::ok` or `base::unexpected`.
851   //
852   // Returns an instance of base::expected<remove_cv_t<U>, E> that is
853   // constructed with f() if has_value() is true, or unexpected(error())
854   // otherwise.
855   //
856   // `transform` is overloaded for all possible forms of const and ref
857   // qualifiers.
858   template <typename F>
859     requires(std::copy_constructible<E>)
860   constexpr auto transform(F&& f) & noexcept {
861     return internal::Transform(*this, std::forward<F>(f));
862   }
863 
864   template <typename F>
865     requires(std::copy_constructible<E>)
866   constexpr auto transform(F&& f) const& noexcept {
867     return internal::Transform(*this, std::forward<F>(f));
868   }
869 
870   template <typename F>
871     requires(std::move_constructible<E>)
872   constexpr auto transform(F&& f) && noexcept {
873     return internal::Transform(std::move(*this), std::forward<F>(f));
874   }
875 
876   template <typename F>
877     requires(std::move_constructible<E>)
878   constexpr auto transform(F&& f) const&& noexcept {
879     return internal::Transform(std::move(*this), std::forward<F>(f));
880   }
881 
882   // `transform_error`: This methods accepts a callable `f` that is invoked with
883   // `error()` in case `has_value()` is false.
884   //
885   // `f`'s return type G needs to be a valid error_type for expected, i.e. any
886   // type for which `remove_cv_t` is a complete non-array object type that is
887   // not `absl::in_place_t`, `base::unexpect_t`, or a specialization of
888   // `base::ok` or `base::unexpected`.
889   //
890   // Returns an instance of base::expected<cv void, remove_cv_t<G>> that is
891   // constructed with unexpected(f(error())) if there is no value, or default
892   // constructed otherwise.
893   //
894   // `transform_error` is overloaded for all possible forms of const and ref
895   // qualifiers.
896   template <typename F>
897   constexpr auto transform_error(F&& f) & noexcept {
898     return internal::TransformError(*this, std::forward<F>(f));
899   }
900 
901   template <typename F>
902   constexpr auto transform_error(F&& f) const& noexcept {
903     return internal::TransformError(*this, std::forward<F>(f));
904   }
905 
906   template <typename F>
907   constexpr auto transform_error(F&& f) && noexcept {
908     return internal::TransformError(std::move(*this), std::forward<F>(f));
909   }
910 
911   template <typename F>
912   constexpr auto transform_error(F&& f) const&& noexcept {
913     return internal::TransformError(std::move(*this), std::forward<F>(f));
914   }
915 
916   // Deviation from the Standard: stringification support.
917   //
918   // If we move to `std::expected` someday, we would need to either forego nice
919   // formatted output or move to `std::format` or similar, which can have
920   // customized output for STL types.
921   std::string ToString() const {
922     return has_value() ? "Expected()"
923                        : StrCat({"Unexpected(", base::ToString(error()), ")"});
924   }
925 
926  private:
927   // Note: Since we can't store void types we use absl::monostate instead.
928   using Impl = internal::ExpectedImpl<absl::monostate, E>;
929   static constexpr auto kErrTag = Impl::kErrTag;
930 
931   Impl impl_;
932 };
933 
934 // [expected.object.eq], equality operators
935 // [expected.void.eq], equality operators
936 template <typename T, typename E, typename U, typename G>
937 constexpr bool operator==(const expected<T, E>& x,
938                           const expected<U, G>& y) noexcept {
939   if (x.has_value() != y.has_value()) {
940     return false;
941   }
942 
943   if (x.has_value()) {
944     // Values for expected void types always compare equal.
945     if constexpr (std::is_void_v<T> && std::is_void_v<U>) {
946       return true;
947     } else {
948       return x.value() == y.value();
949     }
950   }
951 
952   return x.error() == y.error();
953 }
954 
955 template <typename T, typename E, typename U>
956   requires(!std::is_void_v<T>)
957 constexpr bool operator==(const expected<T, E>& x, const U& v) noexcept {
958   return x.has_value() && x.value() == v;
959 }
960 
961 template <typename T, typename E, typename U>
962 constexpr bool operator==(const expected<T, E>& x, const ok<U>& o) noexcept {
963   if constexpr (std::is_void_v<T> && std::is_void_v<U>) {
964     return x.has_value();
965   } else if constexpr (std::is_void_v<T> || std::is_void_v<U>) {
966     return false;
967   } else {
968     return x.has_value() && x.value() == o.value();
969   }
970 }
971 
972 template <typename T, typename E, typename G>
973 constexpr bool operator==(const expected<T, E>& x,
974                           const unexpected<G>& e) noexcept {
975   return !x.has_value() && x.error() == e.error();
976 }
977 
978 }  // namespace base
979 
980 #endif  // BASE_TYPES_EXPECTED_H_
981