]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Reuse predicates in std::search and std::is_permutation
authorJonathan Wakely <jwakely@redhat.com>
Wed, 10 Sep 2025 09:10:07 +0000 (10:10 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 26 Sep 2025 10:05:59 +0000 (11:05 +0100)
commit1cf6cda0554406f3d3ca641de7c4e360953aeb22
tree23b11c2ba4bbc1bdfd0c0567f902bc7220f5997d
parentb83c2e52a21c1882a149e89e5ab152c09a73fb30
libstdc++: Reuse predicates in std::search and std::is_permutation

Hoist construction of the call wrappers out of the loop when we're
repeatedly creating a call wrapper with the same bound arguments.

We need to be careful about iterators that return proxy references,
because bind1st(pred, *first) could bind a reference to a prvalue proxy
reference returned by *first. That would then be an invalid reference by
the time we invoked the call wrapper.

If we dereference the iterator first and store the result of that on the
stack, then we don't have a prvalue proxy reference, and can bind it (or
the value it refers to) into the call wrapper:

  auto&& val = *first; // lifetime extension
  auto wrapper = bind1st(pred, val);
  for (;;)
    /* use wrapper */;

This ensures that the reference returned from *first outlives the call
wrapper, whether it's a proxy reference or not.

For C++98 compatibility in __search we can use __decltype(expr) instead
of auto&&.

libstdc++-v3/ChangeLog:

* include/bits/stl_algobase.h (__search, __is_permutation):
Reuse predicate instead of creating a new one each time.
* include/bits/stl_algo.h (__is_permutation): Likewise.

Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
libstdc++-v3/include/bits/stl_algo.h
libstdc++-v3/include/bits/stl_algobase.h