Skip to content

Commit ae7d2eb

Browse files
committed
[libc++] Merge the segmented iterator code for {copy,move}_backward
1 parent 63b83ea commit ae7d2eb

File tree

3 files changed

+35
-42
lines changed

3 files changed

+35
-42
lines changed

libcxx/include/__algorithm/copy_backward.h

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -173,27 +173,10 @@ struct __copy_backward_impl {
173173
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
174174
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
175175
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
176-
using _Traits = __segmented_iterator_traits<_InIter>;
177-
auto __sfirst = _Traits::__segment(__first);
178-
auto __slast = _Traits::__segment(__last);
179-
if (__sfirst == __slast) {
180-
auto __iters =
181-
std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
182-
return std::make_pair(__last, __iters.second);
183-
}
184-
185-
__result =
186-
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
187-
.second;
188-
--__slast;
189-
while (__sfirst != __slast) {
190-
__result =
191-
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
192-
.second;
193-
--__slast;
194-
}
195-
__result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
196-
.second;
176+
using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
177+
std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
178+
__result = std::__copy_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result));
179+
});
197180
return std::make_pair(__last, std::move(__result));
198181
}
199182

libcxx/include/__algorithm/for_each_segment.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,32 @@ __for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Funct
4848
__func(_Traits::__begin(__sfirst), _Traits::__local(__last));
4949
}
5050

51+
template <class _SegmentedIterator, class _Functor>
52+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
53+
__for_each_segment_backward(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
54+
using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
55+
56+
auto __sfirst = _Traits::__segment(__first);
57+
auto __slast = _Traits::__segment(__last);
58+
59+
// We are in a single segment, so we might not be at the beginning or end
60+
if (__sfirst == __slast) {
61+
__func(_Traits::__local(__first), _Traits::__local(__last));
62+
return;
63+
}
64+
65+
// We have more than one segment. Iterate over the last segment, since we might not start at the end
66+
__func(_Traits::__begin(__slast), _Traits::__local(__last));
67+
--__slast;
68+
// iterate over the segments which are guaranteed to be completely in the range
69+
while (__sfirst != __slast) {
70+
__func(_Traits::__begin(__slast), _Traits::__end(__slast));
71+
--__slast;
72+
}
73+
// iterate over the first segment
74+
__func(_Traits::__local(__first), _Traits::__end(__slast));
75+
}
76+
5177
_LIBCPP_END_NAMESPACE_STD
5278

5379
#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H

libcxx/include/__algorithm/move_backward.h

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <__algorithm/copy_backward.h>
1313
#include <__algorithm/copy_move_common.h>
14+
#include <__algorithm/for_each_segment.h>
1415
#include <__algorithm/iterator_operations.h>
1516
#include <__algorithm/min.h>
1617
#include <__config>
@@ -54,27 +55,10 @@ struct __move_backward_impl {
5455
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
5556
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
5657
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
57-
using _Traits = __segmented_iterator_traits<_InIter>;
58-
auto __sfirst = _Traits::__segment(__first);
59-
auto __slast = _Traits::__segment(__last);
60-
if (__sfirst == __slast) {
61-
auto __iters =
62-
std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
63-
return std::make_pair(__last, __iters.second);
64-
}
65-
66-
__result =
67-
std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
68-
.second;
69-
--__slast;
70-
while (__sfirst != __slast) {
71-
__result =
72-
std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
73-
.second;
74-
--__slast;
75-
}
76-
__result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
77-
.second;
58+
using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
59+
std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
60+
__result = std::__move_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result));
61+
});
7862
return std::make_pair(__last, std::move(__result));
7963
}
8064

0 commit comments

Comments
 (0)