Enable `operator==` for `StatusOr` only if the contained type is equality-comparable PiperOrigin-RevId: 774693039 Change-Id: I915ce87aa37094d1596618cf2604d0bd98583218
diff --git a/absl/status/internal/statusor_internal.h b/absl/status/internal/statusor_internal.h index e986611..029fdee 100644 --- a/absl/status/internal/statusor_internal.h +++ b/absl/status/internal/statusor_internal.h
@@ -46,6 +46,16 @@ struct HasConversionOperatorToStatusOr<T, U, decltype(test<T, U>(0))> : std::true_type {}; +// Detects whether `T` is equality-comparable. +template <typename T, typename = void> +struct IsEqualityComparable : std::false_type {}; + +template <typename T> +struct IsEqualityComparable< + T, std::enable_if_t<std::is_convertible< + decltype(std::declval<T>() == std::declval<T>()), + bool>::value>> : std::true_type {}; + // Detects whether `T` is constructible or convertible from `StatusOr<U>`. template <typename T, typename U> using IsConstructibleOrConvertibleFromStatusOr =
diff --git a/absl/status/statusor.h b/absl/status/statusor.h index 6142a2f..25c6288 100644 --- a/absl/status/statusor.h +++ b/absl/status/statusor.h
@@ -607,7 +607,9 @@ // operator==() // // This operator checks the equality of two `absl::StatusOr<T>` objects. -template <typename T> +template <typename T, + std::enable_if_t<internal_statusor::IsEqualityComparable<T>::value, + int> = 0> bool operator==(const StatusOr<T>& lhs, const StatusOr<T>& rhs) { if (lhs.ok() && rhs.ok()) return *lhs == *rhs; return lhs.status() == rhs.status(); @@ -616,7 +618,9 @@ // operator!=() // // This operator checks the inequality of two `absl::StatusOr<T>` objects. -template <typename T> +template <typename T, + std::enable_if_t<internal_statusor::IsEqualityComparable<T>::value, + int> = 0> bool operator!=(const StatusOr<T>& lhs, const StatusOr<T>& rhs) { return !(lhs == rhs); }