Files
gcc/libstdc++-v3/include/bits
Patrick Palka 1d29b68562 libstdc++: Implement P2408R5 C++20 iterators as inputs to STL algos
From the paper's abstract:

  Change the iterator requirements for non-Ranges algorithms. For
  forward iterators and above that are constant iterators, instead of
  requiring that iterators meet certain Cpp17...Iterator requirements,
  require that the iterators model certain iterator concepts. This makes
  iterators from several standard views usable with non-Ranges
  algorithms that require forward iterators or above, such as the
  parallel overloads of most algorithms.

This patch narrowly implements P2408R5 in C++23 mode and C++20 mode
(as an extension).  "Narrowly" because just as in the paper, we don't
attempt to relax the requirements of mutable iterators even though it's
possible in theory.  Note that the PSTL algorithm requirements have
already been relaxed in r15-3650.  And we don't bother touching the
deprecated parallel mode algorithms under ./include/parallel.

The main workhorse of this paper is a new helper
__iterator_concept_or_category that replaces eligible uses of
__iterator_category and iterator_traits::iterator_category.  This new
helper considers both the iterator_concept and iterator_category of the
given iterator and returns the former if it's at least as strong as the
latter.  It's implemented in terms of the __promotable_iterator concept
added in r16-2588 that made std::advance etc aware of C++20 iterators.
Note that this helper doesn't check the actual C++20 iterator concepts
(which check syntactic requirements along with iterator_concept if it's
defined) and instead just checks for, and fully trusts, the
iterator_concept defined by the iterator type.  This is a slight
deviation from the paper but IMHO it's consistent with the existing
trusting of iterator_category and should be good enough in practice,
though it means C++20 iterators that don't define iterator_concept will
not be recognized as such by this helper even if they otherwise model
the std::foo_iterator concept.  (An undefined iterator_concept
effectively defaults to random_access_iterator_tag.)

Most of the changes made here are effectively optimizations that don't
have a semantic impact, e.g. for std::reduce.  I added tests for a
couple of algorithms where these changes are observable.

The new __iterator_concept_or_category helper can probably also be used
to fix PR100070 "Standard library container iterator-pair constructors
should check C++20 iterator concepts".

As a follow-up to this patch we should either remove the Boost-style
concept checks, or relax them accordingly.  It seems we're leaning
towards removing them outright; see this thread:
https://gcc.gnu.org/pipermail/libstdc++/2025-May/061568.html

As suggested by Tomasz, this patch also introduces a _GLIBCXX_ITER_MOVE
wrapper around ranges::iter_move that also converts to the iterator's
value type (and is usable before C++20 as well).

	PR libstdc++/113299

libstdc++-v3/ChangeLog:

	* include/bits/deque.tcc (__copy_move_a1): Constrain with
	__is_any_random_access_iter instead of __is_random_access_iter.
	(__copy_move_backward_a1): Likewise.
	(__equal_aux1): Likewise.
	* include/bits/stl_algo.h (__search_n): Use
	__iter_concept_or_category instead of __iterator_category
	or iterator_traits::iterator_category.
	(find_end): Likewise.
	(__is_permutation): Likewise.
	(for_each_n): Likewise.
	(unique_copy): Likewise, for constant iterators.
	(sample): Likewise, for constant iterators.
	* include/bits/stl_algobase.h (__copy_move_a1): Adjust
	deque-based forward declaration accordingly.
	(__copy_move_backward_a1): Likewise.
	(__equal_aux1): Likewise.
	(__lexicographical_compare_impl): Use
	__iter_concept_or_category instead of __iterator_category or
	iterator_traits::iterator_category.
	(__equal4): Likewise.
	* include/bits/stl_iterator_base_funcs.h
	(__iter_concept_or_category): New.
	(__is_any_random_access_iter): New.
	(_GLIBCXX_ITER_MOVE): New.
	* include/bits/stl_uninitialized.h (uninitialized_copy_n):
	Use __iterator_concept_or_category instead of
	__iterator_category for the constant iterator __first.
	(__uninitialized_copy_n_pair): Likewise.
	* include/bits/version.def (algorithm_iterator_requirements):
	Define.
	* include/bits/version.h: Regenerate.
	* include/std/algorithm: Provide the FTM
	__cpp_lib_algorithm_iterator_requirements.
	* include/std/memory: Likewise.
	* include/std/numeric: Likewise.  Include
	<bits/stl_iterator_base_funcs.h>.
	(reduce): Use __is_any_random_access_iter instead of
	__is_random_access_iter.
	(transform_reduce): Likewise.
	(inclusive_scan): Use _GLIBCXX_ITER_MOVE instead of std::move.
	* testsuite/25_algorithms/find_end/c++20_iter.cc: New test.
	* testsuite/25_algorithms/sample/c++20_iter.cc: New test.
	* testsuite/25_algorithms/search_n/c++20_iter.cc: New test.
	* testsuite/25_algorithms/unique_copy/c++20_iter.cc: New test.
	* testsuite/26_numerics/inclusive_scan/c++20_iter.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-12-16 11:22:58 -05:00
..
2025-11-03 21:32:25 +03:00
2025-10-08 18:02:39 +02:00