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 = {});
25 #include "almost_satisfies_types.h"
26 #include "test_iterators.h"
32 template <class Iter
, class Sent
= Iter
>
33 concept HasForEachIt
= requires (Iter iter
, Sent sent
) { std::ranges::for_each(iter
, sent
, Callable
{}); };
35 static_assert(HasForEachIt
<int*>);
36 static_assert(!HasForEachIt
<InputIteratorNotDerivedFrom
>);
37 static_assert(!HasForEachIt
<InputIteratorNotIndirectlyReadable
>);
38 static_assert(!HasForEachIt
<InputIteratorNotInputOrOutputIterator
>);
39 static_assert(!HasForEachIt
<int*, SentinelForNotSemiregular
>);
40 static_assert(!HasForEachIt
<int*, SentinelForNotWeaklyEqualityComparableWith
>);
43 concept HasForEachItFunc
= requires(int* a
, int* b
, Func func
) { std::ranges::for_each(a
, b
, func
); };
45 static_assert(HasForEachItFunc
<Callable
>);
46 static_assert(!HasForEachItFunc
<IndirectUnaryPredicateNotPredicate
>);
47 static_assert(!HasForEachItFunc
<IndirectUnaryPredicateNotCopyConstructible
>);
49 template <class Range
>
50 concept HasForEachR
= requires (Range range
) { std::ranges::for_each(range
, Callable
{}); };
52 static_assert(HasForEachR
<UncheckedRange
<int*>>);
53 static_assert(!HasForEachR
<InputRangeNotDerivedFrom
>);
54 static_assert(!HasForEachR
<InputRangeNotIndirectlyReadable
>);
55 static_assert(!HasForEachR
<InputRangeNotInputOrOutputIterator
>);
56 static_assert(!HasForEachR
<InputRangeNotSentinelSemiregular
>);
57 static_assert(!HasForEachR
<InputRangeNotSentinelEqualityComparableWith
>);
60 concept HasForEachRFunc
= requires(UncheckedRange
<int*> a
, Func func
) { std::ranges::for_each(a
, func
); };
62 static_assert(HasForEachRFunc
<Callable
>);
63 static_assert(!HasForEachRFunc
<IndirectUnaryPredicateNotPredicate
>);
64 static_assert(!HasForEachRFunc
<IndirectUnaryPredicateNotCopyConstructible
>);
66 template <class Iter
, class Sent
= Iter
>
67 constexpr void test_iterator() {
70 auto func
= [i
= 0](int& a
) mutable { a
+= i
++; };
71 int a
[] = {1, 6, 3, 4};
72 std::same_as
<std::ranges::for_each_result
<Iter
, decltype(func
)>> decltype(auto) ret
=
73 std::ranges::for_each(Iter(a
), Sent(Iter(a
+ 4)), func
);
78 assert(base(ret
.in
) == a
+ 4);
84 auto func
= [i
= 0](int& a
) mutable { a
+= i
++; };
85 int a
[] = {1, 6, 3, 4};
86 auto range
= std::ranges::subrange(Iter(a
), Sent(Iter(a
+ 4)));
87 std::same_as
<std::ranges::for_each_result
<Iter
, decltype(func
)>> decltype(auto) ret
=
88 std::ranges::for_each(range
, func
);
93 assert(base(ret
.in
) == a
+ 4);
100 { // check that an empty range works
102 std::array
<int, 0> a
= {};
103 std::ranges::for_each(Iter(a
.data()), Sent(Iter(a
.data())), [](auto&) { assert(false); });
106 std::array
<int, 0> a
= {};
107 auto range
= std::ranges::subrange(Iter(a
.data()), Sent(Iter(a
.data())));
108 std::ranges::for_each(range
, [](auto&) { assert(false); });
113 constexpr bool test() {
114 test_iterator
<cpp17_input_iterator
<int*>, sentinel_wrapper
<cpp17_input_iterator
<int*>>>();
115 test_iterator
<cpp20_input_iterator
<int*>, sentinel_wrapper
<cpp20_input_iterator
<int*>>>();
116 test_iterator
<forward_iterator
<int*>>();
117 test_iterator
<bidirectional_iterator
<int*>>();
118 test_iterator
<random_access_iterator
<int*>>();
119 test_iterator
<contiguous_iterator
<int*>>();
120 test_iterator
<int*>();
122 { // check that std::invoke is used
128 S a
[] = {{1, 2}, {3, 4}, {5, 6}};
129 std::ranges::for_each(a
, a
+ 3, [](int& i
) { i
= 0; }, &S::check
);
130 assert(a
[0].check
== 0);
131 assert(a
[0].other
== 2);
132 assert(a
[1].check
== 0);
133 assert(a
[1].other
== 4);
134 assert(a
[2].check
== 0);
135 assert(a
[2].other
== 6);
138 S a
[] = {{1, 2}, {3, 4}, {5, 6}};
139 std::ranges::for_each(a
, [](int& i
) { i
= 0; }, &S::check
);
140 assert(a
[0].check
== 0);
141 assert(a
[0].other
== 2);
142 assert(a
[1].check
== 0);
143 assert(a
[1].other
== 4);
144 assert(a
[2].check
== 0);
145 assert(a
[2].other
== 6);
152 int main(int, char**) {
154 static_assert(test());