From 962695a02114a3355b5a31727936008d866f53f8 Mon Sep 17 00:00:00 2001 From: c8ef Date: Sat, 11 Oct 2025 23:22:15 +0800 Subject: [PATCH 01/17] [libcxx] Optimize std::generate for segmented iterators --- libcxx/include/__algorithm/generate.h | 27 +++++++++++++++++-- .../alg.generate/generate.pass.cpp | 11 ++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index c95b527402f5d..91e2ada7daf77 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -9,7 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_GENERATE_H #define _LIBCPP___ALGORITHM_GENERATE_H +#include <__algorithm/for_each_segment.h> #include <__config> +#include <__iterator/segmented_iterator.h> +#include <__type_traits/enable_if.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -17,13 +20,33 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template +template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void -generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { +__generate(_ForwardIterator __first, _Sent __last, _Generator __gen) { for (; __first != __last; ++__first) *__first = __gen(); } +#ifndef _LIBCPP_CXX03_LANG +template , int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_SegmentedIterator __generate(_SegmentedIterator __first, _SegmentedIterator __last, _Generator& __gen) { + using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator; + std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) { + std::__generate(__lfirst, __llast, __gen); + }); + return __last; +} +#endif // !_LIBCPP_CXX03_LANG + +template +inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { + std::__generate(__first, __last, __gen); +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___ALGORITHM_GENERATE_H diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp index 29d32d7156742..4591d7ece4645 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "test_macros.h" #include "test_iterators.h" @@ -51,12 +52,22 @@ test() assert(ia[3] == 1); } +void deque_test() { + int sizes[] = {0, 1, 2, 1023, 1024, 1025, 2047, 2048, 2049}; + for (const int size : sizes) { + std::deque d(size); + std::generate(d.begin(), d.end(), gen_test()); + assert(std::all_of(d.begin(), d.end(), [](int x) { return x == 1; })); + } +} + int main(int, char**) { test >(); test >(); test >(); test(); + deque_test(); #if TEST_STD_VER > 17 static_assert(test_constexpr()); From 2f00429ee9d178e6a27cf94fbafb213a735b752b Mon Sep 17 00:00:00 2001 From: c8ef Date: Sat, 11 Oct 2025 23:56:28 +0800 Subject: [PATCH 02/17] fix copy ci --- .../algorithms/robust_against_copying_comparators.pass.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp b/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp index 256251686bb3e..7a3b17b8a6246 100644 --- a/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp +++ b/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp @@ -149,7 +149,8 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() { assert(copies == 0); #endif (void)std::generate(first, last, NullaryValue(&copies)); - assert(copies == 0); + assert(copies == 1); + copies = 0; (void)std::generate_n(first, count, NullaryValue(&copies)); assert(copies == 0); (void)std::includes(first, last, first2, last2, Less(&copies)); From 252611080c81a2e0d5489b80f48176e10b7ac62d Mon Sep 17 00:00:00 2001 From: c8ef Date: Sun, 12 Oct 2025 00:00:44 +0800 Subject: [PATCH 03/17] fix missing & --- libcxx/include/__algorithm/generate.h | 2 +- .../algorithms/robust_against_copying_comparators.pass.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 91e2ada7daf77..188f10111d454 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void -__generate(_ForwardIterator __first, _Sent __last, _Generator __gen) { +__generate(_ForwardIterator __first, _Sent __last, _Generator& __gen) { for (; __first != __last; ++__first) *__first = __gen(); } diff --git a/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp b/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp index 7a3b17b8a6246..256251686bb3e 100644 --- a/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp +++ b/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp @@ -149,8 +149,7 @@ TEST_CONSTEXPR_CXX20 bool all_the_algorithms() { assert(copies == 0); #endif (void)std::generate(first, last, NullaryValue(&copies)); - assert(copies == 1); - copies = 0; + assert(copies == 0); (void)std::generate_n(first, count, NullaryValue(&copies)); assert(copies == 0); (void)std::includes(first, last, first2, last2, Less(&copies)); From 4589580d9b0a7bb7b9906394e5e5e5b5b7b0eb4e Mon Sep 17 00:00:00 2001 From: c8ef Date: Mon, 13 Oct 2025 23:14:54 +0800 Subject: [PATCH 04/17] forward std::generate to std::for_each --- libcxx/include/__algorithm/generate.h | 32 +++++---------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 188f10111d454..87483d45e7482 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -9,10 +9,9 @@ #ifndef _LIBCPP___ALGORITHM_GENERATE_H #define _LIBCPP___ALGORITHM_GENERATE_H -#include <__algorithm/for_each_segment.h> +#include <__algorithm/for_each.h> #include <__config> -#include <__iterator/segmented_iterator.h> -#include <__type_traits/enable_if.h> + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -20,31 +19,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void -__generate(_ForwardIterator __first, _Sent __last, _Generator& __gen) { - for (; __first != __last; ++__first) - *__first = __gen(); -} - -#ifndef _LIBCPP_CXX03_LANG -template , int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_SegmentedIterator __generate(_SegmentedIterator __first, _SegmentedIterator __last, _Generator& __gen) { - using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator; - std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) { - std::__generate(__lfirst, __llast, __gen); - }); - return __last; -} -#endif // !_LIBCPP_CXX03_LANG - template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { - std::__generate(__first, __last, __gen); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { + std::for_each(__first, __last, [&](auto& __element) { __element = __gen(); }); } _LIBCPP_END_NAMESPACE_STD From bb58a986d2ee0373caf144f914af9c453f8fcc4e Mon Sep 17 00:00:00 2001 From: c8ef Date: Mon, 13 Oct 2025 23:17:14 +0800 Subject: [PATCH 05/17] forward std::generate to std::for_each --- libcxx/include/__algorithm/generate.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 87483d45e7482..18af2a1b85434 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -12,7 +12,6 @@ #include <__algorithm/for_each.h> #include <__config> - #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif From f1e883ff9bbb2fbc4c8187dd4a12cac10466fa72 Mon Sep 17 00:00:00 2001 From: c8ef Date: Wed, 15 Oct 2025 22:54:07 +0800 Subject: [PATCH 06/17] use std::forward --- libcxx/docs/ReleaseNotes/22.rst | 2 ++ libcxx/include/__algorithm/generate.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst index ec23ba9d1e3a1..5ca106125fb22 100644 --- a/libcxx/docs/ReleaseNotes/22.rst +++ b/libcxx/docs/ReleaseNotes/22.rst @@ -67,6 +67,8 @@ Improvements and New Features reduced debug information. - The performance of ``std::find`` has been improved by up to 2x for integral types +- The ``std::generate`` algorithm has been optimized for segmented iterators, resulting in a performance improvement for + ``std::deque`` and ``std::join_view>>`` iterators. Deprecations and Removals ------------------------- diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 18af2a1b85434..8f27dbeef4667 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -11,6 +11,7 @@ #include <__algorithm/for_each.h> #include <__config> +#include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { - std::for_each(__first, __last, [&](auto& __element) { __element = __gen(); }); + std::for_each(__first, __last, [&](auto&& __element) { std::forward(__element) = __gen(); }); } _LIBCPP_END_NAMESPACE_STD From eaa9f0fbc63e95b9c5cbbfd922e9b526cfc7400a Mon Sep 17 00:00:00 2001 From: c8ef Date: Thu, 16 Oct 2025 01:42:59 +0800 Subject: [PATCH 07/17] get rid of auto&& --- libcxx/include/__algorithm/generate.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 8f27dbeef4667..2f3ec2e8faf24 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -22,7 +22,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { - std::for_each(__first, __last, [&](auto&& __element) { std::forward(__element) = __gen(); }); + typedef typename std::iterator_traits<_ForwardIterator>::value_type value_type; + std::for_each(__first, __last, [&](value_type&& __element) { std::forward(__element) = __gen(); }); } _LIBCPP_END_NAMESPACE_STD From cea8b3d690bd566eb756d9b01a66833ccb7e9cc5 Mon Sep 17 00:00:00 2001 From: c8ef Date: Thu, 16 Oct 2025 01:47:03 +0800 Subject: [PATCH 08/17] include --- libcxx/include/__algorithm/generate.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 2f3ec2e8faf24..5ff2b421a61d2 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -11,6 +11,7 @@ #include <__algorithm/for_each.h> #include <__config> +#include <__iterator/iterator_traits.h> #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) From ccffb06f6633ca13e17f7613a1920eeaab530bc4 Mon Sep 17 00:00:00 2001 From: c8ef Date: Thu, 16 Oct 2025 01:59:18 +0800 Subject: [PATCH 09/17] fn --- libcxx/include/__algorithm/generate.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 5ff2b421a61d2..b8730d5a7021c 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -11,7 +11,6 @@ #include <__algorithm/for_each.h> #include <__config> -#include <__iterator/iterator_traits.h> #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -20,11 +19,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD +template +struct __fn { + __fn(_Generator& __g) : __gen(__g) {} + + template + void operator()(_Tp&& __element) const { + std::forward<_Tp>(__element) = __gen(); + } + + _Generator& __gen; +}; + template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { - typedef typename std::iterator_traits<_ForwardIterator>::value_type value_type; - std::for_each(__first, __last, [&](value_type&& __element) { std::forward(__element) = __gen(); }); + std::for_each(__first, __last, __fn<_Generator>(__gen)); } _LIBCPP_END_NAMESPACE_STD From fef17dd66b38183473a180d0b970d90c0452b74f Mon Sep 17 00:00:00 2001 From: c8ef Date: Thu, 16 Oct 2025 02:06:56 +0800 Subject: [PATCH 10/17] fn --- libcxx/include/__algorithm/generate.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index b8730d5a7021c..d0230a35569d2 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -21,14 +21,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD template struct __fn { - __fn(_Generator& __g) : __gen(__g) {} + _LIBCPP_HIDE_FROM_ABI __fn(_Generator& __gen) : __gen_(__gen) {} template - void operator()(_Tp&& __element) const { - std::forward<_Tp>(__element) = __gen(); + _LIBCPP_HIDE_FROM_ABI void operator()(_Tp&& __element) const { + std::forward<_Tp>(__element) = __gen_(); } - _Generator& __gen; + _Generator& __gen_; }; template From 49e76c0023f21dde7e17c10ef90220162c194c3c Mon Sep 17 00:00:00 2001 From: c8ef Date: Thu, 16 Oct 2025 02:14:01 +0800 Subject: [PATCH 11/17] namespace --- libcxx/include/__algorithm/generate.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index d0230a35569d2..38daf674c4829 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -19,6 +19,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD +namespace __generate { + template struct __fn { _LIBCPP_HIDE_FROM_ABI __fn(_Generator& __gen) : __gen_(__gen) {} @@ -31,10 +33,12 @@ struct __fn { _Generator& __gen_; }; +} // namespace __generate + template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { - std::for_each(__first, __last, __fn<_Generator>(__gen)); + std::for_each(__first, __last, __generate::__fn<_Generator>(__gen)); } _LIBCPP_END_NAMESPACE_STD From 7156521827d7a8dc5699cf08f1f15ee3e18dfce9 Mon Sep 17 00:00:00 2001 From: c8ef Date: Thu, 16 Oct 2025 02:19:50 +0800 Subject: [PATCH 12/17] constexpr --- libcxx/include/__algorithm/generate.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 38daf674c4829..1c52eb68ed0bc 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -23,10 +23,10 @@ namespace __generate { template struct __fn { - _LIBCPP_HIDE_FROM_ABI __fn(_Generator& __gen) : __gen_(__gen) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __fn(_Generator& __gen) : __gen_(__gen) {} template - _LIBCPP_HIDE_FROM_ABI void operator()(_Tp&& __element) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(_Tp&& __element) const { std::forward<_Tp>(__element) = __gen_(); } From 36ee86c6a3af706391b128d5e2ae2c5511b17dca Mon Sep 17 00:00:00 2001 From: c8ef Date: Thu, 16 Oct 2025 22:04:05 +0800 Subject: [PATCH 13/17] address review comments --- libcxx/include/__algorithm/generate.h | 14 ++---- .../alg.generate/generate.pass.cpp | 49 ++++++++----------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 1c52eb68ed0bc..fe03188b72329 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -19,13 +19,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace __generate { +template +struct __generate_assigner { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __generate_assigner(_Generator& __gen) : __gen_(__gen) {} -template -struct __fn { - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __fn(_Generator& __gen) : __gen_(__gen) {} - - template + template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(_Tp&& __element) const { std::forward<_Tp>(__element) = __gen_(); } @@ -33,12 +31,10 @@ struct __fn { _Generator& __gen_; }; -} // namespace __generate - template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { - std::for_each(__first, __last, __generate::__fn<_Generator>(__gen)); + std::for_each(__first, __last, __generate_assigner<_Generator>(__gen)); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp index 4591d7ece4645..569ac25935932 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp @@ -21,35 +21,29 @@ #include "test_macros.h" #include "test_iterators.h" -struct gen_test -{ - TEST_CONSTEXPR int operator()() const {return 1;} +struct gen_test { + TEST_CONSTEXPR int operator()() const { return 1; } }; - #if TEST_STD_VER > 17 TEST_CONSTEXPR bool test_constexpr() { - int ia[] = {0, 1, 2, 3, 4}; + int ia[] = {0, 1, 2, 3, 4}; - std::generate(std::begin(ia), std::end(ia), gen_test()); + std::generate(std::begin(ia), std::end(ia), gen_test()); - return std::all_of(std::begin(ia), std::end(ia), [](int x) { return x == 1; }) - ; - } + return std::all_of(std::begin(ia), std::end(ia), [](int x) { return x == 1; }); +} #endif - template -void -test() -{ - const unsigned n = 4; - int ia[n] = {0}; - std::generate(Iter(ia), Iter(ia+n), gen_test()); - assert(ia[0] == 1); - assert(ia[1] == 1); - assert(ia[2] == 1); - assert(ia[3] == 1); +void test() { + const unsigned n = 4; + int ia[n] = {0}; + std::generate(Iter(ia), Iter(ia + n), gen_test()); + assert(ia[0] == 1); + assert(ia[1] == 1); + assert(ia[2] == 1); + assert(ia[3] == 1); } void deque_test() { @@ -61,16 +55,15 @@ void deque_test() { } } -int main(int, char**) -{ - test >(); - test >(); - test >(); - test(); - deque_test(); +int main(int, char**) { + test >(); + test >(); + test >(); + test(); + deque_test(); #if TEST_STD_VER > 17 - static_assert(test_constexpr()); + static_assert(test_constexpr()); #endif return 0; From 13f7843895d778a7e6f2fddc6e7db274d2059c09 Mon Sep 17 00:00:00 2001 From: c8ef Date: Thu, 16 Oct 2025 22:08:45 +0800 Subject: [PATCH 14/17] release notes --- libcxx/docs/ReleaseNotes/22.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst index 3041748dd07d6..c67fe00c10f04 100644 --- a/libcxx/docs/ReleaseNotes/22.rst +++ b/libcxx/docs/ReleaseNotes/22.rst @@ -68,11 +68,9 @@ Improvements and New Features reduced debug information. - The performance of ``std::find`` has been improved by up to 2x for integral types -- The ``std::generate`` algorithm has been optimized for segmented iterators, resulting in a performance improvement for - ``std::deque`` and ``std::join_view>>`` iterators. -- The ``std::distance`` and ``std::ranges::distance`` algorithms have been optimized for segmented iterators (e.g., - ``std::join_view`` iterators), reducing the complexity from ``O(n)`` to ``O(n / segment_size)``. Benchmarks show - performance improvements of over 1600x in favorable cases with large segment sizes (e.g., 1024). +- The ``std::distance``, ``std::ranges::distance`` and ``std::generate`` algorithms have been optimized for segmented + iterators (e.g. ``std::join_view`` iterators), reducing the complexity from ``O(n)`` to ``O(n / segment_size)``. + Benchmarks show performance improvements of over 1600x in favorable cases with large segment sizes (e.g., 1024). Deprecations and Removals ------------------------- From 7b1c4a03ce0b7d6d08e3ba43d59c6ac80f501558 Mon Sep 17 00:00:00 2001 From: c8ef Date: Fri, 17 Oct 2025 22:56:19 +0800 Subject: [PATCH 15/17] revert test --- .../alg.generate/generate.pass.cpp | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp index 569ac25935932..4591d7ece4645 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/generate.pass.cpp @@ -21,29 +21,35 @@ #include "test_macros.h" #include "test_iterators.h" -struct gen_test { - TEST_CONSTEXPR int operator()() const { return 1; } +struct gen_test +{ + TEST_CONSTEXPR int operator()() const {return 1;} }; + #if TEST_STD_VER > 17 TEST_CONSTEXPR bool test_constexpr() { - int ia[] = {0, 1, 2, 3, 4}; + int ia[] = {0, 1, 2, 3, 4}; - std::generate(std::begin(ia), std::end(ia), gen_test()); + std::generate(std::begin(ia), std::end(ia), gen_test()); - return std::all_of(std::begin(ia), std::end(ia), [](int x) { return x == 1; }); -} + return std::all_of(std::begin(ia), std::end(ia), [](int x) { return x == 1; }) + ; + } #endif + template -void test() { - const unsigned n = 4; - int ia[n] = {0}; - std::generate(Iter(ia), Iter(ia + n), gen_test()); - assert(ia[0] == 1); - assert(ia[1] == 1); - assert(ia[2] == 1); - assert(ia[3] == 1); +void +test() +{ + const unsigned n = 4; + int ia[n] = {0}; + std::generate(Iter(ia), Iter(ia+n), gen_test()); + assert(ia[0] == 1); + assert(ia[1] == 1); + assert(ia[2] == 1); + assert(ia[3] == 1); } void deque_test() { @@ -55,15 +61,16 @@ void deque_test() { } } -int main(int, char**) { - test >(); - test >(); - test >(); - test(); - deque_test(); +int main(int, char**) +{ + test >(); + test >(); + test >(); + test(); + deque_test(); #if TEST_STD_VER > 17 - static_assert(test_constexpr()); + static_assert(test_constexpr()); #endif return 0; From 4c52a1a3a6170f78fdd3c6b98e80b6c2d512492b Mon Sep 17 00:00:00 2001 From: c8ef Date: Fri, 17 Oct 2025 22:59:36 +0800 Subject: [PATCH 16/17] decltype --- libcxx/include/__algorithm/generate.h | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index fe03188b72329..7b71aaedcf65d 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -19,22 +19,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -struct __generate_assigner { - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __generate_assigner(_Generator& __gen) : __gen_(__gen) {} - - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(_Tp&& __element) const { - std::forward<_Tp>(__element) = __gen_(); - } - - _Generator& __gen_; -}; - template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { - std::for_each(__first, __last, __generate_assigner<_Generator>(__gen)); + std::for_each(__first, __last, [&](decltype(*__first) __element) { __element = __gen(); }); } _LIBCPP_END_NAMESPACE_STD From 82bb2ee5cb3fbdb2c575c24888e9890405480693 Mon Sep 17 00:00:00 2001 From: Connector Switch Date: Sat, 18 Oct 2025 20:41:21 +0800 Subject: [PATCH 17/17] Apply suggestion from @frederick-vs-ja Co-authored-by: A. Jiang --- libcxx/include/__algorithm/generate.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h index 7b71aaedcf65d..c4cd75cd0a4d6 100644 --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -22,7 +22,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { - std::for_each(__first, __last, [&](decltype(*__first) __element) { __element = __gen(); }); + using __iter_ref = decltype(*__first); + std::for_each(__first, __last, [&](__iter_ref __element) { std::forward<__iter_ref>(__element) = __gen(); }); } _LIBCPP_END_NAMESPACE_STD