// { dg-do compile { target c++26 } } #include #ifndef __cpp_lib_reference_wrapper # error "Feature-test macro for reference_wrapper missing" #elif __cpp_lib_reference_wrapper != 202403 # error "Feature-test macro for reference_wrapper has wrong value" #endif // P2944R3 Comparisons for reference_wrapper auto check(int i, std::reference_wrapper r) -> bool { return i == r; } template using Ref = std::reference_wrapper; template concept ref_equality_comparable = requires (T a, T const ca, Ref r, Ref cr) { // the usual T is equality-comparable with itself a == a; a == ca; ca == ca; // Ref is equality-comparable with itself r == r; r == cr; cr == cr; // T and Ref are equality-comparable a == r; a == cr; ca == r; ca == cr; }; static_assert( ref_equality_comparable ); struct A { auto operator==(A const&) const -> bool { return true; } }; struct B { friend auto operator==(B const&, B const&) -> bool { return true; } }; template struct C { friend auto operator==(C const&, C const&) -> bool { return true; } }; template struct D { }; template auto operator==(D const&, D const&) -> bool { return true; } static_assert(ref_equality_comparable); static_assert(ref_equality_comparable); static_assert(ref_equality_comparable); static_assert(ref_equality_comparable>); static_assert(ref_equality_comparable>); #include static_assert(ref_equality_comparable); template struct ValArray { friend auto operator==(ValArray const&, ValArray const&) -> ValArray { return {}; } }; void f(ValArray v) { // this is valid and has type ValArray v == v; // this is also valid today and has the same type std::ref(v) == std::ref(v); } struct ComparesAsInt { friend auto operator==(ComparesAsInt, ComparesAsInt) -> int; }; auto f(std::reference_wrapper a, std::reference_wrapper b) { // today: compiles and returns int // proposed: compiles and returns bool return a == b; } ComparesAsInt& c(); static_assert( std::is_same_v );