1//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// Copyright (C) 2014 Vicente J. Botet Escriba
11//
12// Distributed under the Boost Software License, Version 1.0. (See accompanying
13// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
14
15// <boost/thread/future.hpp>
16
17// template< typename InputIterator>
18// future<vector<typename InputIterator::value_type> >
19// when_all(InputIterator first, InputIterator last)
20
21#include <boost/config.hpp>
22
23#if ! defined BOOST_NO_CXX11_DECLTYPE
24#define BOOST_RESULT_OF_USE_DECLTYPE
25#endif
26
27
28#define BOOST_THREAD_VERSION 4
29
30#include <boost/thread/future.hpp>
31#include <boost/detail/lightweight_test.hpp>
32#include <stdexcept>
33
34#ifdef BOOST_MSVC
35#pragma warning(disable: 4127) // conditional expression is constant
36#endif
37
38int p1()
39{
40 return 123;
41}
42
43int thr()
44{
45 throw std::logic_error("123");
46}
47int p2()
48{
49 return 321;
50}
51
52int main()
53{
54#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
55 if (0) // todo not yet implemented
56 { // invalid future copy-constructible
57 boost::csbl::vector<boost::future<int> > v;
58 boost::future<int> f1;
59 v.push_back(x: boost::move(t&: f1));
60 v.push_back(x: boost::make_ready_future(value: 321));
61 BOOST_TEST(! v[0].valid());
62 BOOST_TEST(v[1].valid());
63
64 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
65 BOOST_TEST(! v[0].valid());
66 BOOST_TEST(! v[1].valid());
67 BOOST_TEST(all.valid());
68 boost::csbl::vector<boost::future<int> > res = all.get();
69 BOOST_TEST(res.size() == 2);
70 BOOST_TEST(res[1].valid());
71 BOOST_TEST(res[1].is_ready());
72 // has exception
73 //BOOST_TEST(res[0].get() == 123);
74 BOOST_TEST(res[1].valid());
75 BOOST_TEST(res[1].is_ready());
76 BOOST_TEST(res[1].get() == 321);
77 }
78 { // is_ready future copy-constructible
79 boost::future<int> f1 = boost::make_ready_future(value: 123);
80 boost::future<int> f2 = boost::make_ready_future(value: 321);
81 boost::csbl::vector<boost::future<int> > v;
82 v.push_back(x: boost::move(t&: f1));
83 v.push_back(x: boost::move(t&: f2));
84 BOOST_TEST(v[0].valid());
85 BOOST_TEST(v[0].is_ready());
86 BOOST_TEST(v[1].valid());
87 BOOST_TEST(v[1].is_ready());
88 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
89 BOOST_TEST(! v[0].valid());
90 BOOST_TEST(! v[1].valid());
91 BOOST_TEST(all.valid());
92 if (0) // todo FAILS not yet implemented
93 BOOST_TEST(all.is_ready());
94 boost::csbl::vector<boost::future<int> > res = all.get();
95 BOOST_TEST(res[0].valid());
96 BOOST_TEST(res[0].is_ready());
97 BOOST_TEST(res[0].get() == 123);
98 BOOST_TEST(res[1].valid());
99 BOOST_TEST(res[1].is_ready());
100 BOOST_TEST(res[1].get() == 321);
101 }
102 { // is_ready shared_future copy-constructible
103 boost::shared_future<int> f1 = boost::make_ready_future(value: 123).share();
104 boost::shared_future<int> f2 = boost::make_ready_future(value: 321).share();
105 boost::csbl::vector<boost::shared_future<int> > v;
106 v.push_back(x: f1);
107 v.push_back(x: f2);
108 BOOST_TEST(v[0].valid());
109 BOOST_TEST(v[0].is_ready());
110 BOOST_TEST(v[1].valid());
111 BOOST_TEST(v[1].is_ready());
112 boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
113 if (0) // fixme
114 BOOST_TEST(v[0].valid());
115 if (0) // fixme
116 BOOST_TEST(v[1].valid());
117 BOOST_TEST(all.valid());
118 if (0) // todo FAILS not yet implemented
119 BOOST_TEST(all.is_ready());
120 boost::csbl::vector<boost::shared_future<int> > res = all.get();
121 BOOST_TEST(res[0].valid());
122 BOOST_TEST(res[0].is_ready());
123 BOOST_TEST(res[0].get() == 123);
124 BOOST_TEST(res[1].valid());
125 BOOST_TEST(res[1].is_ready());
126 BOOST_TEST(res[1].get() == 321);
127 }
128 { // packaged_task future copy-constructible
129 boost::packaged_task<int()> pt1(&p1);
130 boost::future<int> f1 = pt1.get_future();
131 BOOST_TEST(f1.valid());
132 boost::packaged_task<int()> pt2(&p2);
133 boost::future<int> f2 = pt2.get_future();
134 BOOST_TEST(f2.valid());
135 boost::csbl::vector<boost::future<int> > v;
136 v.push_back(x: boost::move(t&: f1));
137 v.push_back(x: boost::move(t&: f2));
138 BOOST_TEST(v[0].valid());
139 BOOST_TEST(v[1].valid());
140 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
141 BOOST_TEST(! v[0].valid());
142 BOOST_TEST(! v[1].valid());
143 BOOST_TEST(all.valid());
144 pt1();
145 pt2();
146 boost::csbl::vector<boost::future<int> > res = all.get();
147 BOOST_TEST(res[0].valid());
148 BOOST_TEST(res[0].is_ready());
149 BOOST_TEST(res[0].get() == 123);
150 BOOST_TEST(res[1].valid());
151 BOOST_TEST(res[1].is_ready());
152 BOOST_TEST(res[1].get() == 321);
153 }
154 { // packaged_task future copy-constructible
155 boost::packaged_task<int()> pt1(&thr);
156 boost::future<int> f1 = pt1.get_future();
157 BOOST_TEST(f1.valid());
158 boost::packaged_task<int()> pt2(&p2);
159 boost::future<int> f2 = pt2.get_future();
160 BOOST_TEST(f2.valid());
161 boost::csbl::vector<boost::future<int> > v;
162 v.push_back(x: boost::move(t&: f1));
163 v.push_back(x: boost::move(t&: f2));
164 BOOST_TEST(v[0].valid());
165 BOOST_TEST(v[1].valid());
166 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
167 BOOST_TEST(! v[0].valid());
168 BOOST_TEST(! v[1].valid());
169 BOOST_TEST(all.valid());
170 pt1();
171 pt2();
172 boost::csbl::vector<boost::future<int> > res = all.get();
173 BOOST_TEST(res[0].valid());
174 BOOST_TEST(res[0].is_ready());
175 try {
176 res[0].get();
177 BOOST_TEST(false);
178 } catch (std::logic_error& ex) {
179 BOOST_TEST(ex.what() == std::string("123"));
180 } catch (...) {
181 BOOST_TEST(false);
182 }
183 BOOST_TEST(res[1].valid());
184 BOOST_TEST(res[1].is_ready());
185 BOOST_TEST(res[1].get() == 321);
186 }
187 { // packaged_task shared_future copy-constructible
188 boost::packaged_task<int()> pt1(&p1);
189 boost::shared_future<int> f1 = pt1.get_future().share();
190 BOOST_TEST(f1.valid());
191 boost::packaged_task<int()> pt2(&p2);
192 boost::shared_future<int> f2 = pt2.get_future().share();
193 BOOST_TEST(f2.valid());
194 boost::csbl::vector<boost::shared_future<int> > v;
195 v.push_back(x: f1);
196 v.push_back(x: f2);
197 BOOST_TEST(v[0].valid());
198 BOOST_TEST(v[1].valid());
199 boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
200 if (0) // fixme
201 BOOST_TEST(v[0].valid());
202 if (0) // fixme
203 BOOST_TEST(v[1].valid());
204 BOOST_TEST(all.valid());
205 BOOST_TEST(! all.is_ready());
206 pt1();
207 BOOST_TEST(! all.is_ready());
208 pt2();
209 boost::this_thread::sleep_for(d: boost::chrono::milliseconds(300));
210 BOOST_TEST(all.is_ready());
211 boost::csbl::vector<boost::shared_future<int> > res = all.get();
212 BOOST_TEST(res[0].valid());
213 BOOST_TEST(res[0].is_ready());
214 BOOST_TEST(res[0].get() == 123);
215 BOOST_TEST(res[1].valid());
216 BOOST_TEST(res[1].is_ready());
217 BOOST_TEST(res[1].get() == 321);
218 }
219 { // async future copy-constructible
220 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1);
221 BOOST_TEST(f1.valid());
222 boost::future<int> f2 = boost::async(policy: boost::launch::async, f: &p2);
223 BOOST_TEST(f2.valid());
224 boost::csbl::vector<boost::future<int> > v;
225 v.push_back(x: boost::move(t&: f1));
226 v.push_back(x: boost::move(t&: f2));
227 BOOST_TEST(v[0].valid());
228 BOOST_TEST(v[1].valid());
229 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
230 BOOST_TEST(! v[0].valid());
231 BOOST_TEST(! v[1].valid());
232 BOOST_TEST(all.valid());
233 boost::csbl::vector<boost::future<int> > res = all.get();
234 BOOST_TEST(res[0].valid());
235 BOOST_TEST(res[0].is_ready());
236 BOOST_TEST(res[0].get() == 123);
237 BOOST_TEST(res[1].valid());
238 BOOST_TEST(res[1].is_ready());
239 BOOST_TEST(res[1].get() == 321);
240 }
241 { // async shared_future copy-constructible
242 boost::shared_future<int> f1 = boost::async(policy: boost::launch::async, f: &p1).share();
243 BOOST_TEST(f1.valid());
244 boost::shared_future<int> f2 = boost::async(policy: boost::launch::async, f: &p2).share();
245 BOOST_TEST(f2.valid());
246 boost::csbl::vector<boost::shared_future<int> > v;
247 v.push_back(x: f1);
248 v.push_back(x: f2);
249 BOOST_TEST(v[0].valid());
250 BOOST_TEST(v[1].valid());
251 boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
252 if (0) // fixme
253 BOOST_TEST(v[0].valid());
254 if (0) // fixme
255 BOOST_TEST(v[1].valid());
256 BOOST_TEST(all.valid());
257 boost::csbl::vector<boost::shared_future<int> > res = all.get();
258 BOOST_TEST(res[0].valid());
259 BOOST_TEST(res[0].is_ready());
260 BOOST_TEST(res[0].get() == 123);
261 BOOST_TEST(res[1].valid());
262 BOOST_TEST(res[1].is_ready());
263 BOOST_TEST(res[1].get() == 321);
264 }
265 { // async future copy-constructible
266 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1);
267 BOOST_TEST(f1.valid());
268 boost::future<int> f2 = boost::make_ready_future(value: 321);
269 BOOST_TEST(f2.valid());
270 BOOST_TEST(f2.is_ready());
271 boost::csbl::vector<boost::future<int> > v;
272 v.push_back(x: boost::move(t&: f1));
273 v.push_back(x: boost::move(t&: f2));
274 BOOST_TEST(v[0].valid());
275 BOOST_TEST(v[1].valid());
276 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
277 BOOST_TEST(! v[0].valid());
278 BOOST_TEST(! v[1].valid());
279 BOOST_TEST(all.valid());
280 boost::csbl::vector<boost::future<int> > res = all.get();
281 BOOST_TEST(res[0].valid());
282 BOOST_TEST(res[0].is_ready());
283 BOOST_TEST(res[0].get() == 123);
284 BOOST_TEST(res[1].valid());
285 BOOST_TEST(res[1].is_ready());
286 BOOST_TEST(res[1].get() == 321);
287 }
288#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
289 // fixme darwin-4.8.0_11 terminate called without an active exception
290 { // deferred future copy-constructible
291 boost::future<int> f1 = boost::async(policy: boost::launch::deferred, f: &p1);
292 boost::future<int> f2 = boost::async(policy: boost::launch::deferred, f: &p2);
293 boost::csbl::vector<boost::future<int> > v;
294 v.push_back(x: boost::move(t&: f1));
295 v.push_back(x: boost::move(t&: f2));
296 BOOST_TEST(v[0].valid());
297 BOOST_TEST(v[1].valid());
298 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
299 BOOST_TEST(! v[0].valid());
300 BOOST_TEST(! v[1].valid());
301 BOOST_TEST(all.valid());
302 boost::csbl::vector<boost::future<int> > res = all.get();
303 BOOST_TEST(res[0].valid());
304 BOOST_TEST(res[0].is_ready());
305 BOOST_TEST(res[0].get() == 123);
306 BOOST_TEST(res[1].valid());
307 BOOST_TEST(res[1].is_ready());
308 BOOST_TEST(res[1].get() == 321);
309 }
310 // fixme darwin-4.8.0_11 terminate called without an active exception
311 { // deferred shared_future copy-constructible
312 boost::shared_future<int> f1 = boost::async(policy: boost::launch::deferred, f: &p1).share();
313 boost::shared_future<int> f2 = boost::async(policy: boost::launch::deferred, f: &p2).share();
314 boost::csbl::vector<boost::shared_future<int> > v;
315 v.push_back(x: f1);
316 v.push_back(x: f2);
317 BOOST_TEST(v[0].valid());
318 BOOST_TEST(v[1].valid());
319 boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
320 if (0) // fixme
321 BOOST_TEST(v[0].valid());
322 if (0) // fixme
323 BOOST_TEST(v[1].valid());
324 BOOST_TEST(all.valid());
325 boost::csbl::vector<boost::shared_future<int> > res = all.get();
326 BOOST_TEST(res[0].valid());
327 BOOST_TEST(res[0].is_ready());
328 BOOST_TEST(res[0].get() == 123);
329 BOOST_TEST(res[1].valid());
330 BOOST_TEST(res[1].is_ready());
331 BOOST_TEST(res[1].get() == 321);
332 }
333#endif
334#if ! defined BOOST_NO_CXX11_LAMBDAS
335 { // async futures copy-constructible then()
336 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1);
337 BOOST_TEST(f1.valid());
338 boost::future<int> f2 = boost::async(policy: boost::launch::async, f: &p2);
339 BOOST_TEST(f2.valid());
340 boost::csbl::vector<boost::future<int> > v;
341 v.push_back(x: boost::move(t&: f1));
342 v.push_back(x: boost::move(t&: f2));
343 BOOST_TEST(v[0].valid());
344 BOOST_TEST(v[1].valid());
345 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
346 BOOST_TEST(! v[0].valid());
347 BOOST_TEST(! v[1].valid());
348 BOOST_TEST(all.valid());
349 boost::future<int> sum = all.then(func: [](boost::future<boost::csbl::vector<boost::future<int> > > f)
350 {
351 boost::csbl::vector<boost::future<int> > v = f.get();
352 return v[0].get() + v[1].get();
353 });
354 BOOST_TEST(sum.valid());
355 BOOST_TEST(sum.get() == 444);
356 }
357#endif
358#endif
359
360 return boost::report_errors();
361}
362
363

source code of boost/libs/thread/test/sync/futures/when_all/iterators_pass.cpp