-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[libc++] Merge the segmented iterator code for {copy,move}_backward #165160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
philnik777
merged 1 commit into
llvm:main
from
philnik777:introduce_for_each_segment_backward
Dec 11, 2025
Merged
[libc++] Merge the segmented iterator code for {copy,move}_backward #165160
philnik777
merged 1 commit into
llvm:main
from
philnik777:introduce_for_each_segment_backward
Dec 11, 2025
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
81c10c2 to
6254e5f
Compare
6254e5f to
d6a492b
Compare
d6a492b to
ef82efb
Compare
ef82efb to
5ec024e
Compare
Member
|
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesThis removes a bit of code duplication and might simplify future segmented iterator optimitations. Full diff: https://github.com/llvm/llvm-project/pull/165160.diff 3 Files Affected:
diff --git a/libcxx/include/__algorithm/copy_backward.h b/libcxx/include/__algorithm/copy_backward.h
index 6c9eba672e154..8758d2c9e7b5d 100644
--- a/libcxx/include/__algorithm/copy_backward.h
+++ b/libcxx/include/__algorithm/copy_backward.h
@@ -11,6 +11,7 @@
#include <__algorithm/copy_move_common.h>
#include <__algorithm/copy_n.h>
+#include <__algorithm/for_each_segment.h>
#include <__algorithm/iterator_operations.h>
#include <__algorithm/min.h>
#include <__config>
@@ -173,27 +174,10 @@ struct __copy_backward_impl {
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
- using _Traits = __segmented_iterator_traits<_InIter>;
- auto __sfirst = _Traits::__segment(__first);
- auto __slast = _Traits::__segment(__last);
- if (__sfirst == __slast) {
- auto __iters =
- std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
- return std::make_pair(__last, __iters.second);
- }
-
- __result =
- std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
- .second;
- --__slast;
- while (__sfirst != __slast) {
- __result =
- std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
- .second;
- --__slast;
- }
- __result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
- .second;
+ using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
+ std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
+ __result = std::__copy_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
+ });
return std::make_pair(__last, std::move(__result));
}
diff --git a/libcxx/include/__algorithm/for_each_segment.h b/libcxx/include/__algorithm/for_each_segment.h
index 93aa8259b2f7f..c02436c9aa33c 100644
--- a/libcxx/include/__algorithm/for_each_segment.h
+++ b/libcxx/include/__algorithm/for_each_segment.h
@@ -48,6 +48,32 @@ __for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Funct
__func(_Traits::__begin(__sfirst), _Traits::__local(__last));
}
+template <class _SegmentedIterator, class _Functor>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
+__for_each_segment_backward(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
+ using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
+
+ auto __sfirst = _Traits::__segment(__first);
+ auto __slast = _Traits::__segment(__last);
+
+ // We are in a single segment, so we might not be at the beginning or end
+ if (__sfirst == __slast) {
+ __func(_Traits::__local(__first), _Traits::__local(__last));
+ return;
+ }
+
+ // We have more than one segment. Iterate over the last segment, since we might not start at the end
+ __func(_Traits::__begin(__slast), _Traits::__local(__last));
+ --__slast;
+ // iterate over the segments which are guaranteed to be completely in the range
+ while (__sfirst != __slast) {
+ __func(_Traits::__begin(__slast), _Traits::__end(__slast));
+ --__slast;
+ }
+ // iterate over the first segment
+ __func(_Traits::__local(__first), _Traits::__end(__slast));
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
diff --git a/libcxx/include/__algorithm/move_backward.h b/libcxx/include/__algorithm/move_backward.h
index a4698327b474d..43b72057a5eca 100644
--- a/libcxx/include/__algorithm/move_backward.h
+++ b/libcxx/include/__algorithm/move_backward.h
@@ -11,6 +11,7 @@
#include <__algorithm/copy_backward.h>
#include <__algorithm/copy_move_common.h>
+#include <__algorithm/for_each_segment.h>
#include <__algorithm/iterator_operations.h>
#include <__algorithm/min.h>
#include <__config>
@@ -54,27 +55,10 @@ struct __move_backward_impl {
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
- using _Traits = __segmented_iterator_traits<_InIter>;
- auto __sfirst = _Traits::__segment(__first);
- auto __slast = _Traits::__segment(__last);
- if (__sfirst == __slast) {
- auto __iters =
- std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
- return std::make_pair(__last, __iters.second);
- }
-
- __result =
- std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
- .second;
- --__slast;
- while (__sfirst != __slast) {
- __result =
- std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
- .second;
- --__slast;
- }
- __result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
- .second;
+ using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
+ std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
+ __result = std::__move_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
+ });
return std::make_pair(__last, std::move(__result));
}
|
ldionne
approved these changes
Dec 10, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This removes a bit of code duplication and might simplify future segmented iterator optimitations.