On 9 March 2018 at 00:41, Jonathan Wakely wrote: > In order to meet the total order requirements of [comparisons] p2 we > need to cast unrelated pointers to uintptr_t before comparing them. > Those casts aren't allowed in constant expressions, so only cast > when __builtin_constant_p says the result of the comparison is not a > compile-time constant (because the arguments are not constants, or the > result of the comparison is unspecified). When the result is constant > just compare the pointers directly without casting. > > This ensures that the function can be called in constant expressions > with suitable arguments, but still yields a total order even for > otherwise unspecified pointer comparisons. > > PR libstdc++/78420 > * include/bits/stl_function.h (__ptr_rel_ops): New struct providing > relational operators defining total order on pointers. > (greater<_Tp*>, less<_Tp*>, greater_equal<_Tp*>, less_equal<_Tp>*): > New partial specializations for pointers, using __ptr_rel_ops. > (greater, less, greater_equal, less_equal Dispatch to __ptr_rel_ops when both arguments are pointers. > * testsuite/20_util/function_objects/comparisons_pointer.cc: New. > > Tested powerpc64le-linux. I intend to commit this to trunk and > backport to the active branches, unless anybody sees a problem with > this solution, or has any suggestions for improvement. I intentionally used "_Tp* const&" for the parameter types of the new partial specializations like greater<_Tp*>, because that's what the standard says for the primary templates. But it would be more efficient to pass pointers by value, and 20.5.5.5 [member.functions] p2 allows us to do that. Here's a new patch with that change.