On Wed, Aug 27, 2025 at 5:00 PM Jonathan Wakely <jwak...@redhat.com> wrote:

> On Wed, 27 Aug 2025 at 15:03, Patrick Palka <ppa...@redhat.com> wrote:
> >
> > On Wed, 27 Aug 2025, Jonathan Wakely wrote:
> >
> > > On Wed, 27 Aug 2025 at 11:05, Tomasz Kamiński <tkami...@redhat.com>
> wrote:
> > > >
> > > > For any minimum value of a signed type, its negation (with
> wraparound) results
> > > > in the same value, behaving like zero. Representing the unordered
> result with
> > > > this minimum value, along with 0 for equal, 1 for greater, and -1
> for less
> > > > in partial_ordering, allows its value to be reversed using unary
> negation.
> > > >
> > > > The operator<=(partial_order, 0) now checks if the reversed value is
> positive.
> > > > This works correctly because the unordered value remains unchanged
> and thus
> > > > negative.
> > > >
> > > > libstdc++-v3/ChangeLog:
> > > >
> > > >         * libsupc++/compare (_Ncmp::_Unordered): Rename and change
> the value
> > > >         to minimum value of signed char.
> > > >         (_Ncomp::unordered): Renamed from _Unordered, the name is
> reserved
> > > >         by partial_ordered::unordered.
> > > >         (partial_ordering::_M_reverse()): Define.
> > > >         (operator<=(partial_ordering, __cmp_cat::__unspec))
> > > >         (operator>=(__cmp_cat::__unspec, partial_ordering)):
> Implemented
> > > >         in terms of negated _M_value.
> > > >         (operator>=(partial_ordering, __cmp_cat::__unspec))
> > > >         (operator<=(__cmp_cat::__unspec, partial_ordering)): Directly
> > > >         compare _M_value, as unordered value is negative.
> > > >         (partial_ordering::unordered): Handle _Ncmp::unoredred
> rename.
> > > > ---
> > > > Changes in v3:
> > > > * rename and simplify defintion of _Ncmp::unordered
> > >
> > > Ah yes, we don't need to use an _Ugly name name for unordered.
> >
> > FWIW it wasn't 100% obvious to me that renaming _Unordered to unordered
> > is safe here, but it does seem to be, since AFAICT there's no way for a
> > user to refer to the enumeration __cmp_cat::_Ncmp (e.g. via decltype).
> >
> > Otherwise it'd potentially be an observable change:
> >
> >     struct A {
> >       using enum decltype(some-expr-of-type-__cmp_cat::_Ncmp);
> >       int unordered; // now errors due to conflict with _Ncmp::unordered
> >     };
>
> Yeah, that type should never be exposed from any public API, so they
> need to refer to __cmp_cat::_Ncmp directly, which would obviously mean
> they're asking to get hurt and they get what they asked for.
>
> I suppose they could use reflection to inspect the parameters of the
> partial_ordering constructor, but that also seems to be a
> self-inflicted wound.
>
> However, do we really need the _Ncmp type and unordered enumerator at all?!
>
> We could just define the unordered constant like this:
>
>   inline constexpr partial_ordering
>   partial_ordering::unordered(__cmp_cat::_Ord{ -__SCHAR_MAX__ - 1 });
>
At that point we could put an unordered enumerator into _Ord enum as well,
which would be my preferred approach. I still think having a list of all
used
in one place have benefits.

>
> That would allow us to remove the _Ncmp type and the corresponding
> partial_ordering constructor.
>
> I think that could be just as clear and expressive as using
> _Ncmp::unordered, if we add a a suitable comment on the definition of
> the constant explaining that we use the most negative value for the
> unordered case.
>
>

Reply via email to