xref: /llvm-project/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp (revision a0cdd32b79318fc45e07bc0cef7e57308b1166ed)
1bd3f5a4bSLouis Dionne //===----------------------------------------------------------------------===//
2bd3f5a4bSLouis Dionne //
3bd3f5a4bSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bd3f5a4bSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5bd3f5a4bSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bd3f5a4bSLouis Dionne //
7bd3f5a4bSLouis Dionne //===----------------------------------------------------------------------===//
8bd3f5a4bSLouis Dionne 
9bd3f5a4bSLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
10bd3f5a4bSLouis Dionne // UNSUPPORTED: no-exceptions
11bd3f5a4bSLouis Dionne // `check_assertion.h` requires Unix headers and regex support.
12*a0cdd32bSStephan T. Lavavej // REQUIRES: has-unix-headers
13*a0cdd32bSStephan T. Lavavej // UNSUPPORTED: no-localization
14bd3f5a4bSLouis Dionne 
15bd3f5a4bSLouis Dionne // UNSUPPORTED: libcpp-has-no-incomplete-pstl
16bd3f5a4bSLouis Dionne 
17bd3f5a4bSLouis Dionne // <algorithm>
18bd3f5a4bSLouis Dionne // <numeric>
19bd3f5a4bSLouis Dionne //
20bd3f5a4bSLouis Dionne // Check that PSTL algorithms terminate on user-thrown exceptions.
21bd3f5a4bSLouis Dionne 
22bd3f5a4bSLouis Dionne #include <algorithm>
23bd3f5a4bSLouis Dionne #include <numeric>
24bd3f5a4bSLouis Dionne 
25bd3f5a4bSLouis Dionne #include "check_assertion.h"
26bd3f5a4bSLouis Dionne #include "test_execution_policies.h"
27bd3f5a4bSLouis Dionne #include "test_iterators.h"
28bd3f5a4bSLouis Dionne 
29bd3f5a4bSLouis Dionne template <class F>
assert_non_throwing(F f)30bd3f5a4bSLouis Dionne void assert_non_throwing(F f) {
31bd3f5a4bSLouis Dionne   // We wrap this whole test in EXPECT_STD_TERMINATE because if f() terminates, we want the test to pass,
32bd3f5a4bSLouis Dionne   // since this signals proper handling of user exceptions in the PSTL.
33bd3f5a4bSLouis Dionne   EXPECT_STD_TERMINATE([&] {
34bd3f5a4bSLouis Dionne     bool threw = false;
35bd3f5a4bSLouis Dionne     try {
36bd3f5a4bSLouis Dionne       f();
37bd3f5a4bSLouis Dionne     } catch (...) {
38bd3f5a4bSLouis Dionne       threw = true;
39bd3f5a4bSLouis Dionne     }
40bd3f5a4bSLouis Dionne     // If nothing was thrown, call std::terminate() to pass the EXPECT_STD_TERMINATE assertion.
41bd3f5a4bSLouis Dionne     // Otherwise, don't call std::terminate() to fail the assertion.
42bd3f5a4bSLouis Dionne     if (!threw)
43bd3f5a4bSLouis Dionne       std::terminate();
44bd3f5a4bSLouis Dionne   });
45bd3f5a4bSLouis Dionne }
46bd3f5a4bSLouis Dionne 
47bd3f5a4bSLouis Dionne struct ThrowToken {
activateThrowToken48bd3f5a4bSLouis Dionne   void activate() { active_ = true; }
deactivateThrowToken49bd3f5a4bSLouis Dionne   void deactivate() { active_ = false; }
activeThrowToken50bd3f5a4bSLouis Dionne   bool active() const { return active_; }
51bd3f5a4bSLouis Dionne 
52bd3f5a4bSLouis Dionne private:
53bd3f5a4bSLouis Dionne   bool active_{false};
54bd3f5a4bSLouis Dionne };
55bd3f5a4bSLouis Dionne 
56bd3f5a4bSLouis Dionne template <class Func>
57bd3f5a4bSLouis Dionne struct on_scope_exit {
on_scope_exiton_scope_exit58bd3f5a4bSLouis Dionne   explicit on_scope_exit(Func func) : func_(func) {}
~on_scope_exiton_scope_exit59bd3f5a4bSLouis Dionne   ~on_scope_exit() { func_(); }
60bd3f5a4bSLouis Dionne 
61bd3f5a4bSLouis Dionne private:
62bd3f5a4bSLouis Dionne   Func func_;
63bd3f5a4bSLouis Dionne };
64bd3f5a4bSLouis Dionne template <class Func>
65bd3f5a4bSLouis Dionne on_scope_exit(Func) -> on_scope_exit<Func>;
66bd3f5a4bSLouis Dionne 
main(int,char **)67bd3f5a4bSLouis Dionne int main(int, char**) {
68bd3f5a4bSLouis Dionne   test_execution_policies([&](auto&& policy) {
69bd3f5a4bSLouis Dionne     int a[] = {1, 2, 3, 4};
70bd3f5a4bSLouis Dionne     int b[] = {1, 2, 3};
71bd3f5a4bSLouis Dionne     int n   = 2;
72bd3f5a4bSLouis Dionne     int storage[999];
73bd3f5a4bSLouis Dionne     int val  = 99;
74bd3f5a4bSLouis Dionne     int init = 1;
75bd3f5a4bSLouis Dionne 
76bd3f5a4bSLouis Dionne     // We generate a certain number of "tokens" and we activate exactly one on each iteration. We then
77bd3f5a4bSLouis Dionne     // throw in a given operation only when that token is active. That way we check that each argument
78bd3f5a4bSLouis Dionne     // of the algorithm is handled properly.
79bd3f5a4bSLouis Dionne     ThrowToken tokens[7];
80bd3f5a4bSLouis Dionne     for (ThrowToken& t : tokens) {
81bd3f5a4bSLouis Dionne       t.activate();
82bd3f5a4bSLouis Dionne       on_scope_exit _([&] { t.deactivate(); });
83bd3f5a4bSLouis Dionne 
84bd3f5a4bSLouis Dionne       auto first1      = util::throw_on_move_iterator(std::begin(a), tokens[0].active() ? 1 : -1);
85bd3f5a4bSLouis Dionne       auto last1       = util::throw_on_move_iterator(std::end(a), tokens[1].active() ? 1 : -1);
86bd3f5a4bSLouis Dionne       auto first2      = util::throw_on_move_iterator(std::begin(b), tokens[2].active() ? 1 : -1);
87bd3f5a4bSLouis Dionne       auto last2       = util::throw_on_move_iterator(std::end(b), tokens[3].active() ? 1 : -1);
88bd3f5a4bSLouis Dionne       auto dest        = util::throw_on_move_iterator(std::end(storage), tokens[4].active() ? 1 : -1);
89bd3f5a4bSLouis Dionne       auto maybe_throw = [](ThrowToken const& token, auto f) {
90bd3f5a4bSLouis Dionne         return [&token, f](auto... args) {
91bd3f5a4bSLouis Dionne           if (token.active())
92bd3f5a4bSLouis Dionne             throw 1;
93bd3f5a4bSLouis Dionne           return f(args...);
94bd3f5a4bSLouis Dionne         };
95bd3f5a4bSLouis Dionne       };
96bd3f5a4bSLouis Dionne 
97bd3f5a4bSLouis Dionne       {
98bd3f5a4bSLouis Dionne         auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
99bd3f5a4bSLouis Dionne 
100bd3f5a4bSLouis Dionne         // all_of(first, last, pred)
101bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::all_of(policy, std::move(first1), std::move(last1), pred); });
102bd3f5a4bSLouis Dionne 
103bd3f5a4bSLouis Dionne         // any_of(first, last, pred)
104bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::any_of(policy, std::move(first1), std::move(last1), pred); });
105bd3f5a4bSLouis Dionne 
106bd3f5a4bSLouis Dionne         // none_of(first, last, pred)
107bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::none_of(policy, std::move(first1), std::move(last1), pred); });
108bd3f5a4bSLouis Dionne       }
109bd3f5a4bSLouis Dionne 
110bd3f5a4bSLouis Dionne       {
111bd3f5a4bSLouis Dionne         // copy(first, last, dest)
112bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
113bd3f5a4bSLouis Dionne           (void)std::copy(policy, std::move(first1), std::move(last1), std::move(dest));
114bd3f5a4bSLouis Dionne         });
115bd3f5a4bSLouis Dionne 
116bd3f5a4bSLouis Dionne         // copy_n(first, n, dest)
117bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::copy_n(policy, std::move(first1), n, std::move(dest)); });
118bd3f5a4bSLouis Dionne       }
119bd3f5a4bSLouis Dionne 
120bd3f5a4bSLouis Dionne       {
121bd3f5a4bSLouis Dionne         auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
122bd3f5a4bSLouis Dionne 
123bd3f5a4bSLouis Dionne         // count(first, last, val)
124bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::count(policy, std::move(first1), std::move(last1), val); });
125bd3f5a4bSLouis Dionne 
126bd3f5a4bSLouis Dionne         // count_if(first, last, pred)
127bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::count_if(policy, std::move(first1), std::move(last1), pred); });
128bd3f5a4bSLouis Dionne       }
129bd3f5a4bSLouis Dionne 
130bd3f5a4bSLouis Dionne       {
131bd3f5a4bSLouis Dionne         auto binary_pred = maybe_throw(tokens[5], [](int x, int y) -> bool { return x == y; });
132bd3f5a4bSLouis Dionne 
133bd3f5a4bSLouis Dionne         // equal(first1, last1, first2)
134bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
135bd3f5a4bSLouis Dionne           (void)std::equal(policy, std::move(first1), std::move(last1), std::move(first2));
136bd3f5a4bSLouis Dionne         });
137bd3f5a4bSLouis Dionne 
138bd3f5a4bSLouis Dionne         // equal(first1, last1, first2, binary_pred)
139bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
140bd3f5a4bSLouis Dionne           (void)std::equal(policy, std::move(first1), std::move(last1), std::move(first2), binary_pred);
141bd3f5a4bSLouis Dionne         });
142bd3f5a4bSLouis Dionne 
143bd3f5a4bSLouis Dionne         // equal(first1, last1, first2, last2)
144bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
145bd3f5a4bSLouis Dionne           (void)std::equal(policy, std::move(first1), std::move(last1), std::move(first2), std::move(last2));
146bd3f5a4bSLouis Dionne         });
147bd3f5a4bSLouis Dionne 
148bd3f5a4bSLouis Dionne         // equal(first1, last1, first2, last2, binary_pred)
149bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
150bd3f5a4bSLouis Dionne           (void)std::equal(
151bd3f5a4bSLouis Dionne               policy, std::move(first1), std::move(last1), std::move(first2), std::move(last2), binary_pred);
152bd3f5a4bSLouis Dionne         });
153bd3f5a4bSLouis Dionne       }
154bd3f5a4bSLouis Dionne 
155bd3f5a4bSLouis Dionne       {
156bd3f5a4bSLouis Dionne         // fill(first, last, val)
157bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::fill(policy, std::move(first1), std::move(last1), val); });
158bd3f5a4bSLouis Dionne 
159bd3f5a4bSLouis Dionne         // fill_n(first, n, val)
160bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::fill_n(policy, std::move(first1), n, val); });
161bd3f5a4bSLouis Dionne       }
162bd3f5a4bSLouis Dionne 
163bd3f5a4bSLouis Dionne       {
164bd3f5a4bSLouis Dionne         auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
165bd3f5a4bSLouis Dionne 
166bd3f5a4bSLouis Dionne         // find(first, last, val)
167bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::find(policy, std::move(first1), std::move(last1), val); });
168bd3f5a4bSLouis Dionne 
169bd3f5a4bSLouis Dionne         // find_if(first, last, pred)
170bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::find_if(policy, std::move(first1), std::move(last1), pred); });
171bd3f5a4bSLouis Dionne 
172bd3f5a4bSLouis Dionne         // find_if_not(first, last, pred)
173bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
174bd3f5a4bSLouis Dionne           (void)std::find_if_not(policy, std::move(first1), std::move(last1), pred);
175bd3f5a4bSLouis Dionne         });
176bd3f5a4bSLouis Dionne       }
177bd3f5a4bSLouis Dionne 
178bd3f5a4bSLouis Dionne       {
179bd3f5a4bSLouis Dionne         auto func = maybe_throw(tokens[5], [](int) {});
180bd3f5a4bSLouis Dionne 
181bd3f5a4bSLouis Dionne         // for_each(first, last, func)
182bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::for_each(policy, std::move(first1), std::move(last1), func); });
183bd3f5a4bSLouis Dionne 
184bd3f5a4bSLouis Dionne         // for_each_n(first, n, func)
185bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::for_each_n(policy, std::move(first1), n, func); });
186bd3f5a4bSLouis Dionne       }
187bd3f5a4bSLouis Dionne 
188bd3f5a4bSLouis Dionne       {
189bd3f5a4bSLouis Dionne         auto gen = maybe_throw(tokens[5], []() -> int { return 42; });
190bd3f5a4bSLouis Dionne 
191bd3f5a4bSLouis Dionne         // generate(first, last, func)
192bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::generate(policy, std::move(first1), std::move(last1), gen); });
193bd3f5a4bSLouis Dionne 
194bd3f5a4bSLouis Dionne         // generate_n(first, n, func)
195bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::generate_n(policy, std::move(first1), n, gen); });
196bd3f5a4bSLouis Dionne       }
197bd3f5a4bSLouis Dionne 
198bd3f5a4bSLouis Dionne       {
199bd3f5a4bSLouis Dionne         auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
200bd3f5a4bSLouis Dionne 
201bd3f5a4bSLouis Dionne         // is_partitioned(first, last, pred)
202bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
203bd3f5a4bSLouis Dionne           (void)std::is_partitioned(policy, std::move(first1), std::move(last1), pred);
204bd3f5a4bSLouis Dionne         });
205bd3f5a4bSLouis Dionne       }
206bd3f5a4bSLouis Dionne 
207bd3f5a4bSLouis Dionne       {
208bd3f5a4bSLouis Dionne         auto compare = maybe_throw(tokens[5], [](int x, int y) -> bool { return x < y; });
209bd3f5a4bSLouis Dionne 
210bd3f5a4bSLouis Dionne         // merge(first1, last1, first2, last2, dest)
211bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
212bd3f5a4bSLouis Dionne           (void)std::merge(
213bd3f5a4bSLouis Dionne               policy, std::move(first1), std::move(last1), std::move(first2), std::move(last2), std::move(dest));
214bd3f5a4bSLouis Dionne         });
215bd3f5a4bSLouis Dionne 
216bd3f5a4bSLouis Dionne         // merge(first1, last1, first2, last2, dest, comp)
217bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
218bd3f5a4bSLouis Dionne           (void)std::merge(
219bd3f5a4bSLouis Dionne               policy,
220bd3f5a4bSLouis Dionne               std::move(first1),
221bd3f5a4bSLouis Dionne               std::move(last1),
222bd3f5a4bSLouis Dionne               std::move(first2),
223bd3f5a4bSLouis Dionne               std::move(last2),
224bd3f5a4bSLouis Dionne               std::move(dest),
225bd3f5a4bSLouis Dionne               compare);
226bd3f5a4bSLouis Dionne         });
227bd3f5a4bSLouis Dionne       }
228bd3f5a4bSLouis Dionne 
229bd3f5a4bSLouis Dionne       {
230bd3f5a4bSLouis Dionne         // move(first, last, dest)
231bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
232bd3f5a4bSLouis Dionne           (void)std::move(policy, std::move(first1), std::move(last1), std::move(dest));
233bd3f5a4bSLouis Dionne         });
234bd3f5a4bSLouis Dionne       }
235bd3f5a4bSLouis Dionne 
236bd3f5a4bSLouis Dionne       {
237bd3f5a4bSLouis Dionne         auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
238bd3f5a4bSLouis Dionne 
239bd3f5a4bSLouis Dionne         // replace_if(first, last, pred, val)
240bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
241bd3f5a4bSLouis Dionne           (void)std::replace_if(policy, std::move(first1), std::move(last1), pred, val);
242bd3f5a4bSLouis Dionne         });
243bd3f5a4bSLouis Dionne 
244bd3f5a4bSLouis Dionne         // replace(first, last, val1, val2)
245bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
246bd3f5a4bSLouis Dionne           (void)std::replace(policy, std::move(first1), std::move(last1), val, val);
247bd3f5a4bSLouis Dionne         });
248bd3f5a4bSLouis Dionne 
249bd3f5a4bSLouis Dionne         // replace_copy_if(first, last, dest, pred, val)
250bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
251bd3f5a4bSLouis Dionne           (void)std::replace_copy_if(policy, std::move(first1), std::move(last1), std::move(dest), pred, val);
252bd3f5a4bSLouis Dionne         });
253bd3f5a4bSLouis Dionne 
254bd3f5a4bSLouis Dionne         // replace_copy(first, last, dest, val1, val2)
255bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
256bd3f5a4bSLouis Dionne           (void)std::replace_copy(policy, std::move(first1), std::move(last1), std::move(dest), val, val);
257bd3f5a4bSLouis Dionne         });
258bd3f5a4bSLouis Dionne       }
259bd3f5a4bSLouis Dionne 
260bd3f5a4bSLouis Dionne       {
261bd3f5a4bSLouis Dionne         auto mid1 = util::throw_on_move_iterator(std::begin(a) + 2, tokens[5].active() ? 1 : -1);
262bd3f5a4bSLouis Dionne 
263bd3f5a4bSLouis Dionne         // rotate_copy(first, mid, last, dest)
264bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
265bd3f5a4bSLouis Dionne           (void)std::rotate_copy(policy, std::move(first1), std::move(mid1), std::move(last1), std::move(dest));
266bd3f5a4bSLouis Dionne         });
267bd3f5a4bSLouis Dionne       }
268bd3f5a4bSLouis Dionne 
269bd3f5a4bSLouis Dionne       {
270bd3f5a4bSLouis Dionne         auto compare = maybe_throw(tokens[5], [](int x, int y) -> bool { return x < y; });
271bd3f5a4bSLouis Dionne 
272bd3f5a4bSLouis Dionne         // sort(first, last)
273bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::sort(policy, std::move(first1), std::move(last1)); });
274bd3f5a4bSLouis Dionne 
275bd3f5a4bSLouis Dionne         // sort(first, last, comp)
276bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::sort(policy, std::move(first1), std::move(last1), compare); });
277bd3f5a4bSLouis Dionne 
278bd3f5a4bSLouis Dionne         // stable_sort(first, last)
279bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::stable_sort(policy, std::move(first1), std::move(last1)); });
280bd3f5a4bSLouis Dionne 
281bd3f5a4bSLouis Dionne         // stable_sort(first, last, comp)
282bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
283bd3f5a4bSLouis Dionne           (void)std::stable_sort(policy, std::move(first1), std::move(last1), compare);
284bd3f5a4bSLouis Dionne         });
285bd3f5a4bSLouis Dionne       }
286bd3f5a4bSLouis Dionne 
287bd3f5a4bSLouis Dionne       {
288bd3f5a4bSLouis Dionne         auto unary  = maybe_throw(tokens[5], [](int x) -> int { return x * 2; });
289bd3f5a4bSLouis Dionne         auto binary = maybe_throw(tokens[5], [](int x, int y) -> int { return x * y; });
290bd3f5a4bSLouis Dionne 
291bd3f5a4bSLouis Dionne         // transform(first, last, dest, func)
292bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
293bd3f5a4bSLouis Dionne           (void)std::transform(policy, std::move(first1), std::move(last1), std::move(dest), unary);
294bd3f5a4bSLouis Dionne         });
295bd3f5a4bSLouis Dionne 
296bd3f5a4bSLouis Dionne         // transform(first1, last1, first2, dest, func)
297bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
298bd3f5a4bSLouis Dionne           (void)std::transform(policy, std::move(first1), std::move(last1), std::move(first2), std::move(dest), binary);
299bd3f5a4bSLouis Dionne         });
300bd3f5a4bSLouis Dionne       }
301bd3f5a4bSLouis Dionne 
302bd3f5a4bSLouis Dionne       {
303bd3f5a4bSLouis Dionne         auto reduction        = maybe_throw(tokens[5], [](int x, int y) -> int { return x + y; });
304bd3f5a4bSLouis Dionne         auto transform_unary  = maybe_throw(tokens[6], [](int x) -> int { return x * 2; });
305bd3f5a4bSLouis Dionne         auto transform_binary = maybe_throw(tokens[6], [](int x, int y) -> int { return x * y; });
306bd3f5a4bSLouis Dionne 
307bd3f5a4bSLouis Dionne         // transform_reduce(first1, last1, first2, init)
308bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
309bd3f5a4bSLouis Dionne           (void)std::transform_reduce(policy, std::move(first1), std::move(last1), std::move(first2), init);
310bd3f5a4bSLouis Dionne         });
311bd3f5a4bSLouis Dionne 
312bd3f5a4bSLouis Dionne         // transform_reduce(first1, last1, init, reduce, transform)
313bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
314bd3f5a4bSLouis Dionne           (void)std::transform_reduce(policy, std::move(first1), std::move(last1), init, reduction, transform_unary);
315bd3f5a4bSLouis Dionne         });
316bd3f5a4bSLouis Dionne 
317bd3f5a4bSLouis Dionne         // transform_reduce(first1, last1, first2, init, reduce, transform)
318bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
319bd3f5a4bSLouis Dionne           (void)std::transform_reduce(
320bd3f5a4bSLouis Dionne               policy, std::move(first1), std::move(last1), std::move(first2), init, reduction, transform_binary);
321bd3f5a4bSLouis Dionne         });
322bd3f5a4bSLouis Dionne       }
323bd3f5a4bSLouis Dionne 
324bd3f5a4bSLouis Dionne       {
325bd3f5a4bSLouis Dionne         auto reduction = maybe_throw(tokens[5], [](int x, int y) -> int { return x + y; });
326bd3f5a4bSLouis Dionne 
327bd3f5a4bSLouis Dionne         // reduce(first, last)
328bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::reduce(policy, std::move(first1), std::move(last1)); });
329bd3f5a4bSLouis Dionne 
330bd3f5a4bSLouis Dionne         // reduce(first, last, init)
331bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] { (void)std::reduce(policy, std::move(first1), std::move(last1), init); });
332bd3f5a4bSLouis Dionne 
333bd3f5a4bSLouis Dionne         // reduce(first, last, init, binop)
334bd3f5a4bSLouis Dionne         assert_non_throwing([=, &policy] {
335bd3f5a4bSLouis Dionne           (void)std::reduce(policy, std::move(first1), std::move(last1), init, reduction);
336bd3f5a4bSLouis Dionne         });
337bd3f5a4bSLouis Dionne       }
338bd3f5a4bSLouis Dionne     }
339bd3f5a4bSLouis Dionne   });
340bd3f5a4bSLouis Dionne }
341