Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 4 additions & 21 deletions libcxx/include/__algorithm/copy_backward.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,27 +173,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));
});
return std::make_pair(__last, std::move(__result));
}

Expand Down
26 changes: 26 additions & 0 deletions libcxx/include/__algorithm/for_each_segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 _SegmentedIterator
__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
26 changes: 5 additions & 21 deletions libcxx/include/__algorithm/move_backward.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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));
}

Expand Down
Loading