1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++03, c++11, c++14, c++17
12 // template<input_iterator I, sentinel_for<I> S, class Proj = identity,
13 // indirectly_unary_invocable<projected<I, Proj>> Fun>
14 // constexpr ranges::for_each_result<I, Fun>
15 // ranges::for_each(I first, S last, Fun f, Proj proj = {});
16 // template<input_range R, class Proj = identity,
17 // indirectly_unary_invocable<projected<iterator_t<R>, Proj>> Fun>
18 // constexpr ranges::for_each_result<borrowed_iterator_t<R>, Fun>
19 // ranges::for_each(R&& r, Fun f, Proj proj = {});
24 #include "almost_satisfies_types.h"
25 #include "test_iterators.h"
31 template <class Iter
, class Sent
= Iter
>
32 concept HasForEachIt
= requires (Iter iter
, Sent sent
) { std::ranges::for_each(iter
, sent
, Callable
{}); };
34 static_assert(HasForEachIt
<int*>);
35 static_assert(!HasForEachIt
<InputIteratorNotDerivedFrom
>);
36 static_assert(!HasForEachIt
<InputIteratorNotIndirectlyReadable
>);
37 static_assert(!HasForEachIt
<InputIteratorNotInputOrOutputIterator
>);
38 static_assert(!HasForEachIt
<int*, SentinelForNotSemiregular
>);
39 static_assert(!HasForEachIt
<int*, SentinelForNotWeaklyEqualityComparableWith
>);
42 concept HasForEachItFunc
= requires(int* a
, int* b
, Func func
) { std::ranges::for_each(a
, b
, func
); };
44 static_assert(HasForEachItFunc
<Callable
>);
45 static_assert(!HasForEachItFunc
<IndirectUnaryPredicateNotPredicate
>);
46 static_assert(!HasForEachItFunc
<IndirectUnaryPredicateNotCopyConstructible
>);
48 template <class Range
>
49 concept HasForEachR
= requires (Range range
) { std::ranges::for_each(range
, Callable
{}); };
51 static_assert(HasForEachR
<UncheckedRange
<int*>>);
52 static_assert(!HasForEachR
<InputRangeNotDerivedFrom
>);
53 static_assert(!HasForEachR
<InputRangeNotIndirectlyReadable
>);
54 static_assert(!HasForEachR
<InputRangeNotInputOrOutputIterator
>);
55 static_assert(!HasForEachR
<InputRangeNotSentinelSemiregular
>);
56 static_assert(!HasForEachR
<InputRangeNotSentinelEqualityComparableWith
>);
59 concept HasForEachRFunc
= requires(UncheckedRange
<int*> a
, Func func
) { std::ranges::for_each(a
, func
); };
61 static_assert(HasForEachRFunc
<Callable
>);
62 static_assert(!HasForEachRFunc
<IndirectUnaryPredicateNotPredicate
>);
63 static_assert(!HasForEachRFunc
<IndirectUnaryPredicateNotCopyConstructible
>);
65 template <class Iter
, class Sent
= Iter
>
66 constexpr void test_iterator() {
69 auto func
= [i
= 0](int& a
) mutable { a
+= i
++; };
70 int a
[] = {1, 6, 3, 4};
71 std::same_as
<std::ranges::for_each_result
<Iter
, decltype(func
)>> decltype(auto) ret
=
72 std::ranges::for_each(Iter(a
), Sent(Iter(a
+ 4)), func
);
77 assert(base(ret
.in
) == a
+ 4);
83 auto func
= [i
= 0](int& a
) mutable { a
+= i
++; };
84 int a
[] = {1, 6, 3, 4};
85 auto range
= std::ranges::subrange(Iter(a
), Sent(Iter(a
+ 4)));
86 std::same_as
<std::ranges::for_each_result
<Iter
, decltype(func
)>> decltype(auto) ret
=
87 std::ranges::for_each(range
, func
);
92 assert(base(ret
.in
) == a
+ 4);
99 { // check that an empty range works
102 std::ranges::for_each(Iter(a
), Sent(Iter(a
)), [](auto&) { assert(false); });
106 auto range
= std::ranges::subrange(Iter(a
), Sent(Iter(a
)));
107 std::ranges::for_each(range
, [](auto&) { assert(false); });
112 constexpr bool test() {
113 test_iterator
<cpp17_input_iterator
<int*>, sentinel_wrapper
<cpp17_input_iterator
<int*>>>();
114 test_iterator
<cpp20_input_iterator
<int*>, sentinel_wrapper
<cpp20_input_iterator
<int*>>>();
115 test_iterator
<forward_iterator
<int*>>();
116 test_iterator
<bidirectional_iterator
<int*>>();
117 test_iterator
<random_access_iterator
<int*>>();
118 test_iterator
<contiguous_iterator
<int*>>();
119 test_iterator
<int*>();
121 { // check that std::invoke is used
127 S a
[] = {{1, 2}, {3, 4}, {5, 6}};
128 std::ranges::for_each(a
, a
+ 3, [](int& i
) { i
= 0; }, &S::check
);
129 assert(a
[0].check
== 0);
130 assert(a
[0].other
== 2);
131 assert(a
[1].check
== 0);
132 assert(a
[1].other
== 4);
133 assert(a
[2].check
== 0);
134 assert(a
[2].other
== 6);
137 S a
[] = {{1, 2}, {3, 4}, {5, 6}};
138 std::ranges::for_each(a
, [](int& i
) { i
= 0; }, &S::check
);
139 assert(a
[0].check
== 0);
140 assert(a
[0].other
== 2);
141 assert(a
[1].check
== 0);
142 assert(a
[1].other
== 4);
143 assert(a
[2].check
== 0);
144 assert(a
[2].other
== 6);
151 int main(int, char**) {
153 static_assert(test());