xref: /llvm-project/libcxx/test/std/numerics/numeric.ops/reduce/pstl.reduce.pass.cpp (revision bd3f5a4bd3d9d7ee8ae801c24c5081073b20abd4)
1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14
10 
11 // UNSUPPORTED: libcpp-has-no-incomplete-pstl
12 
13 // <numeric>
14 
15 // template<class ExecutionPolicy, class ForwardIterator>
16 //   typename iterator_traits<ForwardIterator>::value_type
17 //     reduce(ExecutionPolicy&& exec,
18 //            ForwardIterator first, ForwardIterator last);
19 // template<class ExecutionPolicy, class ForwardIterator, class T, class BinaryOperation>
20 //   T reduce(ExecutionPolicy&& exec,
21 //            ForwardIterator first, ForwardIterator last, T init,
22 //            BinaryOperation binary_op);
23 
24 #include <numeric>
25 #include <vector>
26 
27 #include "MoveOnly.h"
28 #include "test_execution_policies.h"
29 #include "test_iterators.h"
30 #include "test_macros.h"
31 
32 template <class Iter, class ValueT>
33 struct Test {
34   template <class Policy>
operator ()Test35   void operator()(Policy&& policy) {
36     for (const auto& pair : {std::pair{0, 34}, {1, 36}, {2, 39}, {100, 5184}, {350, 61809}}) {
37       auto [size, expected] = pair;
38       std::vector<int> a(size);
39       for (int i = 0; i != size; ++i)
40         a[i] = i;
41 
42       {
43         decltype(auto) ret = std::reduce(
44             policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), ValueT(34), [](ValueT i, ValueT j) {
45               return i + j + 2;
46             });
47         static_assert(std::is_same_v<decltype(ret), ValueT>);
48         assert(ret == ValueT(expected));
49       }
50       {
51         decltype(auto) ret = std::reduce(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)), ValueT(34));
52         static_assert(std::is_same_v<decltype(ret), ValueT>);
53         assert(ret == expected - 2 * size);
54       }
55       {
56         decltype(auto) ret = std::reduce(policy, Iter(std::data(a)), Iter(std::data(a) + std::size(a)));
57         static_assert(std::is_same_v<decltype(ret), typename std::iterator_traits<Iter>::value_type>);
58         assert(ret == expected - 2 * size - 34);
59       }
60     }
61   }
62 };
63 
main(int,char **)64 int main(int, char**) {
65   types::for_each(types::forward_iterator_list<int*>{}, types::apply_type_identity{[](auto v) {
66                     using Iter = typename decltype(v)::type;
67                     types::for_each(
68                         types::type_list<int, MoveOnly>{},
69                         TestIteratorWithPolicies<types::partial_instantiation<Test, Iter>::template apply>{});
70                   }});
71 
72   return 0;
73 }
74