1 // -*- C++ -*-
2 //===-- generate.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 #include "support/pstl_test_config.h"
13 
14 #include <atomic>
15 #include <execution>
16 #include <algorithm>
17 
18 #include "support/utils.h"
19 
20 using namespace TestUtils;
21 
22 template <typename T>
23 struct Generator_count
24 {
25     const T def_val = T(-1);
26     T
operator ()Generator_count27     operator()()
28     {
29         return def_val;
30     }
31     T
default_valueGenerator_count32     default_value() const
33     {
34         return def_val;
35     }
36 };
37 
38 struct test_generate
39 {
40     template <typename Policy, typename Iterator, typename Size>
41     void
operator ()test_generate42     operator()(Policy&& exec, Iterator first, Iterator last, Size n)
43     {
44         using namespace std;
45         typedef typename std::iterator_traits<Iterator>::value_type T;
46 
47         // Try random-access iterator
48         {
49             Generator_count<T> g;
50             generate(exec, first, last, g);
51             Size count = std::count(first, last, g.default_value());
52             EXPECT_TRUE(count == n, "generate wrong result for generate");
53             std::fill(first, last, T(0));
54         }
55 
56         {
57             Generator_count<T> g;
58             const auto m = n / 2;
59             auto actual_last = generate_n(exec, first, m, g);
60             Size count = std::count(first, actual_last, g.default_value());
61             EXPECT_TRUE(count == m && actual_last == std::next(first, m), "generate_n wrong result for generate_n");
62             std::fill(first, actual_last, T(0));
63         }
64     }
65 };
66 
67 template <typename T>
68 void
test_generate_by_type()69 test_generate_by_type()
70 {
71     for (size_t n = 0; n <= 100000; n = n < 16 ? n + 1 : size_t(3.1415 * n))
72     {
73         Sequence<T> in(n, [](size_t) -> T { return T(0); }); //fill by zero
74 
75         invoke_on_all_policies(test_generate(), in.begin(), in.end(), in.size());
76     }
77 }
78 
79 template <typename T>
80 struct test_non_const
81 {
82     template <typename Policy, typename Iterator>
83     void
operator ()test_non_const84     operator()(Policy&& exec, Iterator iter)
85     {
86         auto gen = []() { return T(0); };
87 
88         generate(exec, iter, iter, non_const(gen));
89         generate_n(exec, iter, 0, non_const(gen));
90     }
91 };
92 
93 int
main()94 main()
95 {
96 
97     test_generate_by_type<int32_t>();
98     test_generate_by_type<float64_t>();
99 
100     test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
101 
102     std::cout << done() << std::endl;
103     return 0;
104 }
105