1 // Copyright 2020 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // -----------------------------------------------------------------------------
16 // File: statusor.h
17 // -----------------------------------------------------------------------------
18 //
19 // An `absl::StatusOr<T>` represents a union of an `absl::Status` object
20 // and an object of type `T`. The `absl::StatusOr<T>` will either contain an
21 // object of type `T` (indicating a successful operation), or an error (of type
22 // `absl::Status`) explaining why such a value is not present.
23 //
24 // In general, check the success of an operation returning an
25 // `absl::StatusOr<T>` like you would an `absl::Status` by using the `ok()`
26 // member function.
27 //
28 // Example:
29 //
30 //   StatusOr<Foo> result = Calculation();
31 //   if (result.ok()) {
32 //     result->DoSomethingCool();
33 //   } else {
34 //     LOG(ERROR) << result.status();
35 //   }
36 #ifndef ABSL_STATUS_STATUSOR_H_
37 #define ABSL_STATUS_STATUSOR_H_
38 
39 #include <exception>
40 #include <initializer_list>
41 #include <new>
42 #include <string>
43 #include <type_traits>
44 #include <utility>
45 
46 #include "absl/base/attributes.h"
47 #include "absl/base/call_once.h"
48 #include "absl/meta/type_traits.h"
49 #include "absl/status/internal/statusor_internal.h"
50 #include "absl/status/status.h"
51 #include "absl/types/variant.h"
52 #include "absl/utility/utility.h"
53 
54 namespace absl {
55 ABSL_NAMESPACE_BEGIN
56 
57 // BadStatusOrAccess
58 //
59 // This class defines the type of object to throw (if exceptions are enabled),
60 // when accessing the value of an `absl::StatusOr<T>` object that does not
61 // contain a value. This behavior is analogous to that of
62 // `std::bad_optional_access` in the case of accessing an invalid
63 // `std::optional` value.
64 //
65 // Example:
66 //
67 // try {
68 //   absl::StatusOr<int> v = FetchInt();
69 //   DoWork(v.value());  // Accessing value() when not "OK" may throw
70 // } catch (absl::BadStatusOrAccess& ex) {
71 //   LOG(ERROR) << ex.status();
72 // }
73 class BadStatusOrAccess : public std::exception {
74  public:
75   explicit BadStatusOrAccess(absl::Status status);
76   ~BadStatusOrAccess() override = default;
77 
78   BadStatusOrAccess(const BadStatusOrAccess& other);
79   BadStatusOrAccess& operator=(const BadStatusOrAccess& other);
80   BadStatusOrAccess(BadStatusOrAccess&& other);
81   BadStatusOrAccess& operator=(BadStatusOrAccess&& other);
82 
83   // BadStatusOrAccess::what()
84   //
85   // Returns the associated explanatory string of the `absl::StatusOr<T>`
86   // object's error code. This function contains information about the failing
87   // status, but its exact formatting may change and should not be depended on.
88   //
89   // The pointer of this string is guaranteed to be valid until any non-const
90   // function is invoked on the exception object.
91   const char* what() const noexcept override;
92 
93   // BadStatusOrAccess::status()
94   //
95   // Returns the associated `absl::Status` of the `absl::StatusOr<T>` object's
96   // error.
97   const absl::Status& status() const;
98 
99  private:
100   void InitWhat() const;
101 
102   absl::Status status_;
103   mutable absl::once_flag init_what_;
104   mutable std::string what_;
105 };
106 
107 // Returned StatusOr objects may not be ignored.
108 template <typename T>
109 #if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
110 // TODO(b/176172494): ABSL_MUST_USE_RESULT should expand to the more strict
111 // [[nodiscard]]. For now, just use [[nodiscard]] directly when it is available.
112 class [[nodiscard]] StatusOr;
113 #else
114 class ABSL_MUST_USE_RESULT StatusOr;
115 #endif  // ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
116 
117 // absl::StatusOr<T>
118 //
119 // The `absl::StatusOr<T>` class template is a union of an `absl::Status` object
120 // and an object of type `T`. The `absl::StatusOr<T>` models an object that is
121 // either a usable object, or an error (of type `absl::Status`) explaining why
122 // such an object is not present. An `absl::StatusOr<T>` is typically the return
123 // value of a function which may fail.
124 //
125 // An `absl::StatusOr<T>` can never hold an "OK" status (an
126 // `absl::StatusCode::kOk` value); instead, the presence of an object of type
127 // `T` indicates success. Instead of checking for a `kOk` value, use the
128 // `absl::StatusOr<T>::ok()` member function. (It is for this reason, and code
129 // readability, that using the `ok()` function is preferred for `absl::Status`
130 // as well.)
131 //
132 // Example:
133 //
134 //   StatusOr<Foo> result = DoBigCalculationThatCouldFail();
135 //   if (result.ok()) {
136 //     result->DoSomethingCool();
137 //   } else {
138 //     LOG(ERROR) << result.status();
139 //   }
140 //
141 // Accessing the object held by an `absl::StatusOr<T>` should be performed via
142 // `operator*` or `operator->`, after a call to `ok()` confirms that the
143 // `absl::StatusOr<T>` holds an object of type `T`:
144 //
145 // Example:
146 //
147 //   absl::StatusOr<int> i = GetCount();
148 //   if (i.ok()) {
149 //     updated_total += *i
150 //   }
151 //
152 // NOTE: using `absl::StatusOr<T>::value()` when no valid value is present will
153 // throw an exception if exceptions are enabled or terminate the process when
154 // exceptions are not enabled.
155 //
156 // Example:
157 //
158 //   StatusOr<Foo> result = DoBigCalculationThatCouldFail();
159 //   const Foo& foo = result.value();    // Crash/exception if no value present
160 //   foo.DoSomethingCool();
161 //
162 // A `absl::StatusOr<T*>` can be constructed from a null pointer like any other
163 // pointer value, and the result will be that `ok()` returns `true` and
164 // `value()` returns `nullptr`. Checking the value of pointer in an
165 // `absl::StatusOr<T*>` generally requires a bit more care, to ensure both that
166 // a value is present and that value is not null:
167 //
168 //  StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg);
169 //  if (!result.ok()) {
170 //    LOG(ERROR) << result.status();
171 //  } else if (*result == nullptr) {
172 //    LOG(ERROR) << "Unexpected null pointer";
173 //  } else {
174 //    (*result)->DoSomethingCool();
175 //  }
176 //
177 // Example factory implementation returning StatusOr<T>:
178 //
179 //  StatusOr<Foo> FooFactory::MakeFoo(int arg) {
180 //    if (arg <= 0) {
181 //      return absl::Status(absl::StatusCode::kInvalidArgument,
182 //                          "Arg must be positive");
183 //    }
184 //    return Foo(arg);
185 //  }
186 template <typename T>
187 class StatusOr : private internal_statusor::StatusOrData<T>,
188                  private internal_statusor::CopyCtorBase<T>,
189                  private internal_statusor::MoveCtorBase<T>,
190                  private internal_statusor::CopyAssignBase<T>,
191                  private internal_statusor::MoveAssignBase<T> {
192   template <typename U>
193   friend class StatusOr;
194 
195   typedef internal_statusor::StatusOrData<T> Base;
196 
197  public:
198   // StatusOr<T>::value_type
199   //
200   // This instance data provides a generic `value_type` member for use within
201   // generic programming. This usage is analogous to that of
202   // `optional::value_type` in the case of `std::optional`.
203   typedef T value_type;
204 
205   // Constructors
206 
207   // Constructs a new `absl::StatusOr` with an `absl::StatusCode::kUnknown`
208   // status. This constructor is marked 'explicit' to prevent usages in return
209   // values such as 'return {};', under the misconception that
210   // `absl::StatusOr<std::vector<int>>` will be initialized with an empty
211   // vector, instead of an `absl::StatusCode::kUnknown` error code.
212   explicit StatusOr();
213 
214   // `StatusOr<T>` is copy constructible if `T` is copy constructible.
215   StatusOr(const StatusOr&) = default;
216   // `StatusOr<T>` is copy assignable if `T` is copy constructible and copy
217   // assignable.
218   StatusOr& operator=(const StatusOr&) = default;
219 
220   // `StatusOr<T>` is move constructible if `T` is move constructible.
221   StatusOr(StatusOr&&) = default;
222   // `StatusOr<T>` is moveAssignable if `T` is move constructible and move
223   // assignable.
224   StatusOr& operator=(StatusOr&&) = default;
225 
226   // Converting Constructors
227 
228   // Constructs a new `absl::StatusOr<T>` from an `absl::StatusOr<U>`, when `T`
229   // is constructible from `U`. To avoid ambiguity, these constructors are
230   // disabled if `T` is also constructible from `StatusOr<U>.`. This constructor
231   // is explicit if and only if the corresponding construction of `T` from `U`
232   // is explicit. (This constructor inherits its explicitness from the
233   // underlying constructor.)
234   template <
235       typename U,
236       absl::enable_if_t<
237           absl::conjunction<
238               absl::negation<std::is_same<T, U>>,
239               std::is_constructible<T, const U&>,
240               std::is_convertible<const U&, T>,
241               absl::negation<
242                   internal_statusor::IsConstructibleOrConvertibleFromStatusOr<
243                       T, U>>>::value,
244           int> = 0>
StatusOr(const StatusOr<U> & other)245   StatusOr(const StatusOr<U>& other)  // NOLINT
246       : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {}
247   template <
248       typename U,
249       absl::enable_if_t<
250           absl::conjunction<
251               absl::negation<std::is_same<T, U>>,
252               std::is_constructible<T, const U&>,
253               absl::negation<std::is_convertible<const U&, T>>,
254               absl::negation<
255                   internal_statusor::IsConstructibleOrConvertibleFromStatusOr<
256                       T, U>>>::value,
257           int> = 0>
StatusOr(const StatusOr<U> & other)258   explicit StatusOr(const StatusOr<U>& other)
259       : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {}
260 
261   template <
262       typename U,
263       absl::enable_if_t<
264           absl::conjunction<
265               absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>,
266               std::is_convertible<U&&, T>,
267               absl::negation<
268                   internal_statusor::IsConstructibleOrConvertibleFromStatusOr<
269                       T, U>>>::value,
270           int> = 0>
StatusOr(StatusOr<U> && other)271   StatusOr(StatusOr<U>&& other)  // NOLINT
272       : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {}
273   template <
274       typename U,
275       absl::enable_if_t<
276           absl::conjunction<
277               absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>,
278               absl::negation<std::is_convertible<U&&, T>>,
279               absl::negation<
280                   internal_statusor::IsConstructibleOrConvertibleFromStatusOr<
281                       T, U>>>::value,
282           int> = 0>
StatusOr(StatusOr<U> && other)283   explicit StatusOr(StatusOr<U>&& other)
284       : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {}
285 
286   // Converting Assignment Operators
287 
288   // Creates an `absl::StatusOr<T>` through assignment from an
289   // `absl::StatusOr<U>` when:
290   //
291   //   * Both `absl::StatusOr<T>` and `absl::StatusOr<U>` are OK by assigning
292   //     `U` to `T` directly.
293   //   * `absl::StatusOr<T>` is OK and `absl::StatusOr<U>` contains an error
294   //      code by destroying `absl::StatusOr<T>`'s value and assigning from
295   //      `absl::StatusOr<U>'
296   //   * `absl::StatusOr<T>` contains an error code and `absl::StatusOr<U>` is
297   //      OK by directly initializing `T` from `U`.
298   //   * Both `absl::StatusOr<T>` and `absl::StatusOr<U>` contain an error
299   //     code by assigning the `Status` in `absl::StatusOr<U>` to
300   //     `absl::StatusOr<T>`
301   //
302   // These overloads only apply if `absl::StatusOr<T>` is constructible and
303   // assignable from `absl::StatusOr<U>` and `StatusOr<T>` cannot be directly
304   // assigned from `StatusOr<U>`.
305   template <
306       typename U,
307       absl::enable_if_t<
308           absl::conjunction<
309               absl::negation<std::is_same<T, U>>,
310               std::is_constructible<T, const U&>,
311               std::is_assignable<T, const U&>,
312               absl::negation<
313                   internal_statusor::
314                       IsConstructibleOrConvertibleOrAssignableFromStatusOr<
315                           T, U>>>::value,
316           int> = 0>
317   StatusOr& operator=(const StatusOr<U>& other) {
318     this->Assign(other);
319     return *this;
320   }
321   template <
322       typename U,
323       absl::enable_if_t<
324           absl::conjunction<
325               absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>,
326               std::is_assignable<T, U&&>,
327               absl::negation<
328                   internal_statusor::
329                       IsConstructibleOrConvertibleOrAssignableFromStatusOr<
330                           T, U>>>::value,
331           int> = 0>
332   StatusOr& operator=(StatusOr<U>&& other) {
333     this->Assign(std::move(other));
334     return *this;
335   }
336 
337   // Constructs a new `absl::StatusOr<T>` with a non-ok status. After calling
338   // this constructor, `this->ok()` will be `false` and calls to `value()` will
339   // crash, or produce an exception if exceptions are enabled.
340   //
341   // The constructor also takes any type `U` that is convertible to
342   // `absl::Status`. This constructor is explicit if an only if `U` is not of
343   // type `absl::Status` and the conversion from `U` to `Status` is explicit.
344   //
345   // REQUIRES: !Status(std::forward<U>(v)).ok(). This requirement is DCHECKed.
346   // In optimized builds, passing absl::OkStatus() here will have the effect
347   // of passing absl::StatusCode::kInternal as a fallback.
348   template <
349       typename U = absl::Status,
350       absl::enable_if_t<
351           absl::conjunction<
352               std::is_convertible<U&&, absl::Status>,
353               std::is_constructible<absl::Status, U&&>,
354               absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>,
355               absl::negation<std::is_same<absl::decay_t<U>, T>>,
356               absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>,
357               absl::negation<internal_statusor::HasConversionOperatorToStatusOr<
358                   T, U&&>>>::value,
359           int> = 0>
StatusOr(U && v)360   StatusOr(U&& v) : Base(std::forward<U>(v)) {}
361 
362   template <
363       typename U = absl::Status,
364       absl::enable_if_t<
365           absl::conjunction<
366               absl::negation<std::is_convertible<U&&, absl::Status>>,
367               std::is_constructible<absl::Status, U&&>,
368               absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>,
369               absl::negation<std::is_same<absl::decay_t<U>, T>>,
370               absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>,
371               absl::negation<internal_statusor::HasConversionOperatorToStatusOr<
372                   T, U&&>>>::value,
373           int> = 0>
StatusOr(U && v)374   explicit StatusOr(U&& v) : Base(std::forward<U>(v)) {}
375 
376   template <
377       typename U = absl::Status,
378       absl::enable_if_t<
379           absl::conjunction<
380               std::is_convertible<U&&, absl::Status>,
381               std::is_constructible<absl::Status, U&&>,
382               absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>,
383               absl::negation<std::is_same<absl::decay_t<U>, T>>,
384               absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>,
385               absl::negation<internal_statusor::HasConversionOperatorToStatusOr<
386                   T, U&&>>>::value,
387           int> = 0>
388   StatusOr& operator=(U&& v) {
389     this->AssignStatus(std::forward<U>(v));
390     return *this;
391   }
392 
393   // Perfect-forwarding value assignment operator.
394 
395   // If `*this` contains a `T` value before the call, the contained value is
396   // assigned from `std::forward<U>(v)`; Otherwise, it is directly-initialized
397   // from `std::forward<U>(v)`.
398   // This function does not participate in overload unless:
399   // 1. `std::is_constructible_v<T, U>` is true,
400   // 2. `std::is_assignable_v<T&, U>` is true.
401   // 3. `std::is_same_v<StatusOr<T>, std::remove_cvref_t<U>>` is false.
402   // 4. Assigning `U` to `T` is not ambiguous:
403   //  If `U` is `StatusOr<V>` and `T` is constructible and assignable from
404   //  both `StatusOr<V>` and `V`, the assignment is considered bug-prone and
405   //  ambiguous thus will fail to compile. For example:
406   //    StatusOr<bool> s1 = true;  // s1.ok() && *s1 == true
407   //    StatusOr<bool> s2 = false;  // s2.ok() && *s2 == false
408   //    s1 = s2;  // ambiguous, `s1 = *s2` or `s1 = bool(s2)`?
409   template <
410       typename U = T,
411       typename = typename std::enable_if<absl::conjunction<
412           std::is_constructible<T, U&&>, std::is_assignable<T&, U&&>,
413           absl::disjunction<
414               std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, T>,
415               absl::conjunction<
416                   absl::negation<std::is_convertible<U&&, absl::Status>>,
417                   absl::negation<internal_statusor::
418                                      HasConversionOperatorToStatusOr<T, U&&>>>>,
419           internal_statusor::IsForwardingAssignmentValid<T, U&&>>::value>::type>
420   StatusOr& operator=(U&& v) {
421     this->Assign(std::forward<U>(v));
422     return *this;
423   }
424 
425   // Constructs the inner value `T` in-place using the provided args, using the
426   // `T(args...)` constructor.
427   template <typename... Args>
428   explicit StatusOr(absl::in_place_t, Args&&... args);
429   template <typename U, typename... Args>
430   explicit StatusOr(absl::in_place_t, std::initializer_list<U> ilist,
431                     Args&&... args);
432 
433   // Constructs the inner value `T` in-place using the provided args, using the
434   // `T(U)` (direct-initialization) constructor. This constructor is only valid
435   // if `T` can be constructed from a `U`. Can accept move or copy constructors.
436   //
437   // This constructor is explicit if `U` is not convertible to `T`. To avoid
438   // ambiguity, this constructor is disabled if `U` is a `StatusOr<J>`, where
439   // `J` is convertible to `T`.
440   template <
441       typename U = T,
442       absl::enable_if_t<
443           absl::conjunction<
444               internal_statusor::IsDirectInitializationValid<T, U&&>,
445               std::is_constructible<T, U&&>, std::is_convertible<U&&, T>,
446               absl::disjunction<
447                   std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>,
448                                T>,
449                   absl::conjunction<
450                       absl::negation<std::is_convertible<U&&, absl::Status>>,
451                       absl::negation<
452                           internal_statusor::HasConversionOperatorToStatusOr<
453                               T, U&&>>>>>::value,
454           int> = 0>
StatusOr(U && u)455   StatusOr(U&& u)  // NOLINT
456       : StatusOr(absl::in_place, std::forward<U>(u)) {}
457 
458   template <
459       typename U = T,
460       absl::enable_if_t<
461           absl::conjunction<
462               internal_statusor::IsDirectInitializationValid<T, U&&>,
463               absl::disjunction<
464                   std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>,
465                                T>,
466                   absl::conjunction<
467                       absl::negation<std::is_constructible<absl::Status, U&&>>,
468                       absl::negation<
469                           internal_statusor::HasConversionOperatorToStatusOr<
470                               T, U&&>>>>,
471               std::is_constructible<T, U&&>,
472               absl::negation<std::is_convertible<U&&, T>>>::value,
473           int> = 0>
StatusOr(U && u)474   explicit StatusOr(U&& u)  // NOLINT
475       : StatusOr(absl::in_place, std::forward<U>(u)) {}
476 
477   // StatusOr<T>::ok()
478   //
479   // Returns whether or not this `absl::StatusOr<T>` holds a `T` value. This
480   // member function is analogous to `absl::Status::ok()` and should be used
481   // similarly to check the status of return values.
482   //
483   // Example:
484   //
485   // StatusOr<Foo> result = DoBigCalculationThatCouldFail();
486   // if (result.ok()) {
487   //    // Handle result
488   // else {
489   //    // Handle error
490   // }
ok()491   ABSL_MUST_USE_RESULT bool ok() const { return this->status_.ok(); }
492 
493   // StatusOr<T>::status()
494   //
495   // Returns a reference to the current `absl::Status` contained within the
496   // `absl::StatusOr<T>`. If `absl::StatusOr<T>` contains a `T`, then this
497   // function returns `absl::OkStatus()`.
498   const Status& status() const&;
499   Status status() &&;
500 
501   // StatusOr<T>::value()
502   //
503   // Returns a reference to the held value if `this->ok()`. Otherwise, throws
504   // `absl::BadStatusOrAccess` if exceptions are enabled, or is guaranteed to
505   // terminate the process if exceptions are disabled.
506   //
507   // If you have already checked the status using `this->ok()`, you probably
508   // want to use `operator*()` or `operator->()` to access the value instead of
509   // `value`.
510   //
511   // Note: for value types that are cheap to copy, prefer simple code:
512   //
513   //   T value = statusor.value();
514   //
515   // Otherwise, if the value type is expensive to copy, but can be left
516   // in the StatusOr, simply assign to a reference:
517   //
518   //   T& value = statusor.value();  // or `const T&`
519   //
520   // Otherwise, if the value type supports an efficient move, it can be
521   // used as follows:
522   //
523   //   T value = std::move(statusor).value();
524   //
525   // The `std::move` on statusor instead of on the whole expression enables
526   // warnings about possible uses of the statusor object after the move.
527   const T& value() const& ABSL_ATTRIBUTE_LIFETIME_BOUND;
528   T& value() & ABSL_ATTRIBUTE_LIFETIME_BOUND;
529   const T&& value() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND;
530   T&& value() && ABSL_ATTRIBUTE_LIFETIME_BOUND;
531 
532   // StatusOr<T>:: operator*()
533   //
534   // Returns a reference to the current value.
535   //
536   // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined.
537   //
538   // Use `this->ok()` to verify that there is a current value within the
539   // `absl::StatusOr<T>`. Alternatively, see the `value()` member function for a
540   // similar API that guarantees crashing or throwing an exception if there is
541   // no current value.
542   const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND;
543   T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND;
544   const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND;
545   T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND;
546 
547   // StatusOr<T>::operator->()
548   //
549   // Returns a pointer to the current value.
550   //
551   // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined.
552   //
553   // Use `this->ok()` to verify that there is a current value.
554   const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
555   T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND;
556 
557   // StatusOr<T>::value_or()
558   //
559   // Returns the current value if `this->ok() == true`. Otherwise constructs a
560   // value using the provided `default_value`.
561   //
562   // Unlike `value`, this function returns by value, copying the current value
563   // if necessary. If the value type supports an efficient move, it can be used
564   // as follows:
565   //
566   //   T value = std::move(statusor).value_or(def);
567   //
568   // Unlike with `value`, calling `std::move()` on the result of `value_or` will
569   // still trigger a copy.
570   template <typename U>
571   T value_or(U&& default_value) const&;
572   template <typename U>
573   T value_or(U&& default_value) &&;
574 
575   // StatusOr<T>::IgnoreError()
576   //
577   // Ignores any errors. This method does nothing except potentially suppress
578   // complaints from any tools that are checking that errors are not dropped on
579   // the floor.
580   void IgnoreError() const;
581 
582   // StatusOr<T>::emplace()
583   //
584   // Reconstructs the inner value T in-place using the provided args, using the
585   // T(args...) constructor. Returns reference to the reconstructed `T`.
586   template <typename... Args>
emplace(Args &&...args)587   T& emplace(Args&&... args) {
588     if (ok()) {
589       this->Clear();
590       this->MakeValue(std::forward<Args>(args)...);
591     } else {
592       this->MakeValue(std::forward<Args>(args)...);
593       this->status_ = absl::OkStatus();
594     }
595     return this->data_;
596   }
597 
598   template <
599       typename U, typename... Args,
600       absl::enable_if_t<
601           std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
602           int> = 0>
emplace(std::initializer_list<U> ilist,Args &&...args)603   T& emplace(std::initializer_list<U> ilist, Args&&... args) {
604     if (ok()) {
605       this->Clear();
606       this->MakeValue(ilist, std::forward<Args>(args)...);
607     } else {
608       this->MakeValue(ilist, std::forward<Args>(args)...);
609       this->status_ = absl::OkStatus();
610     }
611     return this->data_;
612   }
613 
614  private:
615   using internal_statusor::StatusOrData<T>::Assign;
616   template <typename U>
617   void Assign(const absl::StatusOr<U>& other);
618   template <typename U>
619   void Assign(absl::StatusOr<U>&& other);
620 };
621 
622 // operator==()
623 //
624 // This operator checks the equality of two `absl::StatusOr<T>` objects.
625 template <typename T>
626 bool operator==(const StatusOr<T>& lhs, const StatusOr<T>& rhs) {
627   if (lhs.ok() && rhs.ok()) return *lhs == *rhs;
628   return lhs.status() == rhs.status();
629 }
630 
631 // operator!=()
632 //
633 // This operator checks the inequality of two `absl::StatusOr<T>` objects.
634 template <typename T>
635 bool operator!=(const StatusOr<T>& lhs, const StatusOr<T>& rhs) {
636   return !(lhs == rhs);
637 }
638 
639 //------------------------------------------------------------------------------
640 // Implementation details for StatusOr<T>
641 //------------------------------------------------------------------------------
642 
643 // TODO(sbenza): avoid the string here completely.
644 template <typename T>
StatusOr()645 StatusOr<T>::StatusOr() : Base(Status(absl::StatusCode::kUnknown, "")) {}
646 
647 template <typename T>
648 template <typename U>
Assign(const StatusOr<U> & other)649 inline void StatusOr<T>::Assign(const StatusOr<U>& other) {
650   if (other.ok()) {
651     this->Assign(*other);
652   } else {
653     this->AssignStatus(other.status());
654   }
655 }
656 
657 template <typename T>
658 template <typename U>
Assign(StatusOr<U> && other)659 inline void StatusOr<T>::Assign(StatusOr<U>&& other) {
660   if (other.ok()) {
661     this->Assign(*std::move(other));
662   } else {
663     this->AssignStatus(std::move(other).status());
664   }
665 }
666 template <typename T>
667 template <typename... Args>
StatusOr(absl::in_place_t,Args &&...args)668 StatusOr<T>::StatusOr(absl::in_place_t, Args&&... args)
669     : Base(absl::in_place, std::forward<Args>(args)...) {}
670 
671 template <typename T>
672 template <typename U, typename... Args>
StatusOr(absl::in_place_t,std::initializer_list<U> ilist,Args &&...args)673 StatusOr<T>::StatusOr(absl::in_place_t, std::initializer_list<U> ilist,
674                       Args&&... args)
675     : Base(absl::in_place, ilist, std::forward<Args>(args)...) {}
676 
677 template <typename T>
status()678 const Status& StatusOr<T>::status() const& {
679   return this->status_;
680 }
681 template <typename T>
status()682 Status StatusOr<T>::status() && {
683   return ok() ? OkStatus() : std::move(this->status_);
684 }
685 
686 template <typename T>
value()687 const T& StatusOr<T>::value() const& {
688   if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_);
689   return this->data_;
690 }
691 
692 template <typename T>
value()693 T& StatusOr<T>::value() & {
694   if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_);
695   return this->data_;
696 }
697 
698 template <typename T>
value()699 const T&& StatusOr<T>::value() const&& {
700   if (!this->ok()) {
701     internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_));
702   }
703   return std::move(this->data_);
704 }
705 
706 template <typename T>
value()707 T&& StatusOr<T>::value() && {
708   if (!this->ok()) {
709     internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_));
710   }
711   return std::move(this->data_);
712 }
713 
714 template <typename T>
715 const T& StatusOr<T>::operator*() const& {
716   this->EnsureOk();
717   return this->data_;
718 }
719 
720 template <typename T>
721 T& StatusOr<T>::operator*() & {
722   this->EnsureOk();
723   return this->data_;
724 }
725 
726 template <typename T>
727 const T&& StatusOr<T>::operator*() const&& {
728   this->EnsureOk();
729   return std::move(this->data_);
730 }
731 
732 template <typename T>
733 T&& StatusOr<T>::operator*() && {
734   this->EnsureOk();
735   return std::move(this->data_);
736 }
737 
738 template <typename T>
739 const T* StatusOr<T>::operator->() const {
740   this->EnsureOk();
741   return &this->data_;
742 }
743 
744 template <typename T>
745 T* StatusOr<T>::operator->() {
746   this->EnsureOk();
747   return &this->data_;
748 }
749 
750 template <typename T>
751 template <typename U>
value_or(U && default_value)752 T StatusOr<T>::value_or(U&& default_value) const& {
753   if (ok()) {
754     return this->data_;
755   }
756   return std::forward<U>(default_value);
757 }
758 
759 template <typename T>
760 template <typename U>
value_or(U && default_value)761 T StatusOr<T>::value_or(U&& default_value) && {
762   if (ok()) {
763     return std::move(this->data_);
764   }
765   return std::forward<U>(default_value);
766 }
767 
768 template <typename T>
IgnoreError()769 void StatusOr<T>::IgnoreError() const {
770   // no-op
771 }
772 
773 ABSL_NAMESPACE_END
774 }  // namespace absl
775 
776 #endif  // ABSL_STATUS_STATUSOR_H_
777