// { dg-do run { target c++26 } } #include #include struct Obj { int i; constexpr auto operator<=>(const Obj&) const = default; }; template<> struct std::hash { static size_t operator()(Obj const& obj) { return std::hash{}(obj.i); } }; constexpr void test_relops() { std::indirect i1; VERIFY( i1 == i1 ); VERIFY( i1 <= i1 ); VERIFY( i1 >= i1 ); std::indirect i2 = std::move(i1); // make i1 valueless VERIFY( i1 == i1 ); VERIFY( i2 == i2 ); VERIFY( i2 != i1 ); VERIFY( i1 < i2 ); VERIFY( i2 >= i1 ); std::indirect i3 = std::move(i2); // make i2 valueless VERIFY( i2 == i1 ); VERIFY( i2 >= i1 ); VERIFY( i2 <= i1 ); VERIFY( i3 > i2 ); } constexpr void test_comp_with_t() { std::indirect i1; Obj o{2}; VERIFY( i1 != o ); VERIFY( i1 < o ); std::indirect i2(Obj{2}); VERIFY( i2 == o ); VERIFY( i2 <= o ); VERIFY( o <= i2 ); std::indirect i3 = std::move(i2); // make i2 valueless VERIFY( i2 != o ); VERIFY( i2 < o ); } void test_hash() { Obj o{5}; std::indirect i(o); VERIFY( std::hash>{}(i) == std::hash{}(o) ); auto(std::move(i)); // make i valueless (void)std::hash>{}(i); } int main() { test_relops(); test_comp_with_t(); test_hash(); static_assert([] { test_relops(); test_comp_with_t(); return true; }()); }