1 // -*- C++ -*-
2 // { dg-options "-std=gnu++17 -ltbb" }
3 // { dg-do run { target c++17 } }
4 // { dg-require-effective-target tbb-backend }
5 
6 //===-- fill.pass.cpp -----------------------------------------------------===//
7 //
8 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
9 // See https://llvm.org/LICENSE.txt for license information.
10 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "pstl/pstl_test_config.h"
15 
16 #ifdef PSTL_STANDALONE_TESTS
17 
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_fill
30 {
31     template <typename It, typename T>
32     bool
checktest_fill33     check(It first, It last, const T& value)
34     {
35         for (; first != last; ++first)
36             if (*first != value)
37                 return false;
38         return true;
39     }
40 
41     template <typename Policy, typename Iterator, typename T>
42     void
operator ()test_fill43     operator()(Policy&& exec, Iterator first, Iterator last, const T& value)
44     {
45         fill(first, last, T(value + 1)); // initialize memory with different value
46 
47         fill(exec, first, last, value);
48         EXPECT_TRUE(check(first, last, value), "fill wrong result");
49     }
50 };
51 
52 struct test_fill_n
53 {
54     template <typename It, typename Size, typename T>
55     bool
checktest_fill_n56     check(It first, Size n, const T& value)
57     {
58         for (Size i = 0; i < n; ++i, ++first)
59             if (*first != value)
60                 return false;
61         return true;
62     }
63 
64     template <typename Policy, typename Iterator, typename Size, typename T>
65     void
operator ()test_fill_n66     operator()(Policy&& exec, Iterator first, Size n, const T& value)
67     {
68         fill_n(first, n, T(value + 1)); // initialize memory with different value
69 
70         const Iterator one_past_last = fill_n(exec, first, n, value);
71         const Iterator expected_return = std::next(first, n);
72 
73         EXPECT_TRUE(expected_return == one_past_last, "fill_n should return Iterator to one past the element assigned");
74         EXPECT_TRUE(check(first, n, value), "fill_n wrong result");
75 
76         //n == -1
77         const Iterator res = fill_n(exec, first, -1, value);
78         EXPECT_TRUE(res == first, "fill_n wrong result for n == -1");
79     }
80 };
81 
82 template <typename T>
83 void
test_fill_by_type(std::size_t n)84 test_fill_by_type(std::size_t n)
85 {
86     Sequence<T> in(n, [](std::size_t v) -> T { return T(0); }); //fill with zeros
87     T value = -1;
88 
89     invoke_on_all_policies(test_fill(), in.begin(), in.end(), value);
90     invoke_on_all_policies(test_fill_n(), in.begin(), n, value);
91 }
92 
93 int32_t
main()94 main()
95 {
96 
97     const std::size_t N = 100000;
98 
99     for (std::size_t n = 0; n < N; n = n < 16 ? n + 1 : size_t(3.1415 * n))
100     {
101         test_fill_by_type<int32_t>(n);
102         test_fill_by_type<float64_t>(n);
103     }
104 
105     std::cout << done() << std::endl;
106 
107     return 0;
108 }
109