[libcxx-commits] [libcxx] [libc++] Optimize ranges::{for_each, for_each_n} for segmented iterators (PR #132896)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Mar 27 06:40:46 PDT 2025
================
----------------
ldionne wrote:
For `std::for_each_n`, is there a reason you don't simply do the following?
```c++
template <class _InputIterator,
class _Size,
class _Function,
__enable_if_t<!__is_random_access_iterator<_InputIterator>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) {
// existing loop with counter
}
template <class _RandomAccessIterator,
class _Size,
class _Function,
__enable_if_t<__is_random_access_iterator<_RandomAccessIterator>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
for_each_n(_RandomAccessIterator __first, _Size __orig_n, _Function __f) {
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
_IntegralSize __n = __orig_n;
return std::for_each(__first, __first + __n, std::move(__f));
}
```
That way we dispatch to `std::for_each` in more cases, which covers the segmented iterator optimization you're introducing now but also potentially future optimizations.
Note that this formulation does mean that we lose the optimization for a non random-access segmented sequence, like `join_view`. However, today this optimization is happening at the cost of an additional traversal of the whole sequence, which is not clear to me is worth it. If you have a benchmark on a `join_view`, I'd be curious to see it.
https://github.com/llvm/llvm-project/pull/132896
More information about the libcxx-commits
mailing list