diff options
author | Abseil Team <absl-team@google.com> | 2024-03-21 12:02:15 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-03-21 12:03:13 -0700 |
commit | 76f8011beabdaee872b5fde7546e02407b220cb1 (patch) | |
tree | 1715640b80d5af18af2d8da2e0e6d0c5e0707578 /absl/status | |
parent | 5036f0b69ccfaa9f74a7895b50748247a7aee124 (diff) |
Separate out absl::StatusOr constraints into statusor_internal.h
PiperOrigin-RevId: 617920100
Change-Id: I0717560a88d32c067ce26b463b14d0db458b28b6
Diffstat (limited to 'absl/status')
-rw-r--r-- | absl/status/internal/statusor_internal.h | 52 | ||||
-rw-r--r-- | 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<absl::in_place_t, absl::remove_cvref_t<U>>, IsForwardingAssignmentAmbiguous<T, U>>>>; +template <bool Explicit, typename T> +using NegationIf = std::conditional_t<Explicit, absl::negation<T>, T>; + +template <typename T, typename U, bool Explicit> +using IsConstructionValid = absl::conjunction< + IsDirectInitializationValid<T, U&&>, std::is_constructible<T, U&&>, + NegationIf<Explicit, std::is_convertible<U&&, T>>, + absl::disjunction< + std::is_same<T, absl::remove_cvref_t<U>>, + absl::conjunction< + std::conditional_t< + Explicit, + absl::negation<std::is_constructible<absl::Status, U&&>>, + absl::negation<std::is_convertible<U&&, absl::Status>>>, + absl::negation< + internal_statusor::HasConversionOperatorToStatusOr<T, U&&>>>>>; + +template <typename T, typename U> +using IsAssignmentValid = absl::conjunction< + std::is_constructible<T, U&&>, std::is_assignable<T&, U&&>, + absl::disjunction< + std::is_same<T, absl::remove_cvref_t<U>>, + absl::conjunction< + absl::negation<std::is_convertible<U&&, absl::Status>>, + absl::negation<HasConversionOperatorToStatusOr<T, U&&>>>>, + IsForwardingAssignmentValid<T, U&&>>; + +template <typename T, typename U, bool Explicit> +using IsConstructionFromStatusValid = absl::conjunction< + absl::negation<std::is_same<absl::StatusOr<T>, absl::remove_cvref_t<U>>>, + absl::negation<std::is_same<T, absl::remove_cvref_t<U>>>, + absl::negation<std::is_same<absl::in_place_t, absl::remove_cvref_t<U>>>, + NegationIf<Explicit, std::is_convertible<U, absl::Status>>, + std::is_constructible<absl::Status, U>, + absl::negation<HasConversionOperatorToStatusOr<T, U>>>; + +template <typename T, typename U> +using IsStatusAssignmentValid = IsConstructionFromStatusValid<T, U, false>; + +template <typename T, typename U, typename UQ, bool Explicit> +using IsConstructionFromStatusOrValid = absl::conjunction< + absl::negation<std::is_same<T, U>>, std::is_constructible<T, UQ>, + NegationIf<Explicit, std::is_convertible<UQ, T>>, + absl::negation<IsConstructibleOrConvertibleFromStatusOr<T, U>>>; + +template <typename T, typename U> +using IsStatusOrAssignmentValid = absl::conjunction< + absl::negation<std::is_same<T, absl::remove_cvref_t<U>>>, + std::is_constructible<T, U>, std::is_assignable<T, U>, + absl::negation<IsConstructibleOrConvertibleOrAssignableFromStatusOr< + T, absl::remove_cvref_t<U>>>>; + 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<T>, // 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_same<T, U>>, - std::is_constructible<T, const U&>, - std::is_convertible<const U&, T>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> + template <typename U, absl::enable_if_t< + internal_statusor::IsConstructionFromStatusOrValid< + T, U, const U&, false>::value, + int> = 0> StatusOr(const StatusOr<U>& other) // NOLINT : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {} - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, - std::is_constructible<T, const U&>, - absl::negation<std::is_convertible<const U&, T>>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> + template <typename U, absl::enable_if_t< + internal_statusor::IsConstructionFromStatusOrValid< + T, U, const U&, true>::value, + int> = 0> explicit StatusOr(const StatusOr<U>& other) : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {} - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, - std::is_convertible<U&&, T>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> + template <typename U, absl::enable_if_t< + internal_statusor::IsConstructionFromStatusOrValid< + T, U, U&&, false>::value, + int> = 0> StatusOr(StatusOr<U>&& other) // NOLINT : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {} - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, - absl::negation<std::is_convertible<U&&, T>>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> + template <typename U, absl::enable_if_t< + internal_statusor::IsConstructionFromStatusOrValid< + T, U, U&&, true>::value, + int> = 0> explicit StatusOr(StatusOr<U>&& other) : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {} @@ -307,18 +281,10 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // These overloads only apply if `absl::StatusOr<T>` is constructible and // assignable from `absl::StatusOr<U>` and `StatusOr<T>` cannot be directly // assigned from `StatusOr<U>`. - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, - std::is_constructible<T, const U&>, - std::is_assignable<T, const U&>, - absl::negation< - internal_statusor:: - IsConstructibleOrConvertibleOrAssignableFromStatusOr< - T, U>>>::value, - int> = 0> + template <typename U, + absl::enable_if_t<internal_statusor::IsStatusOrAssignmentValid< + T, const U&>::value, + int> = 0> StatusOr& operator=(const StatusOr<U>& other) { this->Assign(other); return *this; @@ -326,14 +292,7 @@ class StatusOr : private internal_statusor::StatusOrData<T>, template < typename U, absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, - std::is_assignable<T, U&&>, - absl::negation< - internal_statusor:: - IsConstructibleOrConvertibleOrAssignableFromStatusOr< - T, U>>>::value, - int> = 0> + internal_statusor::IsStatusOrAssignmentValid<T, U&&>::value, int> = 0> StatusOr& operator=(StatusOr<U>&& other) { this->Assign(std::move(other)); return *this; @@ -350,46 +309,22 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // REQUIRES: !Status(std::forward<U>(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<U&&, absl::Status>, - std::is_constructible<absl::Status, U&&>, - absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>, - absl::negation<std::is_same<absl::decay_t<U>, T>>, - absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>, - absl::negation<internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>::value, - int> = 0> + template <typename U = absl::Status, + absl::enable_if_t<internal_statusor::IsConstructionFromStatusValid< + T, U, false>::value, + int> = 0> StatusOr(U&& v) : Base(std::forward<U>(v)) {} - template < - typename U = absl::Status, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_convertible<U&&, absl::Status>>, - std::is_constructible<absl::Status, U&&>, - absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>, - absl::negation<std::is_same<absl::decay_t<U>, T>>, - absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>, - absl::negation<internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>::value, - int> = 0> + template <typename U = absl::Status, + absl::enable_if_t<internal_statusor::IsConstructionFromStatusValid< + T, U, true>::value, + int> = 0> explicit StatusOr(U&& v) : Base(std::forward<U>(v)) {} template < typename U = absl::Status, - absl::enable_if_t< - absl::conjunction< - std::is_convertible<U&&, absl::Status>, - std::is_constructible<absl::Status, U&&>, - absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>, - absl::negation<std::is_same<absl::decay_t<U>, T>>, - absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>, - absl::negation<internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>::value, - int> = 0> + absl::enable_if_t<internal_statusor::IsStatusAssignmentValid<T, U>::value, + int> = 0> StatusOr& operator=(U&& v) { this->AssignStatus(std::forward<U>(v)); return *this; @@ -411,17 +346,9 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // StatusOr<bool> s1 = true; // s1.ok() && *s1 == true // StatusOr<bool> s2 = false; // s2.ok() && *s2 == false // s1 = s2; // ambiguous, `s1 = *s2` or `s1 = bool(s2)`? - template < - typename U = T, - typename = typename std::enable_if<absl::conjunction< - std::is_constructible<T, U&&>, std::is_assignable<T&, U&&>, - absl::disjunction< - std::is_same<absl::remove_cvref_t<U>, T>, - absl::conjunction< - absl::negation<std::is_convertible<U&&, absl::Status>>, - absl::negation<internal_statusor:: - HasConversionOperatorToStatusOr<T, U&&>>>>, - internal_statusor::IsForwardingAssignmentValid<T, U&&>>::value>::type> + template <typename U = T, + typename = typename std::enable_if< + internal_statusor::IsAssignmentValid<T, U>::value>::type> StatusOr& operator=(U&& v) { this->Assign(std::forward<U>(v)); return *this; @@ -442,38 +369,19 @@ class StatusOr : private internal_statusor::StatusOrData<T>, // This constructor is explicit if `U` is not convertible to `T`. To avoid // ambiguity, this constructor is disabled if `U` is a `StatusOr<J>`, where // `J` is convertible to `T`. - template < - typename U = T, - absl::enable_if_t< - absl::conjunction< - internal_statusor::IsDirectInitializationValid<T, U&&>, - std::is_constructible<T, U&&>, std::is_convertible<U&&, T>, - absl::disjunction< - std::is_same<absl::remove_cvref_t<U>, T>, - absl::conjunction< - absl::negation<std::is_convertible<U&&, absl::Status>>, - absl::negation< - internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>>>::value, - int> = 0> + template <typename U = T, + absl::enable_if_t< + absl::conjunction<internal_statusor::IsConstructionValid< + T, U, false> >::value, + int> = 0> StatusOr(U&& u) // NOLINT : StatusOr(absl::in_place, std::forward<U>(u)) {} - template < - typename U = T, - absl::enable_if_t< - absl::conjunction< - internal_statusor::IsDirectInitializationValid<T, U&&>, - absl::disjunction< - std::is_same<absl::remove_cvref_t<U>, T>, - absl::conjunction< - absl::negation<std::is_constructible<absl::Status, U&&>>, - absl::negation< - internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>>, - std::is_constructible<T, U&&>, - absl::negation<std::is_convertible<U&&, T>>>::value, - int> = 0> + template <typename U = T, + absl::enable_if_t< + absl::conjunction< + internal_statusor::IsConstructionValid<T, U, true> >::value, + int> = 0> explicit StatusOr(U&& u) // NOLINT : StatusOr(absl::in_place, std::forward<U>(u)) {} |