|
10 | 10 | #ifndef _LIBCPP___ALGORITHM_FOR_EACH_N_H
|
11 | 11 | #define _LIBCPP___ALGORITHM_FOR_EACH_N_H
|
12 | 12 |
|
| 13 | +#include <__algorithm/for_each.h> |
| 14 | +#include <__algorithm/for_each_n_segment.h> |
13 | 15 | #include <__config>
|
| 16 | +#include <__iterator/iterator_traits.h> |
| 17 | +#include <__iterator/segmented_iterator.h> |
| 18 | +#include <__type_traits/enable_if.h> |
14 | 19 | #include <__utility/convert_to_integral.h>
|
| 20 | +#include <__utility/move.h> |
15 | 21 |
|
16 | 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
17 | 23 | # pragma GCC system_header
|
18 | 24 | #endif
|
19 | 25 |
|
20 |
| -_LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | +_LIBCPP_PUSH_MACROS |
| 27 | +#include <__undef_macros> |
21 | 28 |
|
22 |
| -#if _LIBCPP_STD_VER >= 17 |
| 29 | +_LIBCPP_BEGIN_NAMESPACE_STD |
23 | 30 |
|
24 |
| -template <class _InputIterator, class _Size, class _Function> |
25 |
| -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator |
26 |
| -for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { |
| 31 | +template <class _InputIterator, |
| 32 | + class _Size, |
| 33 | + class _Func, |
| 34 | + __enable_if_t<!__has_random_access_iterator_category<_InputIterator>::value && |
| 35 | + (!__is_segmented_iterator<_InputIterator>::value |
| 36 | + // || !__has_random_access_iterator_category< |
| 37 | + // typename __segmented_iterator_traits<_InputIterator>::__local_iterator>::value |
| 38 | + ), // TODO: __segmented_iterator_traits<_InputIterator> results in template instantiation |
| 39 | + // during SFINAE, which is a hard error to be fixed. Once fixed, we should uncomment. |
| 40 | + int> = 0> |
| 41 | +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator |
| 42 | +__for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f) { |
27 | 43 | typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
|
28 | 44 | _IntegralSize __n = __orig_n;
|
29 | 45 | while (__n > 0) {
|
30 | 46 | __f(*__first);
|
31 | 47 | ++__first;
|
32 | 48 | --__n;
|
33 | 49 | }
|
34 |
| - return __first; |
| 50 | + return std::move(__first); |
35 | 51 | }
|
36 | 52 |
|
37 |
| -#endif |
| 53 | +template <class _RandIter, |
| 54 | + class _Size, |
| 55 | + class _Func, |
| 56 | + __enable_if_t<__has_random_access_iterator_category<_RandIter>::value, int> = 0> |
| 57 | +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandIter |
| 58 | +__for_each_n(_RandIter __first, _Size __orig_n, _Func& __f) { |
| 59 | + typename std::iterator_traits<_RandIter>::difference_type __n = __orig_n; |
| 60 | + auto __last = __first + __n; |
| 61 | + std::__for_each(__first, __last, __f); |
| 62 | + return std::move(__last); |
| 63 | +} |
| 64 | + |
| 65 | +#ifndef _LIBCPP_CXX03_LANG |
| 66 | +template <class _SegmentedIterator, |
| 67 | + class _Size, |
| 68 | + class _Func, |
| 69 | + __enable_if_t<!__has_random_access_iterator_category<_SegmentedIterator>::value && |
| 70 | + __is_segmented_iterator<_SegmentedIterator>::value && |
| 71 | + __has_random_access_iterator_category< |
| 72 | + typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value, |
| 73 | + int> = 0> |
| 74 | +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator |
| 75 | +__for_each_n(_SegmentedIterator __first, _Size __orig_n, _Func& __f) { |
| 76 | + using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator; |
| 77 | + return std::__for_each_n_segment(__first, __orig_n, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) { |
| 78 | + std::__for_each(__lfirst, __llast, __f); |
| 79 | + }); |
| 80 | +} |
| 81 | +#endif // !_LIBCPP_CXX03_LANG |
| 82 | + |
| 83 | +#if _LIBCPP_STD_VER >= 17 |
| 84 | + |
| 85 | +template <class _InputIterator, class _Size, class _Function> |
| 86 | +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator |
| 87 | +for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { |
| 88 | + return std::__for_each_n(__first, __orig_n, __f); |
| 89 | +} |
| 90 | + |
| 91 | +#endif // _LIBCPP_STD_VER >= 17 |
38 | 92 |
|
39 | 93 | _LIBCPP_END_NAMESPACE_STD
|
40 | 94 |
|
| 95 | +_LIBCPP_POP_MACROS |
| 96 | + |
41 | 97 | #endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H
|
0 commit comments