1 | // -*- C++ -*- |
2 | //===-- count.pass.cpp ----------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | // UNSUPPORTED: c++03, c++11, c++14 |
11 | |
12 | // Tests for count and count_if |
13 | #include "support/pstl_test_config.h" |
14 | |
15 | #include <execution> |
16 | #include <algorithm> |
17 | |
18 | #include "support/utils.h" |
19 | |
20 | using namespace TestUtils; |
21 | |
22 | struct test_count |
23 | { |
24 | template <typename Policy, typename Iterator, typename T> |
25 | void |
26 | operator()(Policy&& exec, Iterator first, Iterator last, T needle) |
27 | { |
28 | auto expected = std::count(first, last, needle); |
29 | auto result = std::count(exec, first, last, needle); |
30 | EXPECT_EQ(expected, result, "wrong count result" ); |
31 | } |
32 | }; |
33 | |
34 | struct test_count_if |
35 | { |
36 | template <typename Policy, typename Iterator, typename Predicate> |
37 | void |
38 | operator()(Policy&& exec, Iterator first, Iterator last, Predicate pred) |
39 | { |
40 | auto expected = std::count_if(first, last, pred); |
41 | auto result = std::count_if(exec, first, last, pred); |
42 | EXPECT_EQ(expected, result, "wrong count_if result" ); |
43 | } |
44 | }; |
45 | |
46 | template <typename T> |
47 | class IsEqual |
48 | { |
49 | T value; |
50 | |
51 | public: |
52 | IsEqual(T value_, OddTag) : value(value_) {} |
53 | bool |
54 | operator()(const T& x) const |
55 | { |
56 | return x == value; |
57 | } |
58 | }; |
59 | |
60 | template <typename In, typename T, typename Predicate, typename Convert> |
61 | void |
62 | test(T needle, Predicate pred, Convert convert) |
63 | { |
64 | // Try sequences of various lengths. |
65 | for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n)) |
66 | { |
67 | Sequence<In> in(n, [=](size_t k) -> In { |
68 | // Sprinkle "42" and "50" early, so that short sequences have non-zero count. |
69 | return convert((n - k - 1) % 3 == 0 ? 42 : (n - k - 2) % 5 == 0 ? 50 : 3 * (int(k) % 1000 - 500)); |
70 | }); |
71 | invoke_on_all_policies(test_count(), in.begin(), in.end(), needle); |
72 | invoke_on_all_policies(test_count_if(), in.begin(), in.end(), pred); |
73 | |
74 | invoke_on_all_policies(test_count(), in.cbegin(), in.cend(), needle); |
75 | invoke_on_all_policies(test_count_if(), in.cbegin(), in.cend(), pred); |
76 | } |
77 | } |
78 | |
79 | struct test_non_const |
80 | { |
81 | template <typename Policy, typename Iterator> |
82 | void |
83 | operator()(Policy&& exec, Iterator iter) |
84 | { |
85 | auto is_even = [&](float64_t v) { |
86 | uint32_t i = (uint32_t)v; |
87 | return i % 2 == 0; |
88 | }; |
89 | count_if(exec, iter, iter, non_const(is_even)); |
90 | } |
91 | }; |
92 | |
93 | int |
94 | main() |
95 | { |
96 | test<int32_t>(needle: 42, pred: IsEqual<int32_t>(50, OddTag()), convert: [](int32_t j) { return j; }); |
97 | #if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN) |
98 | test<int32_t>(needle: 42, pred: [](const int32_t&) { return true; }, convert: [](int32_t j) { return j; }); |
99 | #endif |
100 | test<float64_t>(needle: 42, pred: IsEqual<float64_t>(50, OddTag()), convert: [](int32_t j) { return float64_t(j); }); |
101 | test<Number>(needle: Number(42, OddTag()), pred: IsEqual<Number>(Number(50, OddTag()), OddTag()), |
102 | convert: [](int32_t j) { return Number(j, OddTag()); }); |
103 | |
104 | test_algo_basic_single<int32_t>(f: run_for_rnd_fw<test_non_const>()); |
105 | |
106 | std::cout << done() << std::endl; |
107 | return 0; |
108 | } |
109 | |