|
10 | 10 | #define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H
|
11 | 11 |
|
12 | 12 | #include <__algorithm/for_each.h>
|
| 13 | +#include <__algorithm/for_each_n.h> |
13 | 14 | #include <__algorithm/in_fun_result.h>
|
| 15 | +#include <__concepts/assignable.h> |
14 | 16 | #include <__config>
|
15 | 17 | #include <__functional/identity.h>
|
16 | 18 | #include <__functional/invoke.h>
|
@@ -42,11 +44,14 @@ struct __for_each {
|
42 | 44 | template <class _Iter, class _Sent, class _Proj, class _Func>
|
43 | 45 | _LIBCPP_HIDE_FROM_ABI constexpr static for_each_result<_Iter, _Func>
|
44 | 46 | __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) {
|
45 |
| - if constexpr (random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) { |
46 |
| - auto __n = __last - __first; |
47 |
| - auto __end = __first + __n; |
48 |
| - auto __f = [&](auto&& __val) { std::invoke(__func, std::invoke(__proj, __val)); }; |
49 |
| - std::__for_each(__first, __end, __f); |
| 47 | + if constexpr (std::assignable_from<_Iter&, _Sent>) { |
| 48 | + _Iter __end = std::move(__last); |
| 49 | + std::for_each(__first, __end, [&](auto&& __val) { std::invoke(__func, std::invoke(__proj, __val)); }); |
| 50 | + return {std::move(__end), std::move(__func)}; |
| 51 | + } else if constexpr (sized_sentinel_for<_Sent, _Iter>) { |
| 52 | + auto __end = std::for_each_n(__first, __last - __first, [&](auto&& __val) { |
| 53 | + std::invoke(__func, std::invoke(__proj, __val)); |
| 54 | + }); |
50 | 55 | return {std::move(__end), std::move(__func)};
|
51 | 56 | } else {
|
52 | 57 | for (; __first != __last; ++__first)
|
|
0 commit comments