mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 06:40:01 +08:00
[libc++] Merge the segmented iterator code for {copy,move}_backward (#165160)
This removes a bit of code duplication and might simplify future segmented iterator optimitations.
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user