From 76f8011beabdaee872b5fde7546e02407b220cb1 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 21 Mar 2024 12:02:15 -0700 Subject: Separate out absl::StatusOr constraints into statusor_internal.h PiperOrigin-RevId: 617920100 Change-Id: I0717560a88d32c067ce26b463b14d0db458b28b6 --- absl/status/internal/statusor_internal.h | 52 +++++++++ absl/status/statusor.h | 180 ++++++++----------------------- 2 files changed, 96 insertions(+), 136 deletions(-) diff --git a/absl/status/internal/statusor_internal.h b/absl/status/internal/statusor_internal.h index 5be94903..1afd3179 100644 --- a/absl/status/internal/statusor_internal.h +++ b/absl/status/internal/statusor_internal.h @@ -123,6 +123,58 @@ using IsForwardingAssignmentValid = absl::disjunction< std::is_same>, IsForwardingAssignmentAmbiguous>>>; +template +using NegationIf = std::conditional_t, T>; + +template +using IsConstructionValid = absl::conjunction< + IsDirectInitializationValid, std::is_constructible, + NegationIf>, + absl::disjunction< + std::is_same>, + absl::conjunction< + std::conditional_t< + Explicit, + absl::negation>, + absl::negation>>, + absl::negation< + internal_statusor::HasConversionOperatorToStatusOr>>>>; + +template +using IsAssignmentValid = absl::conjunction< + std::is_constructible, std::is_assignable, + absl::disjunction< + std::is_same>, + absl::conjunction< + absl::negation>, + absl::negation>>>, + IsForwardingAssignmentValid>; + +template +using IsConstructionFromStatusValid = absl::conjunction< + absl::negation, absl::remove_cvref_t>>, + absl::negation>>, + absl::negation>>, + NegationIf>, + std::is_constructible, + absl::negation>>; + +template +using IsStatusAssignmentValid = IsConstructionFromStatusValid; + +template +using IsConstructionFromStatusOrValid = absl::conjunction< + absl::negation>, std::is_constructible, + NegationIf>, + absl::negation>>; + +template +using IsStatusOrAssignmentValid = absl::conjunction< + absl::negation>>, + std::is_constructible, std::is_assignable, + absl::negation>>>; + class Helper { public: // Move type-agnostic error handling to the .cc. diff --git a/absl/status/statusor.h b/absl/status/statusor.h index cd35e5b4..0ed986dc 100644 --- a/absl/status/statusor.h +++ b/absl/status/statusor.h @@ -236,55 +236,29 @@ class StatusOr : private internal_statusor::StatusOrData, // is explicit if and only if the corresponding construction of `T` from `U` // is explicit. (This constructor inherits its explicitness from the // underlying constructor.) - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation>, - std::is_constructible, - std::is_convertible, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> + template ::value, + int> = 0> StatusOr(const StatusOr& other) // NOLINT : Base(static_cast::Base&>(other)) {} - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation>, - std::is_constructible, - absl::negation>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> + template ::value, + int> = 0> explicit StatusOr(const StatusOr& other) : Base(static_cast::Base&>(other)) {} - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation>, std::is_constructible, - std::is_convertible, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> + template ::value, + int> = 0> StatusOr(StatusOr&& other) // NOLINT : Base(static_cast::Base&&>(other)) {} - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation>, std::is_constructible, - absl::negation>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> + template ::value, + int> = 0> explicit StatusOr(StatusOr&& other) : Base(static_cast::Base&&>(other)) {} @@ -307,18 +281,10 @@ class StatusOr : private internal_statusor::StatusOrData, // These overloads only apply if `absl::StatusOr` is constructible and // assignable from `absl::StatusOr` and `StatusOr` cannot be directly // assigned from `StatusOr`. - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation>, - std::is_constructible, - std::is_assignable, - absl::negation< - internal_statusor:: - IsConstructibleOrConvertibleOrAssignableFromStatusOr< - T, U>>>::value, - int> = 0> + template ::value, + int> = 0> StatusOr& operator=(const StatusOr& other) { this->Assign(other); return *this; @@ -326,14 +292,7 @@ class StatusOr : private internal_statusor::StatusOrData, template < typename U, absl::enable_if_t< - absl::conjunction< - absl::negation>, std::is_constructible, - std::is_assignable, - absl::negation< - internal_statusor:: - IsConstructibleOrConvertibleOrAssignableFromStatusOr< - T, U>>>::value, - int> = 0> + internal_statusor::IsStatusOrAssignmentValid::value, int> = 0> StatusOr& operator=(StatusOr&& other) { this->Assign(std::move(other)); return *this; @@ -350,46 +309,22 @@ class StatusOr : private internal_statusor::StatusOrData, // 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. - template < - typename U = absl::Status, - absl::enable_if_t< - absl::conjunction< - std::is_convertible, - std::is_constructible, - absl::negation, absl::StatusOr>>, - absl::negation, T>>, - absl::negation, absl::in_place_t>>, - absl::negation>>::value, - int> = 0> + template ::value, + int> = 0> StatusOr(U&& v) : Base(std::forward(v)) {} - template < - typename U = absl::Status, - absl::enable_if_t< - absl::conjunction< - absl::negation>, - std::is_constructible, - absl::negation, absl::StatusOr>>, - absl::negation, T>>, - absl::negation, absl::in_place_t>>, - absl::negation>>::value, - int> = 0> + template ::value, + int> = 0> explicit StatusOr(U&& v) : Base(std::forward(v)) {} template < typename U = absl::Status, - absl::enable_if_t< - absl::conjunction< - std::is_convertible, - std::is_constructible, - absl::negation, absl::StatusOr>>, - absl::negation, T>>, - absl::negation, absl::in_place_t>>, - absl::negation>>::value, - int> = 0> + absl::enable_if_t::value, + int> = 0> StatusOr& operator=(U&& v) { this->AssignStatus(std::forward(v)); return *this; @@ -411,17 +346,9 @@ class StatusOr : private internal_statusor::StatusOrData, // StatusOr s1 = true; // s1.ok() && *s1 == true // StatusOr s2 = false; // s2.ok() && *s2 == false // s1 = s2; // ambiguous, `s1 = *s2` or `s1 = bool(s2)`? - template < - typename U = T, - typename = typename std::enable_if, std::is_assignable, - absl::disjunction< - std::is_same, T>, - absl::conjunction< - absl::negation>, - absl::negation>>>, - internal_statusor::IsForwardingAssignmentValid>::value>::type> + template ::value>::type> StatusOr& operator=(U&& v) { this->Assign(std::forward(v)); return *this; @@ -442,38 +369,19 @@ class StatusOr : private internal_statusor::StatusOrData, // This constructor is explicit if `U` is not convertible to `T`. To avoid // ambiguity, this constructor is disabled if `U` is a `StatusOr`, where // `J` is convertible to `T`. - template < - typename U = T, - absl::enable_if_t< - absl::conjunction< - internal_statusor::IsDirectInitializationValid, - std::is_constructible, std::is_convertible, - absl::disjunction< - std::is_same, T>, - absl::conjunction< - absl::negation>, - absl::negation< - internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>>>::value, - int> = 0> + template >::value, + int> = 0> StatusOr(U&& u) // NOLINT : StatusOr(absl::in_place, std::forward(u)) {} - template < - typename U = T, - absl::enable_if_t< - absl::conjunction< - internal_statusor::IsDirectInitializationValid, - absl::disjunction< - std::is_same, T>, - absl::conjunction< - absl::negation>, - absl::negation< - internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>>, - std::is_constructible, - absl::negation>>::value, - int> = 0> + template >::value, + int> = 0> explicit StatusOr(U&& u) // NOLINT : StatusOr(absl::in_place, std::forward(u)) {} -- cgit v1.2.3