1010#define _LIBCPP___ALGORITHM_COPY_H
1111
1212#include < __algorithm/copy_move_common.h>
13+ #include < __algorithm/for_each_segment.h>
1314#include < __algorithm/iterator_operations.h>
1415#include < __algorithm/min.h>
1516#include < __config>
@@ -44,36 +45,34 @@ struct __copy_loop {
4445 return std::make_pair (std::move (__first), std::move (__result));
4546 }
4647
47- template <class _InIter , class _OutIter , __enable_if_t <__is_segmented_iterator<_InIter>::value, int > = 0 >
48- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
49- operator ()(_InIter __first, _InIter __last, _OutIter __result) const {
48+ template <class _InIter , class _OutIter >
49+ struct _CopySegment {
5050 using _Traits = __segmented_iterator_traits<_InIter>;
51- auto __sfirst = _Traits::__segment (__first);
52- auto __slast = _Traits::__segment (__last);
53- if (__sfirst == __slast) {
54- auto __iters = std::__copy<_AlgPolicy>(_Traits::__local (__first), _Traits::__local (__last), std::move (__result));
55- return std::make_pair (__last, std::move (__iters.second ));
56- }
5751
58- __result = std::__copy<_AlgPolicy>(_Traits::__local (__first), _Traits::__end (__sfirst), std::move (__result)).second ;
59- ++__sfirst;
60- while (__sfirst != __slast) {
61- __result =
62- std::__copy<_AlgPolicy>(_Traits::__begin (__sfirst), _Traits::__end (__sfirst), std::move (__result)).second ;
63- ++__sfirst;
52+ _OutIter& __result_;
53+
54+ _LIBCPP_HIDE_FROM_ABI _CopySegment (_OutIter& __result) : __result_(__result) {}
55+
56+ _LIBCPP_HIDE_FROM_ABI void
57+ operator ()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
58+ __result_ = std::__copy<_AlgPolicy>(__lfirst, __llast, std::move (__result_)).second ;
6459 }
65- __result =
66- std::__copy<_AlgPolicy>(_Traits::__begin (__sfirst), _Traits::__local (__last), std::move (__result)).second ;
60+ };
61+
62+ template <class _InIter , class _OutIter , __enable_if_t <__is_segmented_iterator<_InIter>::value, int > = 0 >
63+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
64+ operator ()(_InIter __first, _InIter __last, _OutIter __result) const {
65+ std::__for_each_segment (__first, __last, _CopySegment<_InIter, _OutIter>(__result));
6766 return std::make_pair (__last, std::move (__result));
6867 }
6968
7069 template <class _InIter ,
7170 class _OutIter ,
72- __enable_if_t <__is_cpp17_random_access_iterator <_InIter>::value &&
71+ __enable_if_t <__has_random_access_iterator_category <_InIter>::value &&
7372 !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
7473 int > = 0 >
7574 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
76- operator ()(_InIter __first, _InIter __last, _OutIter __result) {
75+ operator ()(_InIter __first, _InIter __last, _OutIter __result) const {
7776 using _Traits = __segmented_iterator_traits<_OutIter>;
7877 using _DiffT = typename common_type<__iter_diff_t <_InIter>, __iter_diff_t <_OutIter> >::type;
7978
@@ -98,8 +97,7 @@ struct __copy_loop {
9897
9998struct __copy_trivial {
10099 // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
101- template <class _In , class _Out ,
102- __enable_if_t <__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int > = 0 >
100+ template <class _In , class _Out , __enable_if_t <__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int > = 0 >
103101 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
104102 operator ()(_In* __first, _In* __last, _Out* __result) const {
105103 return std::__copy_trivial_impl (__first, __last, __result);
0 commit comments