Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / thread / test / sync / futures / when_all / variadic_pass.cpp
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 <class T, class Ts>
18 // future<tuple<T, Ts...>> when_all(T&&, Ts&& ...);
19
20 #include <boost/config.hpp>
21
22 #if ! defined  BOOST_NO_CXX11_DECLTYPE
23 #define BOOST_RESULT_OF_USE_DECLTYPE
24 #endif
25
26
27 #define BOOST_THREAD_VERSION 4
28
29 #include <boost/thread/future.hpp>
30 #include <boost/detail/lightweight_test.hpp>
31 #include <stdexcept>
32
33 int p1()
34 {
35   boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
36   return 123;
37 }
38
39 int thr()
40 {
41   throw std::logic_error("123");
42 }
43 int p2()
44 {
45   boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
46   return 321;
47 }
48
49 int main()
50 {
51 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
52   if (0) // todo not yet implemented
53   { // invalid future copy-constructible
54     boost::future<int> f1;
55     boost::future<int> f2 = boost::make_ready_future(321);
56     BOOST_TEST(! f1.valid());
57     BOOST_TEST(f2.valid());
58     boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
59     BOOST_TEST(! f1.valid());
60     BOOST_TEST(! f2.valid());
61     BOOST_TEST(all.valid());
62     boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
63     BOOST_TEST(boost::csbl::get<0>(res).valid());
64     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
65     // has exception
66     //BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
67     BOOST_TEST(boost::csbl::get<1>(res).valid());
68     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
69     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
70   }
71   { // is_ready future copy-constructible
72     boost::future<int> f1 = boost::make_ready_future(123);
73     boost::future<int> f2 = boost::make_ready_future(321);
74     BOOST_TEST(f1.valid());
75     BOOST_TEST(f1.is_ready());
76     BOOST_TEST(f2.valid());
77     BOOST_TEST(f2.is_ready());
78     boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
79     BOOST_TEST(! f1.valid());
80     BOOST_TEST(! f2.valid());
81     BOOST_TEST(all.valid());
82     if (0) // todo FAILS not yet implemented
83     BOOST_TEST(all.is_ready());
84     boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
85     BOOST_TEST(boost::csbl::get<0>(res).valid());
86     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
87     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
88     BOOST_TEST(boost::csbl::get<1>(res).valid());
89     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
90     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
91   }
92   { // is_ready shared_future copy-constructible
93     boost::shared_future<int> f1 = boost::make_ready_future(123).share();
94     boost::shared_future<int> f2 = boost::make_ready_future(321).share();
95     BOOST_TEST(f1.valid());
96     BOOST_TEST(f1.is_ready());
97     BOOST_TEST(f2.valid());
98     BOOST_TEST(f2.is_ready());
99     boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2);
100     BOOST_TEST(f1.valid());
101     BOOST_TEST(f2.valid());
102     BOOST_TEST(all.valid());
103     if (0) // todo FAILS not yet implemented
104     BOOST_TEST(all.is_ready());
105     boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
106     BOOST_TEST(boost::csbl::get<0>(res).valid());
107     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
108     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
109     BOOST_TEST(boost::csbl::get<1>(res).valid());
110     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
111     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
112   }
113   { // packaged_task future copy-constructible
114     boost::packaged_task<int()> pt1(&p1);
115     boost::future<int> f1 = pt1.get_future();
116     BOOST_TEST(f1.valid());
117     boost::packaged_task<int()> pt2(&p2);
118     boost::future<int> f2 = pt2.get_future();
119     BOOST_TEST(f2.valid());
120     boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
121     BOOST_TEST(! f1.valid());
122     BOOST_TEST(! f2.valid());
123     BOOST_TEST(all.valid());
124     pt1();
125     pt2();
126     boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
127     BOOST_TEST(boost::csbl::get<0>(res).valid());
128     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
129     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
130     BOOST_TEST(boost::csbl::get<1>(res).valid());
131     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
132     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
133   }
134   { // packaged_task future copy-constructible
135     boost::packaged_task<int()> pt1(&thr);
136     boost::future<int> f1 = pt1.get_future();
137     BOOST_TEST(f1.valid());
138     boost::packaged_task<int()> pt2(&p2);
139     boost::future<int> f2 = pt2.get_future();
140     BOOST_TEST(f2.valid());
141     boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
142     BOOST_TEST(! f1.valid());
143     BOOST_TEST(! f2.valid());
144     BOOST_TEST(all.valid());
145     pt1();
146     pt2();
147     boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
148     BOOST_TEST(boost::csbl::get<0>(res).valid());
149     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
150     try {
151       boost::csbl::get<0>(res).get();
152       BOOST_TEST(false);
153     } catch (std::logic_error& ex) {
154       BOOST_TEST(ex.what() == std::string("123"));
155     } catch (...) {
156       BOOST_TEST(false);
157     }
158     BOOST_TEST(boost::csbl::get<1>(res).valid());
159     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
160     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
161   }
162   { // packaged_task shared_future copy-constructible
163     boost::packaged_task<int()> pt1(&p1);
164     boost::shared_future<int> f1 = pt1.get_future().share();
165     BOOST_TEST(f1.valid());
166     boost::packaged_task<int()> pt2(&p2);
167     boost::shared_future<int> f2 = pt2.get_future().share();
168     BOOST_TEST(f2.valid());
169     boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2);
170     BOOST_TEST(f1.valid());
171     BOOST_TEST(f2.valid());
172     BOOST_TEST(all.valid());
173     BOOST_TEST(! all.is_ready());
174     pt1();
175     BOOST_TEST(! all.is_ready());
176     pt2();
177     boost::this_thread::sleep_for(boost::chrono::milliseconds(300));
178     BOOST_TEST(all.is_ready());
179     boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
180     BOOST_TEST(boost::csbl::get<0>(res).valid());
181     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
182     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
183     BOOST_TEST(boost::csbl::get<1>(res).valid());
184     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
185     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
186   }
187   { // async future copy-constructible
188     boost::future<int> f1 = boost::async(boost::launch::async, &p1);
189     BOOST_TEST(f1.valid());
190     boost::future<int> f2 = boost::async(boost::launch::async, &p2);
191     BOOST_TEST(f2.valid());
192     boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
193     BOOST_TEST(! f1.valid());
194     BOOST_TEST(! f2.valid());
195     BOOST_TEST(all.valid());
196     boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
197     BOOST_TEST(boost::csbl::get<0>(res).valid());
198     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
199     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
200     BOOST_TEST(boost::csbl::get<1>(res).valid());
201     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
202     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
203   }
204   { // async shared_future copy-constructible
205     boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
206     BOOST_TEST(f1.valid());
207     boost::shared_future<int> f2 = boost::async(boost::launch::async, &p2).share();
208     BOOST_TEST(f2.valid());
209     boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2);
210     BOOST_TEST(f1.valid());
211     BOOST_TEST(f2.valid());
212     BOOST_TEST(all.valid());
213     boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
214     BOOST_TEST(boost::csbl::get<0>(res).valid());
215     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
216     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
217     BOOST_TEST(boost::csbl::get<1>(res).valid());
218     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
219     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
220   }
221   { // async future copy-constructible
222     boost::future<int> f1 = boost::async(boost::launch::async, &p1);
223     BOOST_TEST(f1.valid());
224     boost::future<int> f2 = boost::make_ready_future(321);
225     BOOST_TEST(f2.valid());
226     BOOST_TEST(f2.is_ready());
227     boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
228     BOOST_TEST(! f1.valid());
229     BOOST_TEST(! f2.valid());
230     BOOST_TEST(all.valid());
231     boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
232     BOOST_TEST(boost::csbl::get<0>(res).valid());
233     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
234     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
235     BOOST_TEST(boost::csbl::get<1>(res).valid());
236     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
237     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
238   }
239 #if ! defined BOOST_NO_CXX11_DECLTYPE_N3276
240   // fixme darwin-4.8.0_11 terminate called without an active exception
241   { // deferred future copy-constructible
242     boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
243     boost::future<int> f2 = boost::async(boost::launch::deferred, &p2);
244     boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
245     BOOST_TEST(! f1.valid());
246     BOOST_TEST(! f2.valid());
247     BOOST_TEST(all.valid());
248     boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
249     BOOST_TEST(boost::csbl::get<0>(res).valid());
250     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
251     BOOST_TEST(boost::csbl::get<1>(res).valid());
252     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
253     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
254     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
255   }
256   // fixme darwin-4.8.0_11 terminate called without an active exception
257   { // deferred shared_future copy-constructible
258     boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share();
259     boost::shared_future<int> f2 = boost::async(boost::launch::deferred, &p2).share();
260     boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2);
261     BOOST_TEST(f1.valid());
262     BOOST_TEST(f2.valid());
263     BOOST_TEST(all.valid());
264     boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
265     BOOST_TEST(boost::csbl::get<0>(res).valid());
266     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
267     BOOST_TEST(boost::csbl::get<1>(res).valid());
268     BOOST_TEST(boost::csbl::get<1>(res).is_ready());
269     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
270     BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
271   }
272 #endif
273 #if ! defined BOOST_NO_CXX11_LAMBDAS
274     { // async futures copy-constructible then()
275       boost::future<int> f1 = boost::async(boost::launch::async, &p1);
276       BOOST_TEST(f1.valid());
277       boost::future<int> f2 = boost::async(boost::launch::async, &p2);
278       BOOST_TEST(f2.valid());
279       boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
280       BOOST_TEST(! f1.valid());
281       BOOST_TEST(! f2.valid());
282       BOOST_TEST(all.valid());
283       boost::future<int> sum = all.then([](boost::future<boost::csbl::tuple<boost::future<int>, boost::future<int> > > f)
284       {
285         boost::csbl::tuple<boost::future<int>,boost::future<int> > v = f.get();
286         return boost::csbl::get<0>(v).get()+boost::csbl::get<1>(v).get();
287       });
288       BOOST_TEST(sum.valid());
289       BOOST_TEST(sum.get() == 444);
290     }
291 #endif
292 #endif
293
294   return boost::report_errors();
295 }
296