1616#include < __functional/identity.h>
1717#include < __iterator/iterator_traits.h>
1818#include < __iterator/segmented_iterator.h>
19- #include < __type_traits/disjunction.h>
20- #include < __type_traits/enable_if.h>
2119#include < __type_traits/invoke.h>
22- #include < __type_traits/negation.h>
2320#include < __utility/convert_to_integral.h>
2421#include < __utility/move.h>
2522
@@ -32,57 +29,33 @@ _LIBCPP_PUSH_MACROS
3229
3330_LIBCPP_BEGIN_NAMESPACE_STD
3431
35- template <class _InputIterator ,
36- class _Size ,
37- class _Func ,
38- class _Proj ,
39- __enable_if_t <!__has_random_access_iterator_category<_InputIterator>::value &&
40- _Or<integral_constant<bool , !__is_segmented_iterator_v<_InputIterator> >,
41- _Not<__has_random_access_local_iterator<_InputIterator> > >::value,
42- int > = 0 >
32+ template <class _InputIterator , class _Size , class _Func , class _Proj >
4333_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
4434__for_each_n (_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
4535 typedef decltype (std::__convert_to_integral (__orig_n)) _IntegralSize;
4636 _IntegralSize __n = __orig_n;
47- while (__n > 0 ) {
48- std::__invoke (__f, std::__invoke (__proj, *__first));
49- ++__first;
50- --__n;
51- }
52- return std::move (__first);
53- }
54-
55- template <class _RandIter ,
56- class _Size ,
57- class _Func ,
58- class _Proj ,
59- __enable_if_t <__has_random_access_iterator_category<_RandIter>::value, int > = 0 >
60- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandIter
61- __for_each_n (_RandIter __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
62- typename std::iterator_traits<_RandIter>::difference_type __n = __orig_n;
63- auto __last = __first + __n;
64- std::__for_each (__first, __last, __f, __proj);
65- return __last;
66- }
6737
6838#ifndef _LIBCPP_CXX03_LANG
69- template <class _SegmentedIterator ,
70- class _Size ,
71- class _Func ,
72- class _Proj ,
73- __enable_if_t <!__has_random_access_iterator_category<_SegmentedIterator>::value &&
74- __is_segmented_iterator_v<_SegmentedIterator> &&
75- __has_random_access_iterator_category<
76- typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value,
77- int > = 0 >
78- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator
79- __for_each_n (_SegmentedIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
80- using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
81- return std::__for_each_n_segment (__first, __orig_n, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
82- std::__for_each (__lfirst, __llast, __f, __proj);
83- });
39+ if constexpr (__is_segmented_iterator_v<_InputIterator>) {
40+ using __local_iterator = typename __segmented_iterator_traits<_InputIterator>::__local_iterator;
41+ if constexpr (__has_random_access_iterator_category<__local_iterator>::value) {
42+ return std::__for_each_n_segment (__first, __orig_n, [&](__local_iterator __lfirst, __local_iterator __llast) {
43+ std::__for_each (__lfirst, __llast, __f, __proj);
44+ });
45+ } else {
46+ return std::__for_each (__first, __first + __n, __f, __proj);
47+ }
48+ } else
49+ #endif
50+ {
51+ while (__n > 0 ) {
52+ std::__invoke (__f, std::__invoke (__proj, *__first));
53+ ++__first;
54+ --__n;
55+ }
56+ return std::move (__first);
57+ }
8458}
85- #endif // !_LIBCPP_CXX03_LANG
8659
8760#if _LIBCPP_STD_VER >= 17
8861
0 commit comments