File indexing completed on 2025-01-31 09:33:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
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
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
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
0089
0090
0091
0092
0093
0094
0095
0096 absl::Nonnull<const char*> what() const noexcept override;
0097
0098
0099
0100
0101
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
0113 template <typename T>
0114 #if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
0115
0116
0117 class [[nodiscard]] StatusOr;
0118 #else
0119 class ABSL_MUST_USE_RESULT StatusOr;
0120 #endif
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
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
0204
0205
0206
0207
0208 typedef T value_type;
0209
0210
0211
0212
0213
0214
0215
0216
0217 explicit StatusOr();
0218
0219
0220 StatusOr(const StatusOr&) = default;
0221
0222
0223 StatusOr& operator=(const StatusOr&) = default;
0224
0225
0226 StatusOr(StatusOr&&) = default;
0227
0228
0229 StatusOr& operator=(StatusOr&&) = default;
0230
0231
0232
0233
0234
0235
0236
0237
0238
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)
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)
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)
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)
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
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
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
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
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
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
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
0406
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
0414
0415
0416
0417
0418
0419
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)
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)
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)
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)
0444 : StatusOr(absl::in_place, std::forward<U>(u)) {}
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460 ABSL_MUST_USE_RESULT bool ok() const { return this->status_.ok(); }
0461
0462
0463
0464
0465
0466
0467 const Status& status() const&;
0468 Status status() &&;
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
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
0502
0503
0504
0505
0506
0507
0508
0509
0510
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
0517
0518
0519
0520
0521
0522
0523 const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0524 T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND;
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
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
0545
0546
0547
0548
0549 void IgnoreError() const;
0550
0551
0552
0553
0554
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
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
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
0608
0609
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
0617
0618
0619 template <typename T>
0620 bool operator!=(const StatusOr<T>& lhs, const StatusOr<T>& rhs) {
0621 return !(lhs == rhs);
0622 }
0623
0624
0625
0626
0627
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
0642
0643
0644
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
0661
0662
0663
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
0791 }
0792
0793 ABSL_NAMESPACE_END
0794 }
0795
0796 #endif