Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 09:33:37

0001 // Copyright 2020 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
0014 //
0015 // -----------------------------------------------------------------------------
0016 // File: statusor.h
0017 // -----------------------------------------------------------------------------
0018 //
0019 // An `absl::StatusOr<T>` represents a union of an `absl::Status` object
0020 // and an object of type `T`. The `absl::StatusOr<T>` will either contain an
0021 // object of type `T` (indicating a successful operation), or an error (of type
0022 // `absl::Status`) explaining why such a value is not present.
0023 //
0024 // In general, check the success of an operation returning an
0025 // `absl::StatusOr<T>` like you would an `absl::Status` by using the `ok()`
0026 // member function.
0027 //
0028 // Example:
0029 //
0030 //   StatusOr<Foo> result = Calculation();
0031 //   if (result.ok()) {
0032 //     result->DoSomethingCool();
0033 //   } else {
0034 //     LOG(ERROR) << result.status();
0035 //   }
0036 #ifndef ABSL_STATUS_STATUSOR_H_
0037 #define ABSL_STATUS_STATUSOR_H_
0038 
0039 #include <exception>
0040 #include <initializer_list>
0041 #include <new>
0042 #include <ostream>
0043 #include <string>
0044 #include <type_traits>
0045 #include <utility>
0046 
0047 #include "absl/base/attributes.h"
0048 #include "absl/base/nullability.h"
0049 #include "absl/base/call_once.h"
0050 #include "absl/meta/type_traits.h"
0051 #include "absl/status/internal/statusor_internal.h"
0052 #include "absl/status/status.h"
0053 #include "absl/strings/has_absl_stringify.h"
0054 #include "absl/strings/has_ostream_operator.h"
0055 #include "absl/strings/str_format.h"
0056 #include "absl/types/variant.h"
0057 #include "absl/utility/utility.h"
0058 
0059 namespace absl {
0060 ABSL_NAMESPACE_BEGIN
0061 
0062 // BadStatusOrAccess
0063 //
0064 // This class defines the type of object to throw (if exceptions are enabled),
0065 // when accessing the value of an `absl::StatusOr<T>` object that does not
0066 // contain a value. This behavior is analogous to that of
0067 // `std::bad_optional_access` in the case of accessing an invalid
0068 // `std::optional` value.
0069 //
0070 // Example:
0071 //
0072 // try {
0073 //   absl::StatusOr<int> v = FetchInt();
0074 //   DoWork(v.value());  // Accessing value() when not "OK" may throw
0075 // } catch (absl::BadStatusOrAccess& ex) {
0076 //   LOG(ERROR) << ex.status();
0077 // }
0078 class BadStatusOrAccess : public std::exception {
0079  public:
0080   explicit BadStatusOrAccess(absl::Status status);
0081   ~BadStatusOrAccess() override = default;
0082 
0083   BadStatusOrAccess(const BadStatusOrAccess& other);
0084   BadStatusOrAccess& operator=(const BadStatusOrAccess& other);
0085   BadStatusOrAccess(BadStatusOrAccess&& other);
0086   BadStatusOrAccess& operator=(BadStatusOrAccess&& other);
0087 
0088   // BadStatusOrAccess::what()
0089   //
0090   // Returns the associated explanatory string of the `absl::StatusOr<T>`
0091   // object's error code. This function contains information about the failing
0092   // status, but its exact formatting may change and should not be depended on.
0093   //
0094   // The pointer of this string is guaranteed to be valid until any non-const
0095   // function is invoked on the exception object.
0096   absl::Nonnull<const char*> what() const noexcept override;
0097 
0098   // BadStatusOrAccess::status()
0099   //
0100   // Returns the associated `absl::Status` of the `absl::StatusOr<T>` object's
0101   // error.
0102   const absl::Status& status() const;
0103 
0104  private:
0105   void InitWhat() const;
0106 
0107   absl::Status status_;
0108   mutable absl::once_flag init_what_;
0109   mutable std::string what_;
0110 };
0111 
0112 // Returned StatusOr objects may not be ignored.
0113 template <typename T>
0114 #if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
0115 // TODO(b/176172494): ABSL_MUST_USE_RESULT should expand to the more strict
0116 // [[nodiscard]]. For now, just use [[nodiscard]] directly when it is available.
0117 class [[nodiscard]] StatusOr;
0118 #else
0119 class ABSL_MUST_USE_RESULT StatusOr;
0120 #endif  // ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
0121 
0122 // absl::StatusOr<T>
0123 //
0124 // The `absl::StatusOr<T>` class template is a union of an `absl::Status` object
0125 // and an object of type `T`. The `absl::StatusOr<T>` models an object that is
0126 // either a usable object, or an error (of type `absl::Status`) explaining why
0127 // such an object is not present. An `absl::StatusOr<T>` is typically the return
0128 // value of a function which may fail.
0129 //
0130 // An `absl::StatusOr<T>` can never hold an "OK" status (an
0131 // `absl::StatusCode::kOk` value); instead, the presence of an object of type
0132 // `T` indicates success. Instead of checking for a `kOk` value, use the
0133 // `absl::StatusOr<T>::ok()` member function. (It is for this reason, and code
0134 // readability, that using the `ok()` function is preferred for `absl::Status`
0135 // as well.)
0136 //
0137 // Example:
0138 //
0139 //   StatusOr<Foo> result = DoBigCalculationThatCouldFail();
0140 //   if (result.ok()) {
0141 //     result->DoSomethingCool();
0142 //   } else {
0143 //     LOG(ERROR) << result.status();
0144 //   }
0145 //
0146 // Accessing the object held by an `absl::StatusOr<T>` should be performed via
0147 // `operator*` or `operator->`, after a call to `ok()` confirms that the
0148 // `absl::StatusOr<T>` holds an object of type `T`:
0149 //
0150 // Example:
0151 //
0152 //   absl::StatusOr<int> i = GetCount();
0153 //   if (i.ok()) {
0154 //     updated_total += *i;
0155 //   }
0156 //
0157 // NOTE: using `absl::StatusOr<T>::value()` when no valid value is present will
0158 // throw an exception if exceptions are enabled or terminate the process when
0159 // exceptions are not enabled.
0160 //
0161 // Example:
0162 //
0163 //   StatusOr<Foo> result = DoBigCalculationThatCouldFail();
0164 //   const Foo& foo = result.value();    // Crash/exception if no value present
0165 //   foo.DoSomethingCool();
0166 //
0167 // A `absl::StatusOr<T*>` can be constructed from a null pointer like any other
0168 // pointer value, and the result will be that `ok()` returns `true` and
0169 // `value()` returns `nullptr`. Checking the value of pointer in an
0170 // `absl::StatusOr<T*>` generally requires a bit more care, to ensure both that
0171 // a value is present and that value is not null:
0172 //
0173 //  StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg);
0174 //  if (!result.ok()) {
0175 //    LOG(ERROR) << result.status();
0176 //  } else if (*result == nullptr) {
0177 //    LOG(ERROR) << "Unexpected null pointer";
0178 //  } else {
0179 //    (*result)->DoSomethingCool();
0180 //  }
0181 //
0182 // Example factory implementation returning StatusOr<T>:
0183 //
0184 //  StatusOr<Foo> FooFactory::MakeFoo(int arg) {
0185 //    if (arg <= 0) {
0186 //      return absl::Status(absl::StatusCode::kInvalidArgument,
0187 //                          "Arg must be positive");
0188 //    }
0189 //    return Foo(arg);
0190 //  }
0191 template <typename T>
0192 class StatusOr : private internal_statusor::StatusOrData<T>,
0193                  private internal_statusor::CopyCtorBase<T>,
0194                  private internal_statusor::MoveCtorBase<T>,
0195                  private internal_statusor::CopyAssignBase<T>,
0196                  private internal_statusor::MoveAssignBase<T> {
0197   template <typename U>
0198   friend class StatusOr;
0199 
0200   typedef internal_statusor::StatusOrData<T> Base;
0201 
0202  public:
0203   // StatusOr<T>::value_type
0204   //
0205   // This instance data provides a generic `value_type` member for use within
0206   // generic programming. This usage is analogous to that of
0207   // `optional::value_type` in the case of `std::optional`.
0208   typedef T value_type;
0209 
0210   // Constructors
0211 
0212   // Constructs a new `absl::StatusOr` with an `absl::StatusCode::kUnknown`
0213   // status. This constructor is marked 'explicit' to prevent usages in return
0214   // values such as 'return {};', under the misconception that
0215   // `absl::StatusOr<std::vector<int>>` will be initialized with an empty
0216   // vector, instead of an `absl::StatusCode::kUnknown` error code.
0217   explicit StatusOr();
0218 
0219   // `StatusOr<T>` is copy constructible if `T` is copy constructible.
0220   StatusOr(const StatusOr&) = default;
0221   // `StatusOr<T>` is copy assignable if `T` is copy constructible and copy
0222   // assignable.
0223   StatusOr& operator=(const StatusOr&) = default;
0224 
0225   // `StatusOr<T>` is move constructible if `T` is move constructible.
0226   StatusOr(StatusOr&&) = default;
0227   // `StatusOr<T>` is moveAssignable if `T` is move constructible and move
0228   // assignable.
0229   StatusOr& operator=(StatusOr&&) = default;
0230 
0231   // Converting Constructors
0232 
0233   // Constructs a new `absl::StatusOr<T>` from an `absl::StatusOr<U>`, when `T`
0234   // is constructible from `U`. To avoid ambiguity, these constructors are
0235   // disabled if `T` is also constructible from `StatusOr<U>.`. This constructor
0236   // is explicit if and only if the corresponding construction of `T` from `U`
0237   // is explicit. (This constructor inherits its explicitness from the
0238   // underlying constructor.)
0239   template <typename U, absl::enable_if_t<
0240                             internal_statusor::IsConstructionFromStatusOrValid<
0241                                 false, T, U, false, const U&>::value,
0242                             int> = 0>
0243   StatusOr(const StatusOr<U>& other)  // NOLINT
0244       : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {}
0245   template <typename U, absl::enable_if_t<
0246                             internal_statusor::IsConstructionFromStatusOrValid<
0247                                 false, T, U, true, const U&>::value,
0248                             int> = 0>
0249   StatusOr(const StatusOr<U>& other ABSL_ATTRIBUTE_LIFETIME_BOUND)  // NOLINT
0250       : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {}
0251   template <typename U, absl::enable_if_t<
0252                             internal_statusor::IsConstructionFromStatusOrValid<
0253                                 true, T, U, false, const U&>::value,
0254                             int> = 0>
0255   explicit StatusOr(const StatusOr<U>& other)
0256       : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {}
0257   template <typename U, absl::enable_if_t<
0258                             internal_statusor::IsConstructionFromStatusOrValid<
0259                                 true, T, U, true, const U&>::value,
0260                             int> = 0>
0261   explicit StatusOr(const StatusOr<U>& other ABSL_ATTRIBUTE_LIFETIME_BOUND)
0262       : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {}
0263 
0264   template <typename U, absl::enable_if_t<
0265                             internal_statusor::IsConstructionFromStatusOrValid<
0266                                 false, T, U, false, U&&>::value,
0267                             int> = 0>
0268   StatusOr(StatusOr<U>&& other)  // NOLINT
0269       : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {}
0270   template <typename U, absl::enable_if_t<
0271                             internal_statusor::IsConstructionFromStatusOrValid<
0272                                 false, T, U, true, U&&>::value,
0273                             int> = 0>
0274   StatusOr(StatusOr<U>&& other ABSL_ATTRIBUTE_LIFETIME_BOUND)  // NOLINT
0275       : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {}
0276   template <typename U, absl::enable_if_t<
0277                             internal_statusor::IsConstructionFromStatusOrValid<
0278                                 true, T, U, false, U&&>::value,
0279                             int> = 0>
0280   explicit StatusOr(StatusOr<U>&& other)
0281       : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {}
0282   template <typename U, absl::enable_if_t<
0283                             internal_statusor::IsConstructionFromStatusOrValid<
0284                                 true, T, U, true, U&&>::value,
0285                             int> = 0>
0286   explicit StatusOr(StatusOr<U>&& other ABSL_ATTRIBUTE_LIFETIME_BOUND)
0287       : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {}
0288 
0289   // Converting Assignment Operators
0290 
0291   // Creates an `absl::StatusOr<T>` through assignment from an
0292   // `absl::StatusOr<U>` when:
0293   //
0294   //   * Both `absl::StatusOr<T>` and `absl::StatusOr<U>` are OK by assigning
0295   //     `U` to `T` directly.
0296   //   * `absl::StatusOr<T>` is OK and `absl::StatusOr<U>` contains an error
0297   //      code by destroying `absl::StatusOr<T>`'s value and assigning from
0298   //      `absl::StatusOr<U>'
0299   //   * `absl::StatusOr<T>` contains an error code and `absl::StatusOr<U>` is
0300   //      OK by directly initializing `T` from `U`.
0301   //   * Both `absl::StatusOr<T>` and `absl::StatusOr<U>` contain an error
0302   //     code by assigning the `Status` in `absl::StatusOr<U>` to
0303   //     `absl::StatusOr<T>`
0304   //
0305   // These overloads only apply if `absl::StatusOr<T>` is constructible and
0306   // assignable from `absl::StatusOr<U>` and `StatusOr<T>` cannot be directly
0307   // assigned from `StatusOr<U>`.
0308   template <typename U,
0309             absl::enable_if_t<internal_statusor::IsStatusOrAssignmentValid<
0310                                   T, const U&, false>::value,
0311                               int> = 0>
0312   StatusOr& operator=(const StatusOr<U>& other) {
0313     this->Assign(other);
0314     return *this;
0315   }
0316   template <typename U,
0317             absl::enable_if_t<internal_statusor::IsStatusOrAssignmentValid<
0318                                   T, const U&, true>::value,
0319                               int> = 0>
0320   StatusOr& operator=(const StatusOr<U>& other ABSL_ATTRIBUTE_LIFETIME_BOUND) {
0321     this->Assign(other);
0322     return *this;
0323   }
0324   template <typename U,
0325             absl::enable_if_t<internal_statusor::IsStatusOrAssignmentValid<
0326                                   T, U&&, false>::value,
0327                               int> = 0>
0328   StatusOr& operator=(StatusOr<U>&& other) {
0329     this->Assign(std::move(other));
0330     return *this;
0331   }
0332   template <typename U,
0333             absl::enable_if_t<internal_statusor::IsStatusOrAssignmentValid<
0334                                   T, U&&, true>::value,
0335                               int> = 0>
0336   StatusOr& operator=(StatusOr<U>&& other ABSL_ATTRIBUTE_LIFETIME_BOUND) {
0337     this->Assign(std::move(other));
0338     return *this;
0339   }
0340 
0341   // Constructs a new `absl::StatusOr<T>` with a non-ok status. After calling
0342   // this constructor, `this->ok()` will be `false` and calls to `value()` will
0343   // crash, or produce an exception if exceptions are enabled.
0344   //
0345   // The constructor also takes any type `U` that is convertible to
0346   // `absl::Status`. This constructor is explicit if an only if `U` is not of
0347   // type `absl::Status` and the conversion from `U` to `Status` is explicit.
0348   //
0349   // REQUIRES: !Status(std::forward<U>(v)).ok(). This requirement is DCHECKed.
0350   // In optimized builds, passing absl::OkStatus() here will have the effect
0351   // of passing absl::StatusCode::kInternal as a fallback.
0352   template <typename U = absl::Status,
0353             absl::enable_if_t<internal_statusor::IsConstructionFromStatusValid<
0354                                   false, T, U>::value,
0355                               int> = 0>
0356   StatusOr(U&& v) : Base(std::forward<U>(v)) {}
0357 
0358   template <typename U = absl::Status,
0359             absl::enable_if_t<internal_statusor::IsConstructionFromStatusValid<
0360                                   true, T, U>::value,
0361                               int> = 0>
0362   explicit StatusOr(U&& v) : Base(std::forward<U>(v)) {}
0363   template <typename U = absl::Status,
0364             absl::enable_if_t<internal_statusor::IsConstructionFromStatusValid<
0365                                   false, T, U>::value,
0366                               int> = 0>
0367   StatusOr& operator=(U&& v) {
0368     this->AssignStatus(std::forward<U>(v));
0369     return *this;
0370   }
0371 
0372   // Perfect-forwarding value assignment operator.
0373 
0374   // If `*this` contains a `T` value before the call, the contained value is
0375   // assigned from `std::forward<U>(v)`; Otherwise, it is directly-initialized
0376   // from `std::forward<U>(v)`.
0377   // This function does not participate in overload unless:
0378   // 1. `std::is_constructible_v<T, U>` is true,
0379   // 2. `std::is_assignable_v<T&, U>` is true.
0380   // 3. `std::is_same_v<StatusOr<T>, std::remove_cvref_t<U>>` is false.
0381   // 4. Assigning `U` to `T` is not ambiguous:
0382   //  If `U` is `StatusOr<V>` and `T` is constructible and assignable from
0383   //  both `StatusOr<V>` and `V`, the assignment is considered bug-prone and
0384   //  ambiguous thus will fail to compile. For example:
0385   //    StatusOr<bool> s1 = true;  // s1.ok() && *s1 == true
0386   //    StatusOr<bool> s2 = false;  // s2.ok() && *s2 == false
0387   //    s1 = s2;  // ambiguous, `s1 = *s2` or `s1 = bool(s2)`?
0388   template <typename U = T,
0389             typename std::enable_if<
0390                 internal_statusor::IsAssignmentValid<T, U, false>::value,
0391                 int>::type = 0>
0392   StatusOr& operator=(U&& v) {
0393     this->Assign(std::forward<U>(v));
0394     return *this;
0395   }
0396   template <typename U = T,
0397             typename std::enable_if<
0398                 internal_statusor::IsAssignmentValid<T, U, true>::value,
0399                 int>::type = 0>
0400   StatusOr& operator=(U&& v ABSL_ATTRIBUTE_LIFETIME_BOUND) {
0401     this->Assign(std::forward<U>(v));
0402     return *this;
0403   }
0404 
0405   // Constructs the inner value `T` in-place using the provided args, using the
0406   // `T(args...)` constructor.
0407   template <typename... Args>
0408   explicit StatusOr(absl::in_place_t, Args&&... args);
0409   template <typename U, typename... Args>
0410   explicit StatusOr(absl::in_place_t, std::initializer_list<U> ilist,
0411                     Args&&... args);
0412 
0413   // Constructs the inner value `T` in-place using the provided args, using the
0414   // `T(U)` (direct-initialization) constructor. This constructor is only valid
0415   // if `T` can be constructed from a `U`. Can accept move or copy constructors.
0416   //
0417   // This constructor is explicit if `U` is not convertible to `T`. To avoid
0418   // ambiguity, this constructor is disabled if `U` is a `StatusOr<J>`, where
0419   // `J` is convertible to `T`.
0420   template <typename U = T,
0421             absl::enable_if_t<internal_statusor::IsConstructionValid<
0422                                   false, T, U, false>::value,
0423                               int> = 0>
0424   StatusOr(U&& u)  // NOLINT
0425       : StatusOr(absl::in_place, std::forward<U>(u)) {}
0426   template <typename U = T,
0427             absl::enable_if_t<internal_statusor::IsConstructionValid<
0428                                   false, T, U, true>::value,
0429                               int> = 0>
0430   StatusOr(U&& u ABSL_ATTRIBUTE_LIFETIME_BOUND)  // NOLINT
0431       : StatusOr(absl::in_place, std::forward<U>(u)) {}
0432 
0433   template <typename U = T,
0434             absl::enable_if_t<internal_statusor::IsConstructionValid<
0435                                   true, T, U, false>::value,
0436                               int> = 0>
0437   explicit StatusOr(U&& u)  // NOLINT
0438       : StatusOr(absl::in_place, std::forward<U>(u)) {}
0439   template <typename U = T,
0440             absl::enable_if_t<
0441                 internal_statusor::IsConstructionValid<true, T, U, true>::value,
0442                 int> = 0>
0443   explicit StatusOr(U&& u ABSL_ATTRIBUTE_LIFETIME_BOUND)  // NOLINT
0444       : StatusOr(absl::in_place, std::forward<U>(u)) {}
0445 
0446   // StatusOr<T>::ok()
0447   //
0448   // Returns whether or not this `absl::StatusOr<T>` holds a `T` value. This
0449   // member function is analogous to `absl::Status::ok()` and should be used
0450   // similarly to check the status of return values.
0451   //
0452   // Example:
0453   //
0454   // StatusOr<Foo> result = DoBigCalculationThatCouldFail();
0455   // if (result.ok()) {
0456   //    // Handle result
0457   // else {
0458   //    // Handle error
0459   // }
0460   ABSL_MUST_USE_RESULT bool ok() const { return this->status_.ok(); }
0461 
0462   // StatusOr<T>::status()
0463   //
0464   // Returns a reference to the current `absl::Status` contained within the
0465   // `absl::StatusOr<T>`. If `absl::StatusOr<T>` contains a `T`, then this
0466   // function returns `absl::OkStatus()`.
0467   const Status& status() const&;
0468   Status status() &&;
0469 
0470   // StatusOr<T>::value()
0471   //
0472   // Returns a reference to the held value if `this->ok()`. Otherwise, throws
0473   // `absl::BadStatusOrAccess` if exceptions are enabled, or is guaranteed to
0474   // terminate the process if exceptions are disabled.
0475   //
0476   // If you have already checked the status using `this->ok()`, you probably
0477   // want to use `operator*()` or `operator->()` to access the value instead of
0478   // `value`.
0479   //
0480   // Note: for value types that are cheap to copy, prefer simple code:
0481   //
0482   //   T value = statusor.value();
0483   //
0484   // Otherwise, if the value type is expensive to copy, but can be left
0485   // in the StatusOr, simply assign to a reference:
0486   //
0487   //   T& value = statusor.value();  // or `const T&`
0488   //
0489   // Otherwise, if the value type supports an efficient move, it can be
0490   // used as follows:
0491   //
0492   //   T value = std::move(statusor).value();
0493   //
0494   // The `std::move` on statusor instead of on the whole expression enables
0495   // warnings about possible uses of the statusor object after the move.
0496   const T& value() const& ABSL_ATTRIBUTE_LIFETIME_BOUND;
0497   T& value() & ABSL_ATTRIBUTE_LIFETIME_BOUND;
0498   const T&& value() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND;
0499   T&& value() && ABSL_ATTRIBUTE_LIFETIME_BOUND;
0500 
0501   // StatusOr<T>:: operator*()
0502   //
0503   // Returns a reference to the current value.
0504   //
0505   // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined.
0506   //
0507   // Use `this->ok()` to verify that there is a current value within the
0508   // `absl::StatusOr<T>`. Alternatively, see the `value()` member function for a
0509   // similar API that guarantees crashing or throwing an exception if there is
0510   // no current value.
0511   const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND;
0512   T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND;
0513   const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND;
0514   T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND;
0515 
0516   // StatusOr<T>::operator->()
0517   //
0518   // Returns a pointer to the current value.
0519   //
0520   // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined.
0521   //
0522   // Use `this->ok()` to verify that there is a current value.
0523   const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0524   T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND;
0525 
0526   // StatusOr<T>::value_or()
0527   //
0528   // Returns the current value if `this->ok() == true`. Otherwise constructs a
0529   // value using the provided `default_value`.
0530   //
0531   // Unlike `value`, this function returns by value, copying the current value
0532   // if necessary. If the value type supports an efficient move, it can be used
0533   // as follows:
0534   //
0535   //   T value = std::move(statusor).value_or(def);
0536   //
0537   // Unlike with `value`, calling `std::move()` on the result of `value_or` will
0538   // still trigger a copy.
0539   template <typename U>
0540   T value_or(U&& default_value) const&;
0541   template <typename U>
0542   T value_or(U&& default_value) &&;
0543 
0544   // StatusOr<T>::IgnoreError()
0545   //
0546   // Ignores any errors. This method does nothing except potentially suppress
0547   // complaints from any tools that are checking that errors are not dropped on
0548   // the floor.
0549   void IgnoreError() const;
0550 
0551   // StatusOr<T>::emplace()
0552   //
0553   // Reconstructs the inner value T in-place using the provided args, using the
0554   // T(args...) constructor. Returns reference to the reconstructed `T`.
0555   template <typename... Args>
0556   T& emplace(Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
0557     if (ok()) {
0558       this->Clear();
0559       this->MakeValue(std::forward<Args>(args)...);
0560     } else {
0561       this->MakeValue(std::forward<Args>(args)...);
0562       this->status_ = absl::OkStatus();
0563     }
0564     return this->data_;
0565   }
0566 
0567   template <
0568       typename U, typename... Args,
0569       absl::enable_if_t<
0570           std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
0571           int> = 0>
0572   T& emplace(std::initializer_list<U> ilist,
0573              Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
0574     if (ok()) {
0575       this->Clear();
0576       this->MakeValue(ilist, std::forward<Args>(args)...);
0577     } else {
0578       this->MakeValue(ilist, std::forward<Args>(args)...);
0579       this->status_ = absl::OkStatus();
0580     }
0581     return this->data_;
0582   }
0583 
0584   // StatusOr<T>::AssignStatus()
0585   //
0586   // Sets the status of `absl::StatusOr<T>` to the given non-ok status value.
0587   //
0588   // NOTE: We recommend using the constructor and `operator=` where possible.
0589   // This method is intended for use in generic programming, to enable setting
0590   // the status of a `StatusOr<T>` when `T` may be `Status`. In that case, the
0591   // constructor and `operator=` would assign into the inner value of type
0592   // `Status`, rather than status of the `StatusOr` (b/280392796).
0593   //
0594   // REQUIRES: !Status(std::forward<U>(v)).ok(). This requirement is DCHECKed.
0595   // In optimized builds, passing absl::OkStatus() here will have the effect
0596   // of passing absl::StatusCode::kInternal as a fallback.
0597   using internal_statusor::StatusOrData<T>::AssignStatus;
0598 
0599  private:
0600   using internal_statusor::StatusOrData<T>::Assign;
0601   template <typename U>
0602   void Assign(const absl::StatusOr<U>& other);
0603   template <typename U>
0604   void Assign(absl::StatusOr<U>&& other);
0605 };
0606 
0607 // operator==()
0608 //
0609 // This operator checks the equality of two `absl::StatusOr<T>` objects.
0610 template <typename T>
0611 bool operator==(const StatusOr<T>& lhs, const StatusOr<T>& rhs) {
0612   if (lhs.ok() && rhs.ok()) return *lhs == *rhs;
0613   return lhs.status() == rhs.status();
0614 }
0615 
0616 // operator!=()
0617 //
0618 // This operator checks the inequality of two `absl::StatusOr<T>` objects.
0619 template <typename T>
0620 bool operator!=(const StatusOr<T>& lhs, const StatusOr<T>& rhs) {
0621   return !(lhs == rhs);
0622 }
0623 
0624 // Prints the `value` or the status in brackets to `os`.
0625 //
0626 // Requires `T` supports `operator<<`.  Do not rely on the output format which
0627 // may change without notice.
0628 template <typename T, typename std::enable_if<
0629                           absl::HasOstreamOperator<T>::value, int>::type = 0>
0630 std::ostream& operator<<(std::ostream& os, const StatusOr<T>& status_or) {
0631   if (status_or.ok()) {
0632     os << status_or.value();
0633   } else {
0634     os << internal_statusor::StringifyRandom::OpenBrackets()
0635        << status_or.status()
0636        << internal_statusor::StringifyRandom::CloseBrackets();
0637   }
0638   return os;
0639 }
0640 
0641 // As above, but supports `StrCat`, `StrFormat`, etc.
0642 //
0643 // Requires `T` has `AbslStringify`.  Do not rely on the output format which
0644 // may change without notice.
0645 template <
0646     typename Sink, typename T,
0647     typename std::enable_if<absl::HasAbslStringify<T>::value, int>::type = 0>
0648 void AbslStringify(Sink& sink, const StatusOr<T>& status_or) {
0649   if (status_or.ok()) {
0650     absl::Format(&sink, "%v", status_or.value());
0651   } else {
0652     absl::Format(&sink, "%s%v%s",
0653                  internal_statusor::StringifyRandom::OpenBrackets(),
0654                  status_or.status(),
0655                  internal_statusor::StringifyRandom::CloseBrackets());
0656   }
0657 }
0658 
0659 //------------------------------------------------------------------------------
0660 // Implementation details for StatusOr<T>
0661 //------------------------------------------------------------------------------
0662 
0663 // TODO(sbenza): avoid the string here completely.
0664 template <typename T>
0665 StatusOr<T>::StatusOr() : Base(Status(absl::StatusCode::kUnknown, "")) {}
0666 
0667 template <typename T>
0668 template <typename U>
0669 inline void StatusOr<T>::Assign(const StatusOr<U>& other) {
0670   if (other.ok()) {
0671     this->Assign(*other);
0672   } else {
0673     this->AssignStatus(other.status());
0674   }
0675 }
0676 
0677 template <typename T>
0678 template <typename U>
0679 inline void StatusOr<T>::Assign(StatusOr<U>&& other) {
0680   if (other.ok()) {
0681     this->Assign(*std::move(other));
0682   } else {
0683     this->AssignStatus(std::move(other).status());
0684   }
0685 }
0686 template <typename T>
0687 template <typename... Args>
0688 StatusOr<T>::StatusOr(absl::in_place_t, Args&&... args)
0689     : Base(absl::in_place, std::forward<Args>(args)...) {}
0690 
0691 template <typename T>
0692 template <typename U, typename... Args>
0693 StatusOr<T>::StatusOr(absl::in_place_t, std::initializer_list<U> ilist,
0694                       Args&&... args)
0695     : Base(absl::in_place, ilist, std::forward<Args>(args)...) {}
0696 
0697 template <typename T>
0698 const Status& StatusOr<T>::status() const& {
0699   return this->status_;
0700 }
0701 template <typename T>
0702 Status StatusOr<T>::status() && {
0703   return ok() ? OkStatus() : std::move(this->status_);
0704 }
0705 
0706 template <typename T>
0707 const T& StatusOr<T>::value() const& {
0708   if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_);
0709   return this->data_;
0710 }
0711 
0712 template <typename T>
0713 T& StatusOr<T>::value() & {
0714   if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_);
0715   return this->data_;
0716 }
0717 
0718 template <typename T>
0719 const T&& StatusOr<T>::value() const&& {
0720   if (!this->ok()) {
0721     internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_));
0722   }
0723   return std::move(this->data_);
0724 }
0725 
0726 template <typename T>
0727 T&& StatusOr<T>::value() && {
0728   if (!this->ok()) {
0729     internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_));
0730   }
0731   return std::move(this->data_);
0732 }
0733 
0734 template <typename T>
0735 const T& StatusOr<T>::operator*() const& {
0736   this->EnsureOk();
0737   return this->data_;
0738 }
0739 
0740 template <typename T>
0741 T& StatusOr<T>::operator*() & {
0742   this->EnsureOk();
0743   return this->data_;
0744 }
0745 
0746 template <typename T>
0747 const T&& StatusOr<T>::operator*() const&& {
0748   this->EnsureOk();
0749   return std::move(this->data_);
0750 }
0751 
0752 template <typename T>
0753 T&& StatusOr<T>::operator*() && {
0754   this->EnsureOk();
0755   return std::move(this->data_);
0756 }
0757 
0758 template <typename T>
0759 absl::Nonnull<const T*> StatusOr<T>::operator->() const {
0760   this->EnsureOk();
0761   return &this->data_;
0762 }
0763 
0764 template <typename T>
0765 absl::Nonnull<T*> StatusOr<T>::operator->() {
0766   this->EnsureOk();
0767   return &this->data_;
0768 }
0769 
0770 template <typename T>
0771 template <typename U>
0772 T StatusOr<T>::value_or(U&& default_value) const& {
0773   if (ok()) {
0774     return this->data_;
0775   }
0776   return std::forward<U>(default_value);
0777 }
0778 
0779 template <typename T>
0780 template <typename U>
0781 T StatusOr<T>::value_or(U&& default_value) && {
0782   if (ok()) {
0783     return std::move(this->data_);
0784   }
0785   return std::forward<U>(default_value);
0786 }
0787 
0788 template <typename T>
0789 void StatusOr<T>::IgnoreError() const {
0790   // no-op
0791 }
0792 
0793 ABSL_NAMESPACE_END
0794 }  // namespace absl
0795 
0796 #endif  // ABSL_STATUS_STATUSOR_H_