On Wed, Aug 27, 2025 at 5:07 PM Tomasz Kaminski <tkami...@redhat.com> wrote:
> > > 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. > If you agree with that direction (adding unordered to _Ord), pre-approve the patch here and I will commit it directly. > >> 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. >> >>