Coverage Report

Created: 2026-05-30 06:23

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