Skip to content

Commit df7ac69

Browse files
committed
Address ldionne's comments
1 parent 2000f99 commit df7ac69

File tree

2 files changed

+8
-8
lines changed

2 files changed

+8
-8
lines changed

libcxx/docs/ReleaseNotes/21.rst

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,15 @@ Improvements and New Features
6868
up to 10x, depending on type of sorted elements and the initial state of the sorted array.
6969

7070
- The segmented iterator optimization for ``std::for_each`` has been backported to C++11. Previously it was only available
71-
in C++23 and later.
71+
in C++23 and later.
7272

73-
- The ``std::for_each_n`` algorithm has been optimized for segmented iterators, resulting in a performance improvement of
74-
up to 17.7x for ``std::deque<short>`` iterators, and up to 13.9x for ``std::join_view<vector<vector<short>>>`` iterators.
73+
- The ``std::for_each_n``, ``std::ranges::for_each`` and ``std::ranges::for_each_n`` algorithms have been optimized for
74+
segmented iterators, resulting in a performance improvement of up to 17.7x for ``std::deque<short>`` iterators, and up
75+
to 13.9x for ``std::join_view<vector<vector<short>>>`` iterators.
7576

7677
- The ``bitset::to_string`` function has been optimized, resulting in a performance improvement of up to 8.3x for bitsets
7778
with uniformly distributed zeros and ones, and up to 13.5x and 16.1x for sparse and dense bitsets, respectively.
7879

79-
- The ``std::ranges::for_each`` and ``std::ranges::for_each_n`` algorithms have been optimized for segmented iterators,
80-
resulting in performance improvements of up to 21.3x for ``std::deque::iterator`` and 24.9x for ``join_view`` of
81-
``vector<vector<char>>``.
82-
8380
Deprecations and Removals
8481
-------------------------
8582

libcxx/include/__algorithm/ranges_for_each.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ struct __for_each {
4343
template <class _Iter, class _Sent, class _Proj, class _Func>
4444
_LIBCPP_HIDE_FROM_ABI constexpr static for_each_result<_Iter, _Func>
4545
__for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) {
46-
if constexpr (!std::assignable_from<_Iter&, _Sent> && sized_sentinel_for<_Sent, _Iter>) {
46+
// In the case where we have different iterator and sentinel types, the segmented iterator optimization
47+
// in std::for_each will not kick in. Therefore, we prefer std::for_each_n in that case (whenever we can
48+
// obtain the `n`).
49+
if constexpr (!std::assignable_from<_Iter&, _Sent> && std::sized_sentinel_for<_Sent, _Iter>) {
4750
auto __n = __last - __first;
4851
auto __end = std::__for_each_n(std::move(__first), __n, __func, __proj);
4952
return {std::move(__end), std::move(__func)};

0 commit comments

Comments
 (0)