1 // -*- C++ -*-
2 // { dg-options "-ltbb" }
3 // { dg-do run { target c++17 } }
4 // { dg-timeout-factor 4 }
5 // { dg-require-effective-target tbb-backend }
6 
7 //===-- find_end.pass.cpp -------------------------------------------------===//
8 //
9 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
10 // See https://llvm.org/LICENSE.txt for license information.
11 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "pstl/pstl_test_config.h"
16 
17 #ifdef PSTL_STANDALONE_TESTS
18 #include "pstl/execution"
19 #include "pstl/algorithm"
20 #else
21 #include <execution>
22 #include <algorithm>
23 #endif // PSTL_STANDALONE_TESTS
24 
25 #include "pstl/test_utils.h"
26 
27 using namespace TestUtils;
28 
29 struct test_one_policy
30 {
31 #if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN ||                                                            \
32     _PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
33     template <typename Iterator1, typename Iterator2, typename Predicate>
34     void
operator ()test_one_policy35     operator()(pstl::execution::unsequenced_policy, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub,
36                Predicate pred)
37     {
38     }
39     template <typename Iterator1, typename Iterator2, typename Predicate>
40     void
operator ()test_one_policy41     operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub,
42                Predicate pred)
43     {
44     }
45 #endif
46 
47     template <typename ExecutionPolicy, typename Iterator1, typename Iterator2, typename Predicate>
48     void
operator ()test_one_policy49     operator()(ExecutionPolicy&& exec, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub, Predicate pred)
50     {
51         using namespace std;
52         // For find_end
53         {
54             auto expected = find_end(b, e, bsub, esub, pred);
55             auto actual = find_end(exec, b, e, bsub, esub);
56             EXPECT_TRUE(actual == expected, "wrong return result from find_end");
57 
58             actual = find_end(exec, b, e, bsub, esub, pred);
59             EXPECT_TRUE(actual == expected, "wrong return result from find_end with a predicate");
60         }
61 
62         // For search
63         {
64             auto expected = search(b, e, bsub, esub, pred);
65             auto actual = search(exec, b, e, bsub, esub);
66             EXPECT_TRUE(actual == expected, "wrong return result from search");
67 
68             actual = search(exec, b, e, bsub, esub, pred);
69             EXPECT_TRUE(actual == expected, "wrong return result from search with a predicate");
70         }
71     }
72 };
73 
74 template <typename T>
75 void
test(const std::size_t bits)76 test(const std::size_t bits)
77 {
78 
79     const std::size_t max_n1 = 1000;
80     const std::size_t max_n2 = (max_n1 * 10) / 8;
81     Sequence<T> in(max_n1, [max_n1, bits](std::size_t) { return T(2 * HashBits(max_n1, bits - 1) ^ 1); });
82     Sequence<T> sub(max_n2, [max_n1, bits](std::size_t) { return T(2 * HashBits(max_n1, bits - 1)); });
83     for (std::size_t n1 = 0; n1 <= max_n1; n1 = n1 <= 16 ? n1 + 1 : size_t(3.1415 * n1))
84     {
85         std::size_t sub_n[] = {0, 1, 3, n1, (n1 * 10) / 8};
86         std::size_t res[] = {0, 1, n1 / 2, n1};
87         for (auto n2 : sub_n)
88         {
89             for (auto r : res)
90             {
91                 std::size_t i = r, isub = 0;
92                 for (; i < n1 && isub < n2; ++i, ++isub)
93                     in[i] = sub[isub];
94                 invoke_on_all_policies(test_one_policy(), in.begin(), in.begin() + n1, sub.begin(), sub.begin() + n2,
95                                        std::equal_to<T>());
96                 invoke_on_all_policies(test_one_policy(), in.cbegin(), in.cbegin() + n1, sub.cbegin(),
97                                        sub.cbegin() + n2, std::equal_to<T>());
98             }
99         }
100     }
101 }
102 
103 template <typename T>
104 struct test_non_const
105 {
106     template <typename Policy, typename FirstIterator, typename SecondInterator>
107     void
operator ()test_non_const108     operator()(Policy&& exec, FirstIterator first_iter, SecondInterator second_iter)
109     {
110         invoke_if(exec, [&]() {
111             find_end(exec, first_iter, first_iter, second_iter, second_iter, non_const(std::equal_to<T>()));
112             search(exec, first_iter, first_iter, second_iter, second_iter, non_const(std::equal_to<T>()));
113         });
114     }
115 };
116 
117 int32_t
main()118 main()
119 {
120     test<int32_t>(8 * sizeof(int32_t));
121     test<uint16_t>(8 * sizeof(uint16_t));
122     test<float64_t>(53);
123 #if !_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN
124     test<bool>(1);
125 #endif
126 
127     test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
128 
129     std::cout << done() << std::endl;
130     return 0;
131 }
132