1 // Copyright (c) 2014-2015 Hartmut Kaiser
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #if !defined(HPX_PARALLEL_TEST_FOREACH_MAY26_15_1414)
7 #define HPX_PARALLEL_TEST_FOREACH_MAY26_15_1414
8
9 #include <hpx/include/parallel_container_algorithm.hpp>
10 #include <hpx/util/lightweight_test.hpp>
11 #include <hpx/util/iterator_range.hpp>
12
13 #include <atomic>
14 #include <cstddef>
15 #include <iterator>
16 #include <utility>
17 #include <vector>
18
19 #include "test_utils.hpp"
20
21 ////////////////////////////////////////////////////////////////////////////////
22 template <typename ExPolicy, typename IteratorTag, typename Proj>
test_for_each(ExPolicy && policy,IteratorTag,Proj && proj)23 void test_for_each(ExPolicy && policy, IteratorTag, Proj && proj)
24 {
25 BOOST_STATIC_ASSERT(hpx::parallel::execution::is_execution_policy<ExPolicy>::value);
26
27 typedef std::vector<std::size_t>::iterator base_iterator;
28 typedef test::test_iterator<base_iterator, IteratorTag> iterator;
29
30 std::vector<std::size_t> c(10007);
31 std::fill(std::begin(c), std::end(c), std::size_t(42));
32
33 std::atomic<std::size_t> count(0);
34
35 iterator result =
36 hpx::parallel::for_each(std::forward<ExPolicy>(policy),
37 hpx::util::make_iterator_range(
38 iterator(std::begin(c)), iterator(std::end(c))
39 ),
40 [&count, &proj](std::size_t v) {
41 HPX_TEST_EQ(v, proj(std::size_t(42)));
42 ++count;
43 },
44 proj);
45
46 HPX_TEST(result == iterator(std::end(c)));
47 HPX_TEST_EQ(count, c.size());
48 }
49
50 template <typename ExPolicy, typename IteratorTag, typename Proj>
test_for_each_async(ExPolicy && p,IteratorTag,Proj && proj)51 void test_for_each_async(ExPolicy && p, IteratorTag, Proj && proj)
52 {
53 typedef std::vector<std::size_t>::iterator base_iterator;
54 typedef test::test_iterator<base_iterator, IteratorTag> iterator;
55
56 std::vector<std::size_t> c(10007);
57 std::fill(std::begin(c), std::end(c), std::size_t(42));
58
59 std::atomic<std::size_t> count(0);
60
61 hpx::future<iterator> f =
62 hpx::parallel::for_each(std::forward<ExPolicy>(p),
63 hpx::util::make_iterator_range(
64 iterator(std::begin(c)), iterator(std::end(c))
65 ),
66 [&count, &proj](std::size_t v) {
67 HPX_TEST_EQ(v, proj(std::size_t(42)));
68 ++count;
69 },
70 proj);
71 f.wait();
72
73 HPX_TEST(f.get() == iterator(std::end(c)));
74 HPX_TEST_EQ(count, c.size());
75 }
76
77 ////////////////////////////////////////////////////////////////////////////////
78 template <typename ExPolicy, typename IteratorTag, typename Proj>
test_for_each_exception(ExPolicy policy,IteratorTag,Proj && proj)79 void test_for_each_exception(ExPolicy policy, IteratorTag, Proj && proj)
80 {
81 BOOST_STATIC_ASSERT(hpx::parallel::execution::is_execution_policy<ExPolicy>::value);
82
83 typedef std::vector<std::size_t>::iterator base_iterator;
84 typedef test::test_iterator<base_iterator, IteratorTag> iterator;
85
86 std::vector<std::size_t> c(10007);
87 std::fill(std::begin(c), std::end(c), std::size_t(42));
88
89 bool caught_exception = false;
90 try {
91 hpx::parallel::for_each(policy,
92 hpx::util::make_iterator_range(
93 iterator(std::begin(c)), iterator(std::end(c))
94 ),
95 [](std::size_t v) { throw std::runtime_error("test"); },
96 proj);
97
98 HPX_TEST(false);
99 }
100 catch(hpx::exception_list const& e) {
101 caught_exception = true;
102 test::test_num_exceptions<ExPolicy, IteratorTag>::call(policy, e);
103 }
104 catch(...) {
105 HPX_TEST(false);
106 }
107
108 HPX_TEST(caught_exception);
109 }
110
111 template <typename ExPolicy, typename IteratorTag, typename Proj>
test_for_each_exception_async(ExPolicy p,IteratorTag,Proj && proj)112 void test_for_each_exception_async(ExPolicy p, IteratorTag, Proj && proj)
113 {
114 typedef std::vector<std::size_t>::iterator base_iterator;
115 typedef test::test_iterator<base_iterator, IteratorTag> iterator;
116
117 std::vector<std::size_t> c(10007);
118 std::fill(std::begin(c), std::end(c), std::size_t(42));
119
120 bool caught_exception = false;
121 bool returned_from_algorithm = false;
122 try {
123 hpx::future<void> f =
124 hpx::parallel::for_each(p,
125 hpx::util::make_iterator_range(
126 iterator(std::begin(c)), iterator(std::end(c))
127 ),
128 [](std::size_t v) { throw std::runtime_error("test"); },
129 proj);
130 returned_from_algorithm = true;
131 f.get();
132
133 HPX_TEST(false);
134 }
135 catch(hpx::exception_list const& e) {
136 caught_exception = true;
137 test::test_num_exceptions<ExPolicy, IteratorTag>::call(p, e);
138 }
139 catch(...) {
140 HPX_TEST(false);
141 }
142
143 HPX_TEST(caught_exception);
144 HPX_TEST(returned_from_algorithm);
145 }
146
147 ////////////////////////////////////////////////////////////////////////////////
148 template <typename ExPolicy, typename IteratorTag, typename Proj>
test_for_each_bad_alloc(ExPolicy policy,IteratorTag,Proj && proj)149 void test_for_each_bad_alloc(ExPolicy policy, IteratorTag, Proj && proj)
150 {
151 BOOST_STATIC_ASSERT(hpx::parallel::execution::is_execution_policy<ExPolicy>::value);
152
153 typedef std::vector<std::size_t>::iterator base_iterator;
154 typedef test::test_iterator<base_iterator, IteratorTag> iterator;
155
156 std::vector<std::size_t> c(10007);
157 std::fill(std::begin(c), std::end(c), std::size_t(42));
158
159 bool caught_exception = false;
160 try {
161 hpx::parallel::for_each(policy,
162 hpx::util::make_iterator_range(
163 iterator(std::begin(c)), iterator(std::end(c))
164 ),
165 [](std::size_t v) { throw std::bad_alloc(); },
166 proj);
167
168 HPX_TEST(false);
169 }
170 catch(std::bad_alloc const&) {
171 caught_exception = true;
172 }
173 catch(...) {
174 HPX_TEST(false);
175 }
176
177 HPX_TEST(caught_exception);
178 }
179
180 template <typename ExPolicy, typename IteratorTag, typename Proj>
test_for_each_bad_alloc_async(ExPolicy p,IteratorTag,Proj && proj)181 void test_for_each_bad_alloc_async(ExPolicy p, IteratorTag, Proj && proj)
182 {
183 typedef std::vector<std::size_t>::iterator base_iterator;
184 typedef test::test_iterator<base_iterator, IteratorTag> iterator;
185
186 std::vector<std::size_t> c(10007);
187 std::fill(std::begin(c), std::end(c), std::size_t(42));
188
189 bool caught_exception = false;
190 bool returned_from_algorithm = false;
191 try {
192 hpx::future<void> f =
193 hpx::parallel::for_each(p,
194 hpx::util::make_iterator_range(
195 iterator(std::begin(c)), iterator(std::end(c))
196 ),
197 [](std::size_t v) { throw std::bad_alloc(); },
198 proj);
199 returned_from_algorithm = true;
200 f.get();
201
202 HPX_TEST(false);
203 }
204 catch(std::bad_alloc const&) {
205 caught_exception = true;
206 }
207 catch(...) {
208 HPX_TEST(false);
209 }
210
211 HPX_TEST(caught_exception);
212 HPX_TEST(returned_from_algorithm);
213 }
214
215 #endif
216