[PATCH][V2] Reimplement __gnu_cxx::__ops operators
Jonathan Wakely
jwakely@redhat.com
Thu Sep 11 09:34:43 GMT 2025
On Thu, 11 Sept 2025 at 06:16, François Dumont <frs.dumont@gmail.com> wrote:
>
>
> On 9/9/25 01:52, Jonathan Wakely wrote:
> > On Mon, 8 Sept 2025 at 21:06, Jonathan Wakely <jwakely@redhat.com> wrote:
> >> On Mon, 8 Sept 2025 at 20:59, François Dumont <frs.dumont@gmail.com> wrote:
> >>> This is V2 of this patch. Main diff with initial version is that I
> >>> restored the copy of functors in C++98.
> >>>
> >>> I'm all ears for a new name for the _GLIBCXX_CP_FWDREF macros.
> >> Great, I was going to ask you about the status of this patch. I'll
> >> take a look ASAP.
> > It seems to be three changes all bundled together into one patch,
> > replacing the __iter_comp_iter wrappers, reducing the number of copies
> > of functors, and changing lower_bound/upper_bound internals to work
> > with non-const values.
> >
> > The first two changes are good, but should be separate commits, and I
> > don't think the third is needed.
>
> The third is minor indeed, it's yet another attempt to reduce constraint
> on functor arguments const qualifications.
Is it needed though?
> You initially were concern by my patch imposing functors' operator() to
> be const qualified so I thought it mattered also here.
Yes, but then later somebody reminded me about
https://cplusplus.github.io/LWG/issue3031 which clarified that we
don't need to support that.
See https://bugs.llvm.org/show_bug.cgi?id=35235#c1 which specifically
points out that functions like stable_sort need to call lower_bound
with a value obtained from *iter, and lower_bound takes a const
reference for the value. There is no need to provide a non-standard
internal version of lower_bound that takes non-const values. If we did
that, we would give different results for std::sort(first, last, cmp1)
and std::sort(first, last, cmp2) in cases like the "truly awful
example" in LWG 3031, where you get a different ordering depending on
whether you look at a Derived& or a const Derived&. I don't think it
would be an improvement to change our algorithms to add *more* ways
that sorting can be unpredictable.
> > My approach for the first change seems simpler:
> > https://forge.sourceware.org/gcc/gcc-TEST/compare/trunk...redi:remove-predefined-ops
> >
> Indeed, good idea to reuse Standard libs bits for the >= C++11 mode.
>
> Do you plan to submit it and open a PR soon ?
>
> Just 1 remark, despite being in __gnu_cxx::__ops namespace shouldn't
> 'less' or 'equal_to' names be uglyfied ?
>
> I better focus on the second part then, I'll split it.
Tomasz has convinced me that passing functors by reference internally
is a bad idea. For a stateful functor that contains something like an
integer or a pointer (e.g. a lambda with captured values, or just a
trivially-copyable struct with a non-static data member) passing it by
reference adds another indirection when invoking the functor. If we
pass by value, then it's just a simple copy that can be passed in a
register, and then invoking it is cheap.
For heavyweight functors that are not cheap to copy, users can pass
them into the algorithm with std::ref(cmp) if they need to avoid
copies.
More information about the Libstdc++
mailing list