From 921d491854e226b4a1b007ac7f0e250ea8663322 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 7 Nov 2024 10:11:33 +0800 Subject: [PATCH] [libc++] Fix `unexpected` heterogeneous comparison Currently, libc++ incorrectly rejects heterogeneous comparison of `unexpected`, because the `operator==` is only a hidden friend of `unexpected<_Err>` but not of `unexpected<_Err2>`. We need to call `error()` member function on `__y`. --- libcxx/include/__expected/unexpected.h | 2 +- .../expected/expected.unexpected/equality.pass.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libcxx/include/__expected/unexpected.h b/libcxx/include/__expected/unexpected.h index c7fe3c52e43114..cf110bcf69a827 100644 --- a/libcxx/include/__expected/unexpected.h +++ b/libcxx/include/__expected/unexpected.h @@ -108,7 +108,7 @@ class unexpected { template _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const unexpected& __x, const unexpected<_Err2>& __y) { - return __x.__unex_ == __y.__unex_; + return __x.__unex_ == __y.error(); } private: diff --git a/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp index 3c29cf97580460..7098ffc22c5dab 100644 --- a/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp +++ b/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp @@ -23,15 +23,28 @@ struct Error{ int i; friend constexpr bool operator==(const Error&, const Error&) = default; + friend constexpr bool operator==(const Error& lhs, int rhs) noexcept { + return lhs.i == rhs; + } }; constexpr bool test() { std::unexpected unex1(Error{2}); std::unexpected unex2(Error{3}); std::unexpected unex3(Error{2}); + assert(unex1 == unex3); assert(unex1 != unex2); assert(unex2 != unex3); + + std::unexpected unex_i1(1); + std::unexpected unex_i2(2); + + assert(unex1 != unex_i1); + assert(unex_i1 != unex1); + assert(unex1 == unex_i2); + assert(unex_i2 == unex1); + return true; }