|
13 | 13 | #include <__algorithm/for_each.h> |
14 | 14 | #include <__algorithm/for_each_n_segment.h> |
15 | 15 | #include <__config> |
| 16 | +#include <__functional/identity.h> |
| 17 | +#include <__functional/invoke.h> |
16 | 18 | #include <__iterator/iterator_traits.h> |
17 | | -#include <__iterator/next.h> |
18 | 19 | #include <__iterator/segmented_iterator.h> |
19 | 20 | #include <__type_traits/enable_if.h> |
20 | 21 | #include <__utility/convert_to_integral.h> |
|
25 | 26 |
|
26 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
27 | 28 |
|
28 | | -#if _LIBCPP_STD_VER >= 17 |
29 | | - |
30 | 29 | template <class _InputIterator, |
31 | 30 | class _Size, |
32 | 31 | class _Function, |
33 | | - __enable_if_t<!__is_segmented_iterator<_InputIterator>::value || |
34 | | - __has_exactly_input_iterator_category<_InputIterator>::value, |
| 32 | + class _Proj, |
| 33 | + __enable_if_t<!__has_random_access_iterator_category<_InputIterator>::value && |
| 34 | + (!__is_segmented_iterator<_InputIterator>::value |
| 35 | + // || !__has_random_access_iterator_category< |
| 36 | + // typename __segmented_iterator_traits<_InputIterator>::__local_iterator>::value |
| 37 | + ), // TODO: __segmented_iterator_traits<_InputIterator> results in template instantiation |
| 38 | + // during SFINAE, which is a hard error to be fixed. Once fixed, we should uncomment. |
35 | 39 | int> = 0> |
36 | 40 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator |
37 | | -for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { |
| 41 | +__for_each_n(_InputIterator __first, _Size __orig_n, _Function& __f, _Proj& __proj) { |
38 | 42 | typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; |
39 | 43 | _IntegralSize __n = __orig_n; |
40 | 44 | while (__n > 0) { |
41 | | - __f(*__first); |
| 45 | + std::invoke(__f, std::invoke(__proj, *__first)); |
42 | 46 | ++__first; |
43 | 47 | --__n; |
44 | 48 | } |
45 | 49 | return __first; |
46 | 50 | } |
47 | 51 |
|
| 52 | +template <class _RandIter, |
| 53 | + class _Size, |
| 54 | + class _Function, |
| 55 | + class _Proj, |
| 56 | + __enable_if_t<__has_random_access_iterator_category<_RandIter>::value, int> = 0> |
| 57 | +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandIter |
| 58 | +__for_each_n(_RandIter __first, _Size __orig_n, _Function& __f, _Proj& __proj) { |
| 59 | + typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; |
| 60 | + _IntegralSize __n = __orig_n; |
| 61 | + return std::__for_each(__first, __first + __n, __f, __proj); |
| 62 | +} |
| 63 | + |
48 | 64 | template <class _SegmentedIterator, |
49 | 65 | class _Size, |
50 | 66 | class _Function, |
51 | | - __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value && |
52 | | - __has_forward_iterator_category<_SegmentedIterator>::value, |
| 67 | + class _Proj, |
| 68 | + __enable_if_t<!__has_random_access_iterator_category<_SegmentedIterator>::value && |
| 69 | + __is_segmented_iterator<_SegmentedIterator>::value && |
| 70 | + __has_random_access_iterator_category< |
| 71 | + typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value, |
53 | 72 | int> = 0> |
54 | 73 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator |
55 | | -for_each_n(_SegmentedIterator __first, _Size __orig_n, _Function __f) { |
56 | | - return std::__for_each_n_segment(__first, __orig_n, std::__segment_processor<_SegmentedIterator, _Function>(__f)); |
| 74 | +__for_each_n(_SegmentedIterator __first, _Size __orig_n, _Function& __f, _Proj& __proj) { |
| 75 | + return std::__for_each_n_segment( |
| 76 | + __first, __orig_n, std::__segment_processor<_SegmentedIterator, _Function, _Proj>(__f, __proj)); |
| 77 | +} |
| 78 | + |
| 79 | +#if _LIBCPP_STD_VER >= 17 |
| 80 | + |
| 81 | +template <class _InputIterator, class _Size, class _Function> |
| 82 | +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator |
| 83 | +for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { |
| 84 | + __identity __proj; |
| 85 | + return std::__for_each_n(__first, __orig_n, __f, __proj); |
57 | 86 | } |
58 | 87 |
|
59 | 88 | #endif |
|
0 commit comments