[libcxx-commits] [libcxx] [libcxx] Modify `std::__for_each{, _n}` to accept r-values in `__f` (PR #179451)
Connector Switch via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 3 05:09:37 PST 2026
https://github.com/c8ef updated https://github.com/llvm/llvm-project/pull/179451
>From 0fe2c5063b39ba19a5f39a813ac7dbfea06bfa00 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Tue, 3 Feb 2026 20:32:50 +0800
Subject: [PATCH 1/2] make func accept rval
---
libcxx/include/__algorithm/for_each.h | 14 ++++++++++----
libcxx/include/__algorithm/for_each_n.h | 5 +++--
libcxx/include/__algorithm/generate_n.h | 7 +++++--
3 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/libcxx/include/__algorithm/for_each.h b/libcxx/include/__algorithm/for_each.h
index 85fedce3d936d..f46a4d70687e2 100644
--- a/libcxx/include/__algorithm/for_each.h
+++ b/libcxx/include/__algorithm/for_each.h
@@ -17,32 +17,36 @@
#include <__iterator/segmented_iterator.h>
#include <__type_traits/invoke.h>
#include <__type_traits/is_same.h>
+#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Sent, class _Func, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
-__for_each(_InputIterator __first, _Sent __last, _Func& __func, _Proj& __proj) {
+__for_each(_InputIterator __first, _Sent __last, _Func&& __f, _Proj& __proj) {
#ifndef _LIBCPP_CXX03_LANG
if constexpr (using _SpecialAlg =
__specialized_algorithm<_Algorithm::__for_each, __iterator_pair<_InputIterator, _Sent>>;
_SpecialAlg::__has_algorithm) {
- _SpecialAlg()(__first, __last, __func, __proj);
+ _SpecialAlg()(__first, __last, std::forward<_Func>(__f), __proj);
return __last;
} else if constexpr (is_same<_InputIterator, _Sent>::value && __is_segmented_iterator_v<_InputIterator>) {
using __local_iterator_t = typename __segmented_iterator_traits<_InputIterator>::__local_iterator;
std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
- std::__for_each(__lfirst, __llast, __func, __proj);
+ std::__for_each(__lfirst, __llast, __f, __proj);
});
return __last;
}
#endif
for (; __first != __last; ++__first)
- std::__invoke(__func, std::__invoke(__proj, *__first));
+ std::__invoke(__f, std::__invoke(__proj, *__first));
return __first;
}
@@ -56,4 +60,6 @@ for_each(_InputIterator __first, _InputIterator __last, _Func __f) {
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_FOR_EACH_H
diff --git a/libcxx/include/__algorithm/for_each_n.h b/libcxx/include/__algorithm/for_each_n.h
index 72c7adb093f95..7ff3f9b157c02 100644
--- a/libcxx/include/__algorithm/for_each_n.h
+++ b/libcxx/include/__algorithm/for_each_n.h
@@ -18,6 +18,7 @@
#include <__iterator/segmented_iterator.h>
#include <__type_traits/invoke.h>
#include <__utility/convert_to_integral.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -31,7 +32,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Size, class _Func, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
-__for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
+__for_each_n(_InputIterator __first, _Size __orig_n, _Func&& __f, _Proj& __proj) {
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
_IntegralSize __n = __orig_n;
@@ -43,7 +44,7 @@ __for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj)
std::__for_each(__lfirst, __llast, __f, __proj);
});
} else {
- return std::__for_each(__first, __first + __n, __f, __proj);
+ return std::__for_each(__first, __first + __n, std::forward<_Func>(__f), __proj);
}
} else
#endif
diff --git a/libcxx/include/__algorithm/generate_n.h b/libcxx/include/__algorithm/generate_n.h
index 23899e49e0b65..ba04eb62e3c3a 100644
--- a/libcxx/include/__algorithm/generate_n.h
+++ b/libcxx/include/__algorithm/generate_n.h
@@ -29,8 +29,11 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
__generate_n(_OutputIterator __first, _Size __orig_n, _Generator& __gen) {
using __iter_ref = decltype(*__first);
__identity __proj;
- auto __f = [&](__iter_ref __element) { std::forward<__iter_ref>(__element) = __gen(); };
- return std::__for_each_n(std::move(__first), __orig_n, __f, __proj);
+ return std::__for_each_n(
+ std::move(__first),
+ __orig_n,
+ [&](__iter_ref __element) { std::forward<__iter_ref>(__element) = __gen(); },
+ __proj);
}
template <class _OutputIterator, class _Size, class _Generator>
>From f2f48734159925124781eb0af891a97894e5b0e2 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Tue, 3 Feb 2026 21:09:22 +0800
Subject: [PATCH 2/2] restore func; remove a forward
---
libcxx/include/__algorithm/for_each.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libcxx/include/__algorithm/for_each.h b/libcxx/include/__algorithm/for_each.h
index f46a4d70687e2..77eb4cfbcdd4e 100644
--- a/libcxx/include/__algorithm/for_each.h
+++ b/libcxx/include/__algorithm/for_each.h
@@ -30,23 +30,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Sent, class _Func, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
-__for_each(_InputIterator __first, _Sent __last, _Func&& __f, _Proj& __proj) {
+__for_each(_InputIterator __first, _Sent __last, _Func&& __func, _Proj& __proj) {
#ifndef _LIBCPP_CXX03_LANG
if constexpr (using _SpecialAlg =
__specialized_algorithm<_Algorithm::__for_each, __iterator_pair<_InputIterator, _Sent>>;
_SpecialAlg::__has_algorithm) {
- _SpecialAlg()(__first, __last, std::forward<_Func>(__f), __proj);
+ _SpecialAlg()(__first, __last, __func, __proj);
return __last;
} else if constexpr (is_same<_InputIterator, _Sent>::value && __is_segmented_iterator_v<_InputIterator>) {
using __local_iterator_t = typename __segmented_iterator_traits<_InputIterator>::__local_iterator;
std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
- std::__for_each(__lfirst, __llast, __f, __proj);
+ std::__for_each(__lfirst, __llast, __func, __proj);
});
return __last;
}
#endif
for (; __first != __last; ++__first)
- std::__invoke(__f, std::__invoke(__proj, *__first));
+ std::__invoke(__func, std::__invoke(__proj, *__first));
return __first;
}
More information about the libcxx-commits
mailing list