From b2abe7ad28fd79cbb889dbf9814292be495f04ed Mon Sep 17 00:00:00 2001 From: Dino Radakovic Date: Thu, 4 May 2023 12:37:11 -0700 Subject: Make `absl::StatusOr::AssignStatus` public. Recommend against using it outside of generic programming PiperOrigin-RevId: 529484669 Change-Id: I9889a9f7a7fa7dc6ef8c731f1b583a74e6afd2cf --- absl/status/statusor.h | 15 +++++++++++++++ absl/status/statusor_test.cc | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/absl/status/statusor.h b/absl/status/statusor.h index beedd795..f1932238 100644 --- a/absl/status/statusor.h +++ b/absl/status/statusor.h @@ -612,6 +612,21 @@ class StatusOr : private internal_statusor::StatusOrData, return this->data_; } + // StatusOr::AssignStatus() + // + // Sets the status of `absl::StatusOr` to the given non-ok status value. + // + // NOTE: We recommend using the constructor and `operator=` where possible. + // This method is intended for use in generic programming, to enable setting + // the status of a `StatusOr` when `T` may be `Status`. In that case, the + // constructor and `operator=` would assign into the inner value of type + // `Status`, rather than status of the `StatusOr` (b/280392796). + // + // REQUIRES: !Status(std::forward(v)).ok(). This requirement is DCHECKed. + // In optimized builds, passing absl::OkStatus() here will have the effect + // of passing absl::StatusCode::kInternal as a fallback. + using internal_statusor::StatusOrData::AssignStatus; + private: using internal_statusor::StatusOrData::Assign; template diff --git a/absl/status/statusor_test.cc b/absl/status/statusor_test.cc index 29021543..e65f5d27 100644 --- a/absl/status/statusor_test.cc +++ b/absl/status/statusor_test.cc @@ -1844,4 +1844,37 @@ TEST(StatusOr, AssignmentFromTypeConvertibleToStatus) { } } +TEST(StatusOr, StatusAssignmentFromStatusError) { + absl::StatusOr statusor; + statusor.AssignStatus(absl::CancelledError()); + + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), absl::CancelledError()); +} + +#if GTEST_HAS_DEATH_TEST +TEST(StatusOr, StatusAssignmentFromStatusOk) { + EXPECT_DEBUG_DEATH( + { + absl::StatusOr statusor; + // This will DCHECK. + statusor.AssignStatus(absl::OkStatus()); + // In optimized mode, we are actually going to get error::INTERNAL for + // status here, rather than crashing, so check that. + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status().code(), absl::StatusCode::kInternal); + }, + "An OK status is not a valid constructor argument to StatusOr"); +} +#endif + +TEST(StatusOr, StatusAssignmentFromTypeConvertibleToStatus) { + CustomType v; + absl::StatusOr statusor; + statusor.AssignStatus(v); + + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), static_cast(v)); +} + } // namespace -- cgit v1.2.3