On Fri, Oct 17, 2025 at 06:34:41PM +0200, Tomasz Kaminski wrote:
> On Fri, Oct 17, 2025 at 6:33 PM Tomasz Kaminski <[email protected]> wrote:
> 
> >
> >
> > On Fri, Oct 17, 2025 at 6:27 PM Hewill Kang <[email protected]> wrote:
> >
> >> I'm not sure what you mean, but it does weird to me that the underlying
> >> types can't be compared, but the corresponding tuple-like can be compared:
> >>
> >> #include <tuple>
> >> #include <array>
> >>
> >> struct S {
> >> void operator== (const S&) const = delete;
> >> void operator<=>(const S&) const = delete;
> >> void operator <(const S&) const = delete;
> >> };
> >>
> >> int main() {
> >> std::tuple<> t;
> >> std::array<S, 0> a;
> >> // a == a; // error
> >> t < a; // ok
> >>
> > Yes, because the < is doing more efficient implementation of:
> >        t < std::tuple<>(a);
> >
> And this constructor alos does not look on a, and it can be non-movable.
> I think this is more a problem of array<S, 0> not being comparable, despite
> being copyable regardless of S.
> 
> >
> >
> >> t == a; // ok
> >> t <=> a; // ok
> >> }
> >>
> >> Tomasz Kaminski <[email protected]> 於 2025年10月18日 週六 上午12:20寫道:
> >>
> >>>
> >>>
> >>> On Fri, Oct 17, 2025 at 6:00 PM Hewill Kang <[email protected]> wrote:
> >>>
> >>>> Wow, I just noticed that the current wording allows tuple<> to be
> >>>> compared to any array<T, 0>, regardless of the type of T.
> >>>> However, tuple<T> can only be compared to array<T, 1> if T itself is
> >>>> comparable.
> >>>>
> >>> They common_reference is tuple<>, but they are not totally_ordered_with,
> >>> as array is not ordered.
> >>>
> >>>> This seems to be a defect.
> >>>>
> >>>> Osama Abdelkader <[email protected]> 於 2025年10月17日 週五
> >>>> 下午11:27寫道:
> >>>>
> >>>>> Fixes #119721
> >>>>>
> >>>>> This fixes a C++23 compliance issue where std::tuple<> cannot be
> >>>>> compared
> >>>>> with std::array<T, 0>. Both are empty tuple-like types and should be
> >>>>> comparable according to the C++23 standard.
> >>>>>
> >>>>> The fix adds the missing comparison operators:
> >>>>> - operator== and operator!= (return true and false respectively)
> >>>>> - operator<, operator<=, operator>, operator>= (follow ordering rules
> >>>>> for empty types)
> >>>>> - operator<=> (returns strong_ordering::equal)
> >>>>>
> >>>>> This resolves the 'rejects-valid' bug where GCC was rejecting valid
> >>>>> C++23 code
> >>>>> that Clang with libc++ already supports correctly.
> >>>>>
> >>>>> libstdc++-v3/ChangeLog:
> >>>>>
> >>>>>         * include/std/tuple: Add comparison operators between tuple<>
> >>>>> and array<T, 0>.
> >>>>>
> >>>>> Signed-off-by: Osama Abdelkader <[email protected]>
> >>>>> ---
> >>>>>  libstdc++-v3/include/std/tuple | 88 ++++++++++++++++++++++++++++++++++
> >>>>>  1 file changed, 88 insertions(+)
> >>>>>
> >>>>> diff --git a/libstdc++-v3/include/std/tuple
> >>>>> b/libstdc++-v3/include/std/tuple
> >>>>> index 0ca616f1b..d3621dd16 100644
> >>>>> --- a/libstdc++-v3/include/std/tuple
> >>>>> +++ b/libstdc++-v3/include/std/tuple
> >>>>> @@ -1880,6 +1880,94 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >>>>>           using _Cat = typename
> >>>>> __tuple_like_common_comparison_category<_UTuple>::type;
> >>>>>           return std::__tuple_cmp<_Cat>(__t, __u,
> >>>>> index_sequence_for<_Elements...>());
> >>>>>         }
> >>>>> +
> >>>>> +  // Comparison operators between tuple<> and array<T, 0>
> >>>>> +  // These are needed because both are empty tuple-like types in C++23
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator==(const tuple<>&, const array<_Tp, 0>&)
> >>>>> +    { return true; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator==(const array<_Tp, 0>&, const tuple<>&)
> >>>>> +    { return true; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator!=(const tuple<>&, const array<_Tp, 0>&)
> >>>>> +    { return false; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator!=(const array<_Tp, 0>&, const tuple<>&)
> >>>>> +    { return false; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator<(const tuple<>&, const array<_Tp, 0>&)
> >>>>> +    { return false; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator<(const array<_Tp, 0>&, const tuple<>&)
> >>>>> +    { return false; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator<=(const tuple<>&, const array<_Tp, 0>&)
> >>>>> +    { return true; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator<=(const array<_Tp, 0>&, const tuple<>&)
> >>>>> +    { return true; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator>(const tuple<>&, const array<_Tp, 0>&)
> >>>>> +    { return false; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator>(const array<_Tp, 0>&, const tuple<>&)
> >>>>> +    { return false; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator>=(const tuple<>&, const array<_Tp, 0>&)
> >>>>> +    { return true; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr bool
> >>>>> +    operator>=(const array<_Tp, 0>&, const tuple<>&)
> >>>>> +    { return true; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr strong_ordering
> >>>>> +    operator<=>(const tuple<>&, const array<_Tp, 0>&)
> >>>>> +    { return strong_ordering::equal; }
> >>>>> +
> >>>>> +  template<typename _Tp>
> >>>>> +    [[nodiscard]]
> >>>>> +    constexpr strong_ordering
> >>>>> +    operator<=>(const array<_Tp, 0>&, const tuple<>&)
> >>>>> +    { return strong_ordering::equal; }
> >>>>> +
> >>>>>  #endif // C++23
> >>>>>
> >>>>>  #else // ! (concepts && consteval)
> >>>>> --
> >>>>> 2.43.0
> >>>>>
> >>>>>

Thanks for the review, I just sent v2 which addresses your feedback,
would appreciate your review there.

Thanks,
Osama

Reply via email to