1// Copyright (C) 2012-2013 Vicente Botet
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#include <boost/config.hpp>
7
8#if ! defined BOOST_NO_CXX11_DECLTYPE
9#define BOOST_RESULT_OF_USE_DECLTYPE
10#endif
11
12
13#define BOOST_THREAD_VERSION 4
14//#define BOOST_THREAD_USES_LOG
15#define BOOST_THREAD_USES_LOG_THREAD_ID
16
17#include <boost/thread/future.hpp>
18#include <boost/thread/csbl/vector.hpp>
19#include <boost/assert.hpp>
20#include <boost/thread/detail/log.hpp>
21#include <string>
22#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
23
24#ifdef BOOST_MSVC
25#pragma warning(disable: 4127) // conditional expression is constant
26#endif
27
28int p1()
29{
30 BOOST_THREAD_LOG
31 << "P1" << BOOST_THREAD_END_LOG;
32 boost::this_thread::sleep_for(d: boost::chrono::seconds(1));
33 return 123;
34}
35int p1b()
36{
37 BOOST_THREAD_LOG
38 << "P1b" << BOOST_THREAD_END_LOG;
39 boost::this_thread::sleep_for(d: boost::chrono::seconds(1));
40 return 321;
41}
42
43int p2(boost::future<int> f)
44{
45 BOOST_THREAD_LOG
46 << " P2 " << BOOST_THREAD_END_LOG;
47 try
48 {
49 return 2 * f.get();
50 }
51 catch (std::exception& ex)
52 {
53 BOOST_THREAD_LOG
54 << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
55 BOOST_ASSERT(false);
56 }
57 catch (...)
58 {
59 BOOST_THREAD_LOG
60 << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
61 BOOST_ASSERT(false);
62 }
63 BOOST_THREAD_LOG
64 << "P2>" << BOOST_THREAD_END_LOG;
65 return 0;
66
67}
68int p2s(boost::shared_future<int> f)
69{
70 BOOST_THREAD_LOG
71 << "<P2" << BOOST_THREAD_END_LOG;
72 try
73 {
74 return 2 * f.get();
75 }
76 catch (std::exception& ex)
77 {
78 BOOST_THREAD_LOG
79 << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
80 BOOST_ASSERT(false);
81 }
82 catch (...)
83 {
84 BOOST_THREAD_LOG
85 << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
86 BOOST_ASSERT(false);
87 }
88 BOOST_THREAD_LOG
89 << "P2>" << BOOST_THREAD_END_LOG;
90 return 0;
91}
92
93int main()
94{
95 BOOST_THREAD_LOG
96 << "<MAIN" << BOOST_THREAD_END_LOG;
97 {
98 try
99 {
100 {
101 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
102 boost::future<boost::csbl::tuple<> > all0 = boost::when_all();
103 BOOST_THREAD_LOG
104 << BOOST_THREAD_END_LOG;
105 }
106 {
107 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
108 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1);
109 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(f: boost::move(t&: f1));
110 boost::csbl::tuple<boost::future<int> > res = all.get();
111 BOOST_THREAD_LOG
112 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
113 }
114#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
115 {
116 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
117 boost::future<int> f1 = boost::async(policy: boost::launch::deferred, f: &p1);
118 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
119 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(f: boost::move(t&: f1));
120 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
121 boost::csbl::tuple<boost::future<int> > res = all.get();
122 BOOST_THREAD_LOG
123 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
124 }
125#endif
126 {
127 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
128 boost::future<int> f1 = boost::make_ready_future(value: 1);
129 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(f: boost::move(t&: f1));
130 boost::csbl::tuple<boost::future<int> > res = all.get();
131 BOOST_THREAD_LOG
132 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
133 }
134 {
135 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
136 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1);
137 boost::future<int> f2 = boost::async(policy: boost::launch::async, f: &p1b);
138 boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(f: boost::move(t&: f1), futures: boost::move(t&: f2));
139 //(void) all.wait();
140 boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
141 BOOST_THREAD_LOG
142 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
143 BOOST_THREAD_LOG
144 << boost::csbl::get<1>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
145 }
146 {
147 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
148 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1);
149 boost::future<std::string> f2 = boost::make_ready_future(value: std::string("nnnnnnn"));;
150 boost::future<boost::csbl::tuple<boost::future<int>, boost::future<std::string> > > all = boost::when_all(f: boost::move(t&: f1), futures: boost::move(t&: f2));
151 //(void) all.wait();
152 boost::csbl::tuple<boost::future<int>, boost::future<std::string> > res = all.get();
153 BOOST_THREAD_LOG
154 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
155 BOOST_THREAD_LOG
156 << boost::csbl::get<1>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
157 }
158 {
159 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
160 boost::csbl::vector<boost::future<int> > v;
161 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
162 v.push_back(x: boost::async(policy: boost::launch::async, f: &p1));
163 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
164 v.push_back(x: boost::async(policy: boost::launch::async, f: &p1b));
165 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
166 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(first: v.begin(), last: v.end());
167 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
168 boost::csbl::vector<boost::future<int> > res = all.get();
169 BOOST_THREAD_LOG
170 << res[0].get() <<" " << BOOST_THREAD_END_LOG;
171 BOOST_THREAD_LOG
172 << res[1].get() <<" " << BOOST_THREAD_END_LOG;
173 }
174 }
175 catch (std::exception& ex)
176 {
177 BOOST_THREAD_LOG
178 << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
179 return 1;
180 }
181 catch (...)
182 {
183 BOOST_THREAD_LOG
184 << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
185 return 2;
186 }
187 }
188 {
189 try
190 {
191 {
192 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
193 boost::future<boost::csbl::tuple<> > all0 = boost::when_any();
194 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
195 }
196 {
197 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
198 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1);
199 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(f: boost::move(t&: f1));
200 boost::csbl::tuple<boost::future<int> > res = all.get();
201 BOOST_THREAD_LOG
202 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
203 }
204#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
205 {
206 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
207 boost::future<int> f1 = boost::async(policy: boost::launch::deferred, f: &p1);
208 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(f: boost::move(t&: f1));
209 boost::csbl::tuple<boost::future<int> > res = all.get();
210 BOOST_THREAD_LOG
211 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
212 }
213#endif
214 {
215 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
216 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1);
217 boost::future<int> f2 = boost::async(policy: boost::launch::async, f: &p1b);
218 boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(f: boost::move(t&: f1), futures: boost::move(t&: f2));
219 boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
220 BOOST_THREAD_LOG
221 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
222 BOOST_THREAD_LOG
223 << boost::csbl::get<1>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
224 }
225 {
226 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
227 boost::future<int> f1 = boost::make_ready_future(value: 1);
228 boost::future<int> f2 = boost::async(policy: boost::launch::async, f: &p1b);
229 boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(f: boost::move(t&: f1), futures: boost::move(t&: f2));
230 boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
231 BOOST_THREAD_LOG
232 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
233 BOOST_THREAD_LOG
234 << boost::csbl::get<1>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
235 }
236 {
237 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
238 boost::future<std::string> f1 = boost::make_ready_future(value: std::string("aaaa"));
239 boost::future<int> f2 = boost::async(policy: boost::launch::async, f: &p1b);
240 boost::future<boost::csbl::tuple<boost::future<std::string>,boost::future<int> > > all = boost::when_any(f: boost::move(t&: f1), futures: boost::move(t&: f2));
241 boost::csbl::tuple<boost::future<std::string>,boost::future<int> > res = all.get();
242 BOOST_THREAD_LOG
243 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
244 BOOST_THREAD_LOG
245 << boost::csbl::get<1>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
246 }
247 {
248 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
249 boost::future<int> f2 = boost::make_ready_future(value: 1);
250 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1b);
251 boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(f: boost::move(t&: f1), futures: boost::move(t&: f2));
252 boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
253 BOOST_THREAD_LOG
254 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
255 BOOST_THREAD_LOG
256 << boost::csbl::get<1>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
257 }
258#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
259 {
260 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
261 boost::future<int> f1 = boost::async(policy: boost::launch::deferred, f: &p1);
262 boost::future<int> f2 = boost::async(policy: boost::launch::async, f: &p1b);
263 boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(f: boost::move(t&: f1), futures: boost::move(t&: f2));
264 boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
265 BOOST_THREAD_LOG
266 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
267 BOOST_THREAD_LOG
268 << boost::csbl::get<1>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
269 }
270 {
271 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
272 boost::future<int> f1 = boost::async(policy: boost::launch::async, f: &p1);
273 boost::future<int> f2 = boost::async(policy: boost::launch::deferred, f: &p1b);
274 boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(f: boost::move(t&: f1), futures: boost::move(t&: f2));
275 boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
276 BOOST_THREAD_LOG
277 << boost::csbl::get<0>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
278 BOOST_THREAD_LOG
279 << boost::csbl::get<1>(t&: res).get() <<" " << BOOST_THREAD_END_LOG;
280 }
281#endif
282 {
283 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
284 boost::csbl::vector<boost::future<int> > v;
285 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
286 v.push_back(x: boost::async(policy: boost::launch::async, f: &p1));
287 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
288 v.push_back(x: boost::async(policy: boost::launch::async, f: &p1b));
289 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
290 boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(first: v.begin(), last: v.end());
291 BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
292 boost::csbl::vector<boost::future<int> > res = all.get();
293 BOOST_THREAD_LOG
294 << res[0].get() <<" " << BOOST_THREAD_END_LOG;
295 BOOST_THREAD_LOG
296 << res[1].get() <<" " << BOOST_THREAD_END_LOG;
297 }
298 }
299 catch (std::exception& ex)
300 {
301 BOOST_THREAD_LOG
302 << "ERRORRRRR " << ex.what() << "" << BOOST_THREAD_END_LOG;
303 return 1;
304 }
305 catch (...)
306 {
307 BOOST_THREAD_LOG
308 << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
309 return 2;
310 }
311 }
312 BOOST_THREAD_LOG
313 << "MAIN>" << BOOST_THREAD_END_LOG;
314 return 0;
315}
316#else
317#include <boost/thread/csbl/vector.hpp>
318using namespace boost;
319
320void f( boost::csbl::vector<future<int> > &//vec
321 , BOOST_THREAD_RV_REF(future<int>) //f
322 ) {
323}
324int main()
325{
326 boost::csbl::vector<future<int> > vec;
327 f(vec, make_ready_future(0));
328 return 0;
329}
330#endif
331

source code of boost/libs/thread/example/future_when_all.cpp