From: Osama Abdelkader Date: Mon, 20 Oct 2025 15:16:52 +0000 (+0300) Subject: libstdc++: Add comparison operators between tuple<> and array [PR119721] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a4f430006efeb58461402054e29b5ac5bd5ac5b;p=thirdparty%2Fgcc.git libstdc++: Add comparison operators between tuple<> and array [PR119721] This fixes the C++23 compliance issue where std::tuple<> cannot be compared with other empty tuple-like types such as std::array. The operators correctly allow comparison with array even when T is not comparable, because empty tuple-like types don't compare element values. PR libstdc++/119721 libstdc++-v3/ChangeLog: * include/std/tuple (tuple<>::operator==, tuple<>::operator<=>): Define. * testsuite/23_containers/tuple/comparison_operators/119721.cc: New test. Reviewed-by: Jonathan Wakely Reviewed-by: Tomasz KamiƄski Signed-off-by: Osama Abdelkader --- diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 0ca616f1b4f..c064a92df4c 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -1999,6 +1999,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _GLIBCXX20_CONSTEXPR tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { } + +#if __cpp_lib_tuple_like // >= C++23 + // Comparison operators for tuple<> with other empty tuple-like types + template<__tuple_like _UTuple> + requires (!__is_tuple_v<_UTuple> && tuple_size_v<_UTuple> == 0) + [[nodiscard]] + friend constexpr bool + operator==(const tuple&, const _UTuple&) noexcept + { return true; } + + template<__tuple_like _UTuple> + requires (!__is_tuple_v<_UTuple> && tuple_size_v<_UTuple> == 0) + friend constexpr strong_ordering + operator<=>(const tuple&, const _UTuple&) noexcept + { return strong_ordering::equal; } +#endif // C++23 }; #if !(__cpp_concepts && __cpp_consteval && __cpp_conditional_explicit) // !C++20 diff --git a/libstdc++-v3/testsuite/23_containers/tuple/comparison_operators/119721.cc b/libstdc++-v3/testsuite/23_containers/tuple/comparison_operators/119721.cc new file mode 100644 index 00000000000..cad7ca005c4 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/tuple/comparison_operators/119721.cc @@ -0,0 +1,65 @@ +// { dg-do compile { target c++23 } } +// { dg-options "-std=c++23" } + +// Test for PR libstdc++/119721: tuple<> comparison with array + +#include +#include +#include +#include + +constexpr void +test01() +{ + std::tuple<> t; + std::array a; + + // Basic comparison should work + VERIFY( t == a ); + VERIFY( a == t ); + VERIFY( !(t != a) ); + VERIFY( !(a != t) ); + + // Ordering comparisons should be equal + VERIFY( !(t < a) ); + VERIFY( !(t > a) ); + VERIFY( t <= a ); + VERIFY( t >= a ); + VERIFY( !(a < t) ); + VERIFY( !(a > t) ); + VERIFY( a <= t ); + VERIFY( a >= t ); + + // Three-way comparison should return equal + VERIFY( (t <=> a) == std::strong_ordering::equal ); + VERIFY( (a <=> t) == std::strong_ordering::equal ); +} + +constexpr void +test02() +{ + // Test with non-comparable element type + struct NonComparable { + void operator==(const NonComparable&) const = delete; + void operator<=>(const NonComparable&) const = delete; + }; + + std::tuple<> t; + std::array a; + + // Should still work because empty containers don't compare elements + VERIFY( t == a ); + VERIFY( (t <=> a) == std::strong_ordering::equal ); +} + +int main() +{ + auto test_all = [] { + test01(); + test02(); + }; + + test_all(); + static_VERIFY( test_all() ); + return 0; +}