comparison DEPENDENCIES/generic/include/boost/thread/future.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
1 // (C) Copyright 2008-10 Anthony Williams 1 // (C) Copyright 2008-10 Anthony Williams
2 // (C) Copyright 2011-2013 Vicente J. Botet Escriba 2 // (C) Copyright 2011-2015 Vicente J. Botet Escriba
3 // 3 //
4 // Distributed under the Boost Software License, Version 1.0. (See 4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at 5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt) 6 // http://www.boost.org/LICENSE_1_0.txt)
7 7
13 // boost::thread::future requires exception handling 13 // boost::thread::future requires exception handling
14 // due to boost::exception::exception_ptr dependency 14 // due to boost::exception::exception_ptr dependency
15 15
16 #ifndef BOOST_NO_EXCEPTIONS 16 #ifndef BOOST_NO_EXCEPTIONS
17 17
18 //#include <boost/thread/detail/log.hpp> 18 #include <boost/thread/condition_variable.hpp>
19 #include <boost/detail/scoped_enum_emulation.hpp>
20 #include <stdexcept>
21 #include <boost/thread/detail/move.hpp> 19 #include <boost/thread/detail/move.hpp>
22 #include <boost/thread/detail/async_func.hpp> 20 #include <boost/thread/detail/invoker.hpp>
23 #include <boost/thread/thread_time.hpp> 21 #include <boost/thread/detail/invoke.hpp>
24 #include <boost/thread/mutex.hpp> 22 #include <boost/thread/detail/is_convertible.hpp>
25 #include <boost/thread/condition_variable.hpp> 23 #include <boost/thread/exceptional_ptr.hpp>
24 #include <boost/thread/futures/future_error.hpp>
25 #include <boost/thread/futures/future_error_code.hpp>
26 #include <boost/thread/futures/future_status.hpp>
27 #include <boost/thread/futures/is_future_type.hpp>
28 #include <boost/thread/futures/launch.hpp>
29 #include <boost/thread/futures/wait_for_all.hpp>
30 #include <boost/thread/futures/wait_for_any.hpp>
26 #include <boost/thread/lock_algorithms.hpp> 31 #include <boost/thread/lock_algorithms.hpp>
27 #include <boost/thread/lock_types.hpp> 32 #include <boost/thread/lock_types.hpp>
28 #include <boost/exception_ptr.hpp> 33 #include <boost/thread/mutex.hpp>
29 #include <boost/shared_ptr.hpp> 34 #include <boost/thread/thread_only.hpp>
30 #include <boost/scoped_ptr.hpp> 35 #include <boost/thread/thread_time.hpp>
31 #include <boost/type_traits/is_fundamental.hpp> 36
32 #include <boost/thread/detail/is_convertible.hpp> 37 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
33 #include <boost/type_traits/remove_reference.hpp> 38 #include <boost/optional.hpp>
34 #include <boost/type_traits/remove_cv.hpp> 39 #else
35 #include <boost/type_traits/is_void.hpp> 40 #include <boost/thread/csbl/memory/unique_ptr.hpp>
36 #include <boost/mpl/if.hpp> 41 #endif
37 #include <boost/config.hpp> 42
38 #include <boost/throw_exception.hpp> 43 #include <boost/assert.hpp>
39 #include <algorithm>
40 #include <boost/function.hpp>
41 #include <boost/bind.hpp> 44 #include <boost/bind.hpp>
42 #include <boost/ref.hpp>
43 #include <boost/scoped_array.hpp>
44 #include <boost/enable_shared_from_this.hpp>
45 #include <boost/utility/enable_if.hpp>
46 #include <list>
47 #include <boost/next_prior.hpp>
48 #include <vector>
49
50 #include <boost/thread/future_error_code.hpp>
51 #ifdef BOOST_THREAD_USES_CHRONO 45 #ifdef BOOST_THREAD_USES_CHRONO
52 #include <boost/chrono/system_clocks.hpp> 46 #include <boost/chrono/system_clocks.hpp>
53 #endif 47 #endif
48 #include <boost/core/enable_if.hpp>
49 #include <boost/core/ref.hpp>
50 #include <boost/enable_shared_from_this.hpp>
51 #include <boost/exception_ptr.hpp>
52 #include <boost/function.hpp>
53 #include <boost/next_prior.hpp>
54 #include <boost/scoped_array.hpp>
55 #include <boost/shared_ptr.hpp>
56 #include <boost/throw_exception.hpp>
57 #include <boost/type_traits/conditional.hpp>
58 #include <boost/type_traits/decay.hpp>
59 #include <boost/type_traits/is_copy_constructible.hpp>
60 #include <boost/type_traits/is_fundamental.hpp>
61 #include <boost/type_traits/is_void.hpp>
62 #include <boost/utility/result_of.hpp>
63
54 64
55 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS 65 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
56 #include <boost/thread/detail/memory.hpp> 66 #include <boost/thread/detail/memory.hpp>
57 #endif 67 #include <boost/container/scoped_allocator.hpp>
58 68 #if ! defined BOOST_NO_CXX11_ALLOCATOR
59 #include <boost/utility/result_of.hpp> 69 #include <memory>
60 #include <boost/thread/thread_only.hpp> 70 #endif
71 #endif
72
73 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
74 #include <boost/thread/csbl/tuple.hpp>
75 #include <boost/thread/csbl/vector.hpp>
76 #endif
77
78 #include <algorithm>
79 #include <list>
80 #include <vector>
81 #include <utility>
61 82
62 #if defined BOOST_THREAD_PROVIDES_FUTURE 83 #if defined BOOST_THREAD_PROVIDES_FUTURE
63 #define BOOST_THREAD_FUTURE future 84 #define BOOST_THREAD_FUTURE future
64 #else 85 #else
65 #define BOOST_THREAD_FUTURE unique_future 86 #define BOOST_THREAD_FUTURE unique_future
66 #endif 87 #endif
67 88
68 namespace boost 89 namespace boost
69 { 90 {
70
71 //enum class launch
72 BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
73 {
74 none = 0,
75 async = 1,
76 deferred = 2,
77 any = async | deferred
78 }
79 BOOST_SCOPED_ENUM_DECLARE_END(launch)
80
81 //enum class future_status
82 BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
83 {
84 ready,
85 timeout,
86 deferred
87 }
88 BOOST_SCOPED_ENUM_DECLARE_END(future_status)
89
90 class BOOST_SYMBOL_VISIBLE future_error
91 : public std::logic_error
92 {
93 system::error_code ec_;
94 public:
95 future_error(system::error_code ec)
96 : logic_error(ec.message()),
97 ec_(ec)
98 {
99 }
100
101 const system::error_code& code() const BOOST_NOEXCEPT
102 {
103 return ec_;
104 }
105 };
106
107 class BOOST_SYMBOL_VISIBLE future_uninitialized:
108 public future_error
109 {
110 public:
111 future_uninitialized() :
112 future_error(system::make_error_code(future_errc::no_state))
113 {}
114 };
115 class BOOST_SYMBOL_VISIBLE broken_promise:
116 public future_error
117 {
118 public:
119 broken_promise():
120 future_error(system::make_error_code(future_errc::broken_promise))
121 {}
122 };
123 class BOOST_SYMBOL_VISIBLE future_already_retrieved:
124 public future_error
125 {
126 public:
127 future_already_retrieved():
128 future_error(system::make_error_code(future_errc::future_already_retrieved))
129 {}
130 };
131 class BOOST_SYMBOL_VISIBLE promise_already_satisfied:
132 public future_error
133 {
134 public:
135 promise_already_satisfied():
136 future_error(system::make_error_code(future_errc::promise_already_satisfied))
137 {}
138 };
139
140 class BOOST_SYMBOL_VISIBLE task_already_started:
141 public future_error
142 {
143 public:
144 task_already_started():
145 future_error(system::make_error_code(future_errc::promise_already_satisfied))
146 {}
147 };
148
149 class BOOST_SYMBOL_VISIBLE task_moved:
150 public future_error
151 {
152 public:
153 task_moved():
154 future_error(system::make_error_code(future_errc::no_state))
155 {}
156 };
157
158 class promise_moved:
159 public future_error
160 {
161 public:
162 promise_moved():
163 future_error(system::make_error_code(future_errc::no_state))
164 {}
165 };
166
167 namespace future_state
168 {
169 enum state { uninitialized, waiting, ready, moved, deferred };
170 }
171
172 namespace detail 91 namespace detail
173 { 92 {
174 struct relocker 93 struct relocker
175 { 94 {
176 boost::unique_lock<boost::mutex>& lock_; 95 boost::unique_lock<boost::mutex>& lock_;
177 bool unlocked_;
178 96
179 relocker(boost::unique_lock<boost::mutex>& lk): 97 relocker(boost::unique_lock<boost::mutex>& lk):
180 lock_(lk) 98 lock_(lk)
181 { 99 {
182 lock_.unlock(); 100 lock_.unlock();
183 unlocked_=true;
184 } 101 }
185 ~relocker() 102 ~relocker()
186 { 103 {
187 if (unlocked_) { 104 if (! lock_.owns_lock()) {
188 lock_.lock(); 105 lock_.lock();
189 } 106 }
190 } 107 }
191 void lock() { 108 void lock() {
192 if (unlocked_) { 109 if (! lock_.owns_lock()) {
193 lock_.lock(); 110 lock_.lock();
194 unlocked_=false;
195 } 111 }
196 } 112 }
197 private: 113 private:
198 relocker& operator=(relocker const&); 114 relocker& operator=(relocker const&);
199 }; 115 };
200 116
201 struct shared_state_base : enable_shared_from_this<shared_state_base> 117 struct shared_state_base : enable_shared_from_this<shared_state_base>
202 { 118 {
203 typedef std::list<boost::condition_variable_any*> waiter_list; 119 typedef std::list<boost::condition_variable_any*> waiter_list;
120 typedef waiter_list::iterator notify_when_ready_handle;
204 // This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout. 121 // This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
205 typedef shared_ptr<shared_state_base> continuation_ptr_type; 122 typedef shared_ptr<shared_state_base> continuation_ptr_type;
123 typedef std::vector<continuation_ptr_type> continuations_type;
206 124
207 boost::exception_ptr exception; 125 boost::exception_ptr exception;
208 bool done; 126 bool done;
127 bool is_valid_;
209 bool is_deferred_; 128 bool is_deferred_;
129 bool is_constructed;
130 std::size_t cnt_;
210 launch policy_; 131 launch policy_;
211 bool is_constructed;
212 mutable boost::mutex mutex; 132 mutable boost::mutex mutex;
213 boost::condition_variable waiters; 133 boost::condition_variable waiters;
214 waiter_list external_waiters; 134 waiter_list external_waiters;
215 boost::function<void()> callback; 135 boost::function<void()> callback;
216 // This declaration should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
217 bool thread_was_interrupted;
218 // This declaration should be only included conditionally, but is included to maintain the same layout. 136 // This declaration should be only included conditionally, but is included to maintain the same layout.
219 continuation_ptr_type continuation_ptr; 137 continuations_type continuations;
220 138
221 // This declaration should be only included conditionally, but is included to maintain the same layout. 139 // This declaration should be only included conditionally, but is included to maintain the same layout.
222 virtual void launch_continuation(boost::unique_lock<boost::mutex>&) 140 virtual void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base>)
223 { 141 {
224 } 142 }
225 143
226 shared_state_base(): 144 shared_state_base():
227 done(false), 145 done(false),
146 is_valid_(true),
228 is_deferred_(false), 147 is_deferred_(false),
148 is_constructed(false),
149 cnt_(0),
229 policy_(launch::none), 150 policy_(launch::none),
230 is_constructed(false), 151 continuations()
231 thread_was_interrupted(false),
232 continuation_ptr()
233 {} 152 {}
234 virtual ~shared_state_base() 153 virtual ~shared_state_base()
154 {
155 BOOST_ASSERT(cnt_==0);
156 }
157 virtual void block_if_needed(boost::unique_lock<boost::mutex>&)
235 {} 158 {}
159
160 bool valid(boost::unique_lock<boost::mutex>&) { return is_valid_; }
161 bool valid() {
162 boost::unique_lock<boost::mutex> lk(this->mutex);
163 return valid(lk);
164 }
165 void invalidate(boost::unique_lock<boost::mutex>&) { is_valid_ = false; }
166 void invalidate() {
167 boost::unique_lock<boost::mutex> lk(this->mutex);
168 invalidate(lk);
169 }
170 void validate(boost::unique_lock<boost::mutex>&) { is_valid_ = true; }
171 void validate() {
172 boost::unique_lock<boost::mutex> lk(this->mutex);
173 validate(lk);
174 }
175
176 void inc(boost::unique_lock<boost::mutex>&) { ++cnt_; }
177 void inc() { boost::unique_lock<boost::mutex> lk(this->mutex); inc(lk); }
178
179 void dec(boost::unique_lock<boost::mutex>& lk) {
180 if (--cnt_ == 0) {
181 block_if_needed(lk);
182 }
183 }
184 void dec() { boost::unique_lock<boost::mutex> lk(this->mutex); dec(lk); }
236 185
237 void set_deferred() 186 void set_deferred()
238 { 187 {
239 is_deferred_ = true; 188 is_deferred_ = true;
240 policy_ = launch::deferred; 189 policy_ = launch::deferred;
242 void set_async() 191 void set_async()
243 { 192 {
244 is_deferred_ = false; 193 is_deferred_ = false;
245 policy_ = launch::async; 194 policy_ = launch::async;
246 } 195 }
247 196 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
248 waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv) 197 void set_executor()
249 { 198 {
250 boost::unique_lock<boost::mutex> lock(mutex); 199 is_deferred_ = false;
200 policy_ = launch::executor;
201 }
202 #endif
203 notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
204 {
205 boost::unique_lock<boost::mutex> lock(this->mutex);
251 do_callback(lock); 206 do_callback(lock);
252 return external_waiters.insert(external_waiters.end(),&cv); 207 return external_waiters.insert(external_waiters.end(),&cv);
253 } 208 }
254 209
255 void remove_external_waiter(waiter_list::iterator it) 210 void unnotify_when_ready(notify_when_ready_handle it)
256 { 211 {
257 boost::lock_guard<boost::mutex> lock(mutex); 212 boost::lock_guard<boost::mutex> lock(this->mutex);
258 external_waiters.erase(it); 213 external_waiters.erase(it);
259 } 214 }
260 215
261 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION 216 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
262 void do_continuation(boost::unique_lock<boost::mutex>& lock) 217 void do_continuation(boost::unique_lock<boost::mutex>& lock)
263 { 218 {
264 if (continuation_ptr) { 219 if (! continuations.empty()) {
265 continuation_ptr->launch_continuation(lock); 220 continuations_type the_continuations = continuations;
266 if (! lock.owns_lock()) 221 continuations.clear();
267 lock.lock(); 222 relocker rlk(lock);
268 continuation_ptr.reset(); 223 for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) {
224 boost::unique_lock<boost::mutex> cont_lock((*it)->mutex);
225 (*it)->launch_continuation(cont_lock, *it);
226 }
269 } 227 }
270 } 228 }
271 #else 229 #else
272 void do_continuation(boost::unique_lock<boost::mutex>&) 230 void do_continuation(boost::unique_lock<boost::mutex>&)
273 { 231 {
274 } 232 }
275 #endif 233 #endif
276 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION 234 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
277 void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock) 235 virtual void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
278 { 236 {
279 continuation_ptr= continuation; 237 continuations.push_back(continuation);
280 if (done) { 238 if (done) {
281 do_continuation(lock); 239 do_continuation(lock);
282 } 240 }
283 } 241 }
284 #endif 242 #endif
293 } 251 }
294 do_continuation(lock); 252 do_continuation(lock);
295 } 253 }
296 void make_ready() 254 void make_ready()
297 { 255 {
298 boost::unique_lock<boost::mutex> lock(mutex); 256 boost::unique_lock<boost::mutex> lock(this->mutex);
299 mark_finished_internal(lock); 257 mark_finished_internal(lock);
300 } 258 }
301 259
302 void do_callback(boost::unique_lock<boost::mutex>& lock) 260 void do_callback(boost::unique_lock<boost::mutex>& lock)
303 { 261 {
307 relocker relock(lock); 265 relocker relock(lock);
308 local_callback(); 266 local_callback();
309 } 267 }
310 } 268 }
311 269
270 virtual bool run_if_is_deferred()
271 {
272 boost::unique_lock<boost::mutex> lk(this->mutex);
273 if (is_deferred_)
274 {
275 is_deferred_=false;
276 execute(lk);
277 return true;
278 }
279 else
280 return false;
281 }
282 virtual bool run_if_is_deferred_or_ready()
283 {
284 boost::unique_lock<boost::mutex> lk(this->mutex);
285 if (is_deferred_)
286 {
287 is_deferred_=false;
288 execute(lk);
289
290 return true;
291 }
292 else
293 return done;
294 }
312 void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true) 295 void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true)
313 { 296 {
314 do_callback(lk); 297 do_callback(lk);
315 //if (!done) // fixme why this doesn't work? 298 if (is_deferred_)
316 { 299 {
317 if (is_deferred_) 300 is_deferred_=false;
318 { 301 execute(lk);
319 is_deferred_=false;
320 execute(lk);
321 //lk.unlock();
322 }
323 else
324 {
325 while(!done)
326 {
327 waiters.wait(lk);
328 }
329 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
330 if(rethrow && thread_was_interrupted)
331 {
332 throw boost::thread_interrupted();
333 }
334 #endif
335 if(rethrow && exception)
336 {
337 boost::rethrow_exception(exception);
338 }
339 }
340 } 302 }
341 } 303 while(!done)
342 304 {
343 virtual void wait(bool rethrow=true) 305 waiters.wait(lk);
344 { 306 }
345 boost::unique_lock<boost::mutex> lock(mutex); 307 if(rethrow && exception)
308 {
309 boost::rethrow_exception(exception);
310 }
311 }
312
313 virtual void wait(boost::unique_lock<boost::mutex>& lock, bool rethrow=true)
314 {
346 wait_internal(lock, rethrow); 315 wait_internal(lock, rethrow);
316 }
317
318 void wait(bool rethrow=true)
319 {
320 boost::unique_lock<boost::mutex> lock(this->mutex);
321 wait(lock, rethrow);
347 } 322 }
348 323
349 #if defined BOOST_THREAD_USES_DATETIME 324 #if defined BOOST_THREAD_USES_DATETIME
350 bool timed_wait_until(boost::system_time const& target_time) 325 bool timed_wait_until(boost::system_time const& target_time)
351 { 326 {
352 boost::unique_lock<boost::mutex> lock(mutex); 327 boost::unique_lock<boost::mutex> lock(this->mutex);
353 if (is_deferred_) 328 if (is_deferred_)
354 return false; 329 return false;
355 330
356 do_callback(lock); 331 do_callback(lock);
357 while(!done) 332 while(!done)
369 344
370 template <class Clock, class Duration> 345 template <class Clock, class Duration>
371 future_status 346 future_status
372 wait_until(const chrono::time_point<Clock, Duration>& abs_time) 347 wait_until(const chrono::time_point<Clock, Duration>& abs_time)
373 { 348 {
374 boost::unique_lock<boost::mutex> lock(mutex); 349 boost::unique_lock<boost::mutex> lock(this->mutex);
375 if (is_deferred_) 350 if (is_deferred_)
376 return future_status::deferred; 351 return future_status::deferred;
377 do_callback(lock); 352 do_callback(lock);
378 while(!done) 353 while(!done)
379 { 354 {
392 mark_finished_internal(lock); 367 mark_finished_internal(lock);
393 } 368 }
394 369
395 void mark_exceptional_finish() 370 void mark_exceptional_finish()
396 { 371 {
397 boost::unique_lock<boost::mutex> lock(mutex); 372 boost::unique_lock<boost::mutex> lock(this->mutex);
398 mark_exceptional_finish_internal(boost::current_exception(), lock); 373 mark_exceptional_finish_internal(boost::current_exception(), lock);
399 } 374 }
400 375
401 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
402 void mark_interrupted_finish()
403 {
404 boost::unique_lock<boost::mutex> lock(mutex);
405 thread_was_interrupted=true;
406 mark_finished_internal(lock);
407 }
408
409 void set_interrupted_at_thread_exit()
410 {
411 unique_lock<boost::mutex> lk(mutex);
412 thread_was_interrupted=true;
413 if (has_value(lk))
414 {
415 throw_exception(promise_already_satisfied());
416 }
417 detail::make_ready_at_thread_exit(shared_from_this());
418 }
419 #endif
420
421 void set_exception_at_thread_exit(exception_ptr e) 376 void set_exception_at_thread_exit(exception_ptr e)
422 { 377 {
423 unique_lock<boost::mutex> lk(mutex); 378 unique_lock<boost::mutex> lk(this->mutex);
424 if (has_value(lk)) 379 if (has_value(lk))
425 { 380 {
426 throw_exception(promise_already_satisfied()); 381 throw_exception(promise_already_satisfied());
427 } 382 }
428 exception=e; 383 exception=e;
429 this->is_constructed = true; 384 this->is_constructed = true;
430 detail::make_ready_at_thread_exit(shared_from_this()); 385 detail::make_ready_at_thread_exit(shared_from_this());
431
432 } 386 }
433 387
434 bool has_value() const 388 bool has_value() const
435 { 389 {
436 boost::lock_guard<boost::mutex> lock(mutex); 390 boost::lock_guard<boost::mutex> lock(this->mutex);
437 return done && !(exception 391 return done && ! exception;
438 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
439 || thread_was_interrupted
440 #endif
441 );
442 } 392 }
443 393
444 bool has_value(unique_lock<boost::mutex>& ) const 394 bool has_value(unique_lock<boost::mutex>& ) const
445 { 395 {
446 return done && !(exception 396 return done && ! exception;
447 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
448 || thread_was_interrupted
449 #endif
450 );
451 } 397 }
452 398
453 bool has_exception() const 399 bool has_exception() const
454 { 400 {
455 boost::lock_guard<boost::mutex> lock(mutex); 401 boost::lock_guard<boost::mutex> lock(this->mutex);
456 return done && (exception 402 return done && exception;
457 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
458 || thread_was_interrupted
459 #endif
460 );
461 }
462
463 bool has_exception(unique_lock<boost::mutex>&) const
464 {
465 return done && (exception
466 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
467 || thread_was_interrupted
468 #endif
469 );
470 }
471
472 bool is_deferred(boost::lock_guard<boost::mutex>&) const {
473 return is_deferred_;
474 } 403 }
475 404
476 launch launch_policy(boost::unique_lock<boost::mutex>&) const 405 launch launch_policy(boost::unique_lock<boost::mutex>&) const
477 { 406 {
478 return policy_; 407 return policy_;
479 } 408 }
480 409
481 future_state::state get_state() const 410 future_state::state get_state(boost::unique_lock<boost::mutex>& lk) const
482 { 411 {
483 boost::lock_guard<boost::mutex> guard(mutex);
484 if(!done) 412 if(!done)
485 { 413 {
486 return future_state::waiting; 414 return future_state::waiting;
487 } 415 }
488 else 416 else
489 { 417 {
490 return future_state::ready; 418 return future_state::ready;
491 } 419 }
492 } 420 }
421 future_state::state get_state() const
422 {
423 boost::lock_guard<boost::mutex> guard(this->mutex);
424 if(!done)
425 {
426 return future_state::waiting;
427 }
428 else
429 {
430 return future_state::ready;
431 }
432 }
493 433
494 exception_ptr get_exception_ptr() 434 exception_ptr get_exception_ptr()
495 { 435 {
496 boost::unique_lock<boost::mutex> lock(mutex); 436 boost::unique_lock<boost::mutex> lock(this->mutex);
497 return get_exception_ptr(lock);
498 }
499 exception_ptr get_exception_ptr(boost::unique_lock<boost::mutex>& lock)
500 {
501 wait_internal(lock, false); 437 wait_internal(lock, false);
502 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
503 if(thread_was_interrupted)
504 {
505 return copy_exception(boost::thread_interrupted());
506 }
507 #endif
508 return exception; 438 return exception;
509 } 439 }
510 440
511 template<typename F,typename U> 441 template<typename F,typename U>
512 void set_wait_callback(F f,U* u) 442 void set_wait_callback(F f,U* u)
513 { 443 {
514 boost::lock_guard<boost::mutex> lock(mutex); 444 boost::lock_guard<boost::mutex> lock(this->mutex);
515 callback=boost::bind(f,boost::ref(*u)); 445 callback=boost::bind(f,boost::ref(*u));
516 } 446 }
517 447
518 virtual void execute(boost::unique_lock<boost::mutex>&) {} 448 virtual void execute(boost::unique_lock<boost::mutex>&) {}
519 449
520 private: 450 private:
521 shared_state_base(shared_state_base const&); 451 shared_state_base(shared_state_base const&);
522 shared_state_base& operator=(shared_state_base const&); 452 shared_state_base& operator=(shared_state_base const&);
523 }; 453 };
524 454
525 template<typename T>
526 struct future_traits
527 {
528 typedef boost::scoped_ptr<T> storage_type;
529 struct dummy;
530 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
531 typedef T const& source_reference_type;
532 //typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
533 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
534 //typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type;
535 typedef T move_dest_type;
536 #elif defined BOOST_THREAD_USES_MOVE
537 typedef typename boost::mpl::if_c<boost::is_fundamental<T>::value,T,T&>::type source_reference_type;
538 //typedef typename boost::mpl::if_c<boost::is_fundamental<T>::value,T,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
539 //typedef typename boost::mpl::if_c<boost::enable_move_utility_emulation<T>::value,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
540 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
541 typedef T move_dest_type;
542 #else
543 typedef T& source_reference_type;
544 typedef typename boost::mpl::if_<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
545 typedef typename boost::mpl::if_<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
546 #endif
547
548
549 typedef const T& shared_future_get_result_type;
550
551 static void init(storage_type& storage,source_reference_type t)
552 {
553 storage.reset(new T(t));
554 }
555
556 static void init(storage_type& storage,rvalue_source_type t)
557 {
558 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
559 storage.reset(new T(boost::forward<T>(t)));
560 #else
561 storage.reset(new T(static_cast<rvalue_source_type>(t)));
562 #endif
563 }
564
565 static void cleanup(storage_type& storage)
566 {
567 storage.reset();
568 }
569 };
570
571 template<typename T>
572 struct future_traits<T&>
573 {
574 typedef T* storage_type;
575 typedef T& source_reference_type;
576 //struct rvalue_source_type
577 //{};
578 typedef T& move_dest_type;
579 typedef T& shared_future_get_result_type;
580
581 static void init(storage_type& storage,T& t)
582 {
583 storage=&t;
584 }
585
586 static void cleanup(storage_type& storage)
587 {
588 storage=0;
589 }
590 };
591
592 template<>
593 struct future_traits<void>
594 {
595 typedef bool storage_type;
596 typedef void move_dest_type;
597 typedef void shared_future_get_result_type;
598
599 static void init(storage_type& storage)
600 {
601 storage=true;
602 }
603
604 static void cleanup(storage_type& storage)
605 {
606 storage=false;
607 }
608
609 };
610
611 // Used to create stand-alone futures 455 // Used to create stand-alone futures
612 template<typename T> 456 template<typename T>
613 struct shared_state: 457 struct shared_state:
614 detail::shared_state_base 458 detail::shared_state_base
615 { 459 {
616 typedef typename future_traits<T>::storage_type storage_type; 460 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
617 typedef typename future_traits<T>::source_reference_type source_reference_type; 461 typedef boost::optional<T> storage_type;
618 typedef typename future_traits<T>::rvalue_source_type rvalue_source_type; 462 #else
619 typedef typename future_traits<T>::move_dest_type move_dest_type; 463 typedef boost::csbl::unique_ptr<T> storage_type;
620 typedef typename future_traits<T>::shared_future_get_result_type shared_future_get_result_type; 464 #endif
465 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
466 typedef T const& source_reference_type;
467 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
468 typedef T move_dest_type;
469 #elif defined BOOST_THREAD_USES_MOVE
470 typedef typename conditional<boost::is_fundamental<T>::value,T,T const&>::type source_reference_type;
471 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
472 typedef T move_dest_type;
473 #else
474 typedef T& source_reference_type;
475 typedef typename conditional<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >::value, BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
476 typedef typename conditional<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >::value, BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
477 #endif
478
479 typedef const T& shared_future_get_result_type;
621 480
622 storage_type result; 481 storage_type result;
623 482
624 shared_state(): 483 shared_state():
625 result(0) 484 result()
626 {} 485 {}
627 486
628 ~shared_state() 487 ~shared_state()
629 {} 488 {}
630 489
631 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock) 490 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
632 { 491 {
633 future_traits<T>::init(result,result_); 492 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
493 result = result_;
494 #else
495 result.reset(new T(result_));
496 #endif
634 this->mark_finished_internal(lock); 497 this->mark_finished_internal(lock);
635 } 498 }
636 499
637 void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock) 500 void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
638 { 501 {
502 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
503 result = boost::move(result_);
504 #elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
505 result.reset(new T(boost::move(result_)));
506 #else
507 result.reset(new T(static_cast<rvalue_source_type>(result_)));
508 #endif
509 this->mark_finished_internal(lock);
510 }
511
512
513 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
514 template <class ...Args>
515 void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock, BOOST_THREAD_FWD_REF(Args)... args)
516 {
517 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
518 result.emplace(boost::forward<Args>(args)...);
519 #else
520 result.reset(new T(boost::forward<Args>(args)...));
521 #endif
522 this->mark_finished_internal(lock);
523 }
524 #endif
525
526 void mark_finished_with_result(source_reference_type result_)
527 {
528 boost::unique_lock<boost::mutex> lock(this->mutex);
529 this->mark_finished_with_result_internal(result_, lock);
530 }
531
532 void mark_finished_with_result(rvalue_source_type result_)
533 {
534 boost::unique_lock<boost::mutex> lock(this->mutex);
535
639 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 536 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
640 future_traits<T>::init(result,boost::forward<T>(result_)); 537 mark_finished_with_result_internal(boost::move(result_), lock);
641 #else
642 future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
643 #endif
644 this->mark_finished_internal(lock);
645 }
646
647 void mark_finished_with_result(source_reference_type result_)
648 {
649 boost::unique_lock<boost::mutex> lock(mutex);
650 this->mark_finished_with_result_internal(result_, lock);
651 }
652
653 void mark_finished_with_result(rvalue_source_type result_)
654 {
655 boost::unique_lock<boost::mutex> lock(mutex);
656
657 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
658 mark_finished_with_result_internal(boost::forward<T>(result_), lock);
659 #else 538 #else
660 mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock); 539 mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
661 #endif 540 #endif
662 } 541 }
663 542
664 virtual move_dest_type get() 543 storage_type& get_storage(boost::unique_lock<boost::mutex>& lk)
665 { 544 {
666 wait(); 545 wait_internal(lk);
667 return boost::move(*result); 546 return result;
668 } 547 }
669 548 virtual move_dest_type get(boost::unique_lock<boost::mutex>& lk)
670 virtual shared_future_get_result_type get_sh() 549 {
671 { 550 return boost::move(*get_storage(lk));
672 wait(); 551 }
673 return *result; 552 move_dest_type get()
674 } 553 {
675 554 boost::unique_lock<boost::mutex> lk(this->mutex);
676 //void set_value_at_thread_exit(const T & result_) 555 return this->get(lk);
556 }
557
558 virtual shared_future_get_result_type get_sh(boost::unique_lock<boost::mutex>& lk)
559 {
560 return *get_storage(lk);
561 }
562 shared_future_get_result_type get_sh()
563 {
564 boost::unique_lock<boost::mutex> lk(this->mutex);
565 return this->get_sh(lk);
566 }
567
677 void set_value_at_thread_exit(source_reference_type result_) 568 void set_value_at_thread_exit(source_reference_type result_)
678 { 569 {
679 unique_lock<boost::mutex> lk(this->mutex); 570 unique_lock<boost::mutex> lk(this->mutex);
680 if (this->has_value(lk)) 571 if (this->has_value(lk))
681 { 572 {
682 throw_exception(promise_already_satisfied()); 573 throw_exception(promise_already_satisfied());
683 } 574 }
684 //future_traits<T>::init(result,result_); 575 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
576 result = result_;
577 #else
685 result.reset(new T(result_)); 578 result.reset(new T(result_));
579 #endif
686 580
687 this->is_constructed = true; 581 this->is_constructed = true;
688 detail::make_ready_at_thread_exit(shared_from_this()); 582 detail::make_ready_at_thread_exit(shared_from_this());
689 } 583 }
690 //void set_value_at_thread_exit(BOOST_THREAD_RV_REF(T) result_)
691 void set_value_at_thread_exit(rvalue_source_type result_) 584 void set_value_at_thread_exit(rvalue_source_type result_)
692 { 585 {
693 unique_lock<boost::mutex> lk(this->mutex); 586 unique_lock<boost::mutex> lk(this->mutex);
694 if (this->has_value(lk)) 587 if (this->has_value(lk))
695 throw_exception(promise_already_satisfied()); 588 throw_exception(promise_already_satisfied());
696 result.reset(new T(boost::move(result_))); 589
697 //future_traits<T>::init(result,static_cast<rvalue_source_type>(result_)); 590 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
591 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
592 result = boost::move(result_);
593 #else
594 result.reset(new T(boost::move(result_)));
595 #endif
596 #else
597 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
598 result = boost::move(result_);
599 #else
600 result.reset(new T(static_cast<rvalue_source_type>(result_)));
601 #endif
602 #endif
698 this->is_constructed = true; 603 this->is_constructed = true;
699 detail::make_ready_at_thread_exit(shared_from_this()); 604 detail::make_ready_at_thread_exit(shared_from_this());
700 } 605 }
701
702 606
703 private: 607 private:
704 shared_state(shared_state const&); 608 shared_state(shared_state const&);
705 shared_state& operator=(shared_state const&); 609 shared_state& operator=(shared_state const&);
706 }; 610 };
707 611
708 template<typename T> 612 template<typename T>
709 struct shared_state<T&>: 613 struct shared_state<T&>:
710 detail::shared_state_base 614 detail::shared_state_base
711 { 615 {
712 typedef typename future_traits<T&>::storage_type storage_type; 616 typedef T* storage_type;
713 typedef typename future_traits<T&>::source_reference_type source_reference_type; 617 typedef T& source_reference_type;
714 typedef typename future_traits<T&>::move_dest_type move_dest_type; 618 typedef T& move_dest_type;
715 typedef typename future_traits<T&>::shared_future_get_result_type shared_future_get_result_type; 619 typedef T& shared_future_get_result_type;
716 620
717 T* result; 621 T* result;
718 622
719 shared_state(): 623 shared_state():
720 result(0) 624 result(0)
724 { 628 {
725 } 629 }
726 630
727 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock) 631 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
728 { 632 {
729 //future_traits<T>::init(result,result_);
730 result= &result_; 633 result= &result_;
731 mark_finished_internal(lock); 634 mark_finished_internal(lock);
732 } 635 }
733 636
734 void mark_finished_with_result(source_reference_type result_) 637 void mark_finished_with_result(source_reference_type result_)
735 { 638 {
736 boost::unique_lock<boost::mutex> lock(mutex); 639 boost::unique_lock<boost::mutex> lock(this->mutex);
737 mark_finished_with_result_internal(result_, lock); 640 mark_finished_with_result_internal(result_, lock);
738 } 641 }
739 642
740 virtual T& get() 643 virtual T& get(boost::unique_lock<boost::mutex>& lock)
741 { 644 {
742 wait(); 645 wait_internal(lock);
743 return *result; 646 return *result;
744 } 647 }
745 648 T& get()
746 virtual T& get_sh() 649 {
747 { 650 boost::unique_lock<boost::mutex> lk(this->mutex);
748 wait(); 651 return get(lk);
652 }
653
654 virtual T& get_sh(boost::unique_lock<boost::mutex>& lock)
655 {
656 wait_internal(lock);
749 return *result; 657 return *result;
658 }
659 T& get_sh()
660 {
661 boost::unique_lock<boost::mutex> lock(this->mutex);
662 return get_sh(lock);
750 } 663 }
751 664
752 void set_value_at_thread_exit(T& result_) 665 void set_value_at_thread_exit(T& result_)
753 { 666 {
754 unique_lock<boost::mutex> lk(this->mutex); 667 unique_lock<boost::mutex> lk(this->mutex);
755 if (this->has_value(lk)) 668 if (this->has_value(lk))
756 throw_exception(promise_already_satisfied()); 669 throw_exception(promise_already_satisfied());
757 //future_traits<T>::init(result,result_);
758 result= &result_; 670 result= &result_;
759 this->is_constructed = true; 671 this->is_constructed = true;
760 detail::make_ready_at_thread_exit(shared_from_this()); 672 detail::make_ready_at_thread_exit(shared_from_this());
761 } 673 }
762 674
767 679
768 template<> 680 template<>
769 struct shared_state<void>: 681 struct shared_state<void>:
770 detail::shared_state_base 682 detail::shared_state_base
771 { 683 {
772 typedef void shared_future_get_result_type; 684 typedef void shared_future_get_result_type;
685 typedef void move_dest_type;
773 686
774 shared_state() 687 shared_state()
775 {} 688 {}
776 689
777 void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock) 690 void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
779 mark_finished_internal(lock); 692 mark_finished_internal(lock);
780 } 693 }
781 694
782 void mark_finished_with_result() 695 void mark_finished_with_result()
783 { 696 {
784 boost::unique_lock<boost::mutex> lock(mutex); 697 boost::unique_lock<boost::mutex> lock(this->mutex);
785 mark_finished_with_result_internal(lock); 698 mark_finished_with_result_internal(lock);
786 } 699 }
787 700
788 virtual void get() 701 virtual void get(boost::unique_lock<boost::mutex>& lock)
789 { 702 {
790 this->wait(); 703 this->wait_internal(lock);
791 } 704 }
792 705 void get()
793 virtual void get_sh() 706 {
794 { 707 boost::unique_lock<boost::mutex> lock(this->mutex);
795 wait(); 708 this->get(lock);
709 }
710
711 virtual void get_sh(boost::unique_lock<boost::mutex>& lock)
712 {
713 this->wait_internal(lock);
714 }
715 void get_sh()
716 {
717 boost::unique_lock<boost::mutex> lock(this->mutex);
718 this->get_sh(lock);
796 } 719 }
797 720
798 void set_value_at_thread_exit() 721 void set_value_at_thread_exit()
799 { 722 {
800 unique_lock<boost::mutex> lk(this->mutex); 723 unique_lock<boost::mutex> lk(this->mutex);
826 public: 749 public:
827 future_async_shared_state_base() 750 future_async_shared_state_base()
828 { 751 {
829 this->set_async(); 752 this->set_async();
830 } 753 }
831 explicit future_async_shared_state_base(BOOST_THREAD_RV_REF(boost::thread) th) : 754
832 thr_(boost::move(th)) 755 virtual void block_if_needed(boost::unique_lock<boost::mutex>& lk)
833 { 756 {
834 this->set_async(); 757 this->wait(lk, false);
835 } 758 }
836 759
837 ~future_async_shared_state_base() 760 ~future_async_shared_state_base()
838 { 761 {
839 join(); 762 join();
840 } 763 }
841 764
842 virtual void wait(bool rethrow) 765 virtual void wait(boost::unique_lock<boost::mutex>& lk, bool rethrow)
843 { 766 {
844 join(); 767 {
845 this->base_type::wait(rethrow); 768 relocker rlk(lk);
769 join();
770 }
771 this->base_type::wait(lk, rethrow);
846 } 772 }
847 }; 773 };
848 774
849 ///////////////////////// 775 /////////////////////////
850 /// future_async_shared_state 776 /// future_async_shared_state
851 ///////////////////////// 777 /////////////////////////
852 template<typename Rp, typename Fp> 778 template<typename Rp, typename Fp>
853 struct future_async_shared_state: future_async_shared_state_base<Rp> 779 struct future_async_shared_state: future_async_shared_state_base<Rp>
854 { 780 {
855 typedef future_async_shared_state_base<Rp> base_type; 781 future_async_shared_state()
856
857 public:
858 explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) :
859 base_type(thread(&future_async_shared_state::run, this, boost::forward<Fp>(f)))
860 { 782 {
861 } 783 }
862 784
863 static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f) 785 void init(BOOST_THREAD_FWD_REF(Fp) f)
864 { 786 {
787 shared_ptr<boost::detail::shared_state_base> that = this->shared_from_this();
788 this->thr_ = thread(&future_async_shared_state::run, that, boost::forward<Fp>(f));
789 }
790
791 static void run(shared_ptr<boost::detail::shared_state_base> that_, BOOST_THREAD_FWD_REF(Fp) f)
792 {
793 future_async_shared_state* that = dynamic_cast<future_async_shared_state*>(that_.get());
865 try 794 try
866 { 795 {
867 that->mark_finished_with_result(f()); 796 that->mark_finished_with_result(f());
868 } 797 }
869 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
870 catch(thread_interrupted& )
871 {
872 that->mark_interrupted_finish();
873 }
874 #endif
875 catch(...) 798 catch(...)
876 { 799 {
877 that->mark_exceptional_finish(); 800 that->mark_exceptional_finish();
878 } 801 }
879 } 802 }
880 }; 803 };
881 804
882 template<typename Fp> 805 template<typename Fp>
883 struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void> 806 struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void>
884 { 807 {
885 typedef future_async_shared_state_base<void> base_type; 808 void init(BOOST_THREAD_FWD_REF(Fp) f)
886
887 public:
888 explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) :
889 base_type(thread(&future_async_shared_state::run, this, boost::forward<Fp>(f)))
890 { 809 {
810 this->thr_ = thread(&future_async_shared_state::run, this->shared_from_this(), boost::move(f));
891 } 811 }
892 812
893 static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f) 813 static void run(shared_ptr<boost::detail::shared_state_base> that_, BOOST_THREAD_FWD_REF(Fp) f)
894 { 814 {
815 future_async_shared_state* that = dynamic_cast<future_async_shared_state*>(that_.get());
895 try 816 try
896 { 817 {
897 f(); 818 f();
898 that->mark_finished_with_result(); 819 that->mark_finished_with_result();
899 } 820 }
900 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
901 catch(thread_interrupted& )
902 {
903 that->mark_interrupted_finish();
904 }
905 #endif
906 catch(...) 821 catch(...)
907 { 822 {
908 that->mark_exceptional_finish(); 823 that->mark_exceptional_finish();
909 } 824 }
910 } 825 }
911 }; 826 };
912 827
913 template<typename Rp, typename Fp> 828 template<typename Rp, typename Fp>
914 struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&> 829 struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&>
915 { 830 {
916 typedef future_async_shared_state_base<Rp&> base_type; 831 void init(BOOST_THREAD_FWD_REF(Fp) f)
917
918 public:
919 explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) :
920 base_type(thread(&future_async_shared_state::run, this, boost::forward<Fp>(f)))
921 { 832 {
833 this->thr_ = thread(&future_async_shared_state::run, this->shared_from_this(), boost::move(f));
922 } 834 }
923 835
924 static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f) 836 static void run(shared_ptr<boost::detail::shared_state_base> that_, BOOST_THREAD_FWD_REF(Fp) f)
925 { 837 {
838 future_async_shared_state* that = dynamic_cast<future_async_shared_state*>(that_.get());
926 try 839 try
927 { 840 {
928 that->mark_finished_with_result(f()); 841 that->mark_finished_with_result(f());
929 } 842 }
930 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
931 catch(thread_interrupted& )
932 {
933 that->mark_interrupted_finish();
934 }
935 #endif
936 catch(...) 843 catch(...)
937 { 844 {
938 that->mark_exceptional_finish(); 845 that->mark_exceptional_finish();
939 } 846 }
940 } 847 }
949 typedef shared_state<Rp> base_type; 856 typedef shared_state<Rp> base_type;
950 Fp func_; 857 Fp func_;
951 858
952 public: 859 public:
953 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) 860 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
954 : func_(boost::forward<Fp>(f)) 861 : func_(boost::move(f))
955 { 862 {
956 this->set_deferred(); 863 this->set_deferred();
957 } 864 }
958 865
959 virtual void execute(boost::unique_lock<boost::mutex>& lck) { 866 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
977 typedef shared_state<Rp&> base_type; 884 typedef shared_state<Rp&> base_type;
978 Fp func_; 885 Fp func_;
979 886
980 public: 887 public:
981 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) 888 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
982 : func_(boost::forward<Fp>(f)) 889 : func_(boost::move(f))
983 { 890 {
984 this->set_deferred(); 891 this->set_deferred();
985 } 892 }
986 893
987 virtual void execute(boost::unique_lock<boost::mutex>& lck) { 894 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1002 typedef shared_state<void> base_type; 909 typedef shared_state<void> base_type;
1003 Fp func_; 910 Fp func_;
1004 911
1005 public: 912 public:
1006 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) 913 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1007 : func_(boost::forward<Fp>(f)) 914 : func_(boost::move(f))
1008 { 915 {
1009 this->set_deferred(); 916 this->set_deferred();
1010 } 917 }
1011 918
1012 virtual void execute(boost::unique_lock<boost::mutex>& lck) { 919 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1023 this->mark_exceptional_finish_internal(current_exception(), lck); 930 this->mark_exceptional_finish_internal(current_exception(), lck);
1024 } 931 }
1025 } 932 }
1026 }; 933 };
1027 934
1028 // template<typename T, typename Allocator>
1029 // struct shared_state_alloc: public shared_state<T>
1030 // {
1031 // typedef shared_state<T> base;
1032 // Allocator alloc_;
1033 //
1034 // public:
1035 // explicit shared_state_alloc(const Allocator& a)
1036 // : alloc_(a) {}
1037 //
1038 // };
1039 class future_waiter 935 class future_waiter
1040 { 936 {
1041 struct registered_waiter; 937 struct registered_waiter;
1042 typedef std::vector<int>::size_type count_type; 938 typedef std::vector<int>::size_type count_type;
1043 939
1044 struct registered_waiter 940 struct registered_waiter
1045 { 941 {
1046 boost::shared_ptr<detail::shared_state_base> future_; 942 boost::shared_ptr<detail::shared_state_base> future_;
1047 detail::shared_state_base::waiter_list::iterator wait_iterator; 943 detail::shared_state_base::notify_when_ready_handle handle;
1048 count_type index; 944 count_type index;
1049 945
1050 registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future, 946 registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
1051 detail::shared_state_base::waiter_list::iterator wait_iterator_, 947 detail::shared_state_base::notify_when_ready_handle handle_,
1052 count_type index_): 948 count_type index_):
1053 future_(a_future),wait_iterator(wait_iterator_),index(index_) 949 future_(a_future),handle(handle_),index(index_)
1054 {} 950 {}
1055 }; 951 };
1056 952
1057 struct all_futures_lock 953 struct all_futures_lock
1058 { 954 {
1067 all_futures_lock(std::vector<registered_waiter>& futures): 963 all_futures_lock(std::vector<registered_waiter>& futures):
1068 count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count]) 964 count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
1069 { 965 {
1070 for(count_type_portable i=0;i<count;++i) 966 for(count_type_portable i=0;i<count;++i)
1071 { 967 {
1072 #if defined __DECCXX || defined __SUNPRO_CC || defined __hpux 968 locks[i]=BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(futures[i].future_->mutex));
1073 locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex).move();
1074 #else
1075 locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex);
1076 #endif
1077 } 969 }
1078 } 970 }
1079 971
1080 void lock() 972 void lock()
1081 { 973 {
1090 } 982 }
1091 } 983 }
1092 }; 984 };
1093 985
1094 boost::condition_variable_any cv; 986 boost::condition_variable_any cv;
1095 std::vector<registered_waiter> futures; 987 std::vector<registered_waiter> futures_;
1096 count_type future_count; 988 count_type future_count;
1097 989
1098 public: 990 public:
1099 future_waiter(): 991 future_waiter():
1100 future_count(0) 992 future_count(0)
1103 template<typename F> 995 template<typename F>
1104 void add(F& f) 996 void add(F& f)
1105 { 997 {
1106 if(f.future_) 998 if(f.future_)
1107 { 999 {
1108 futures.push_back(registered_waiter(f.future_,f.future_->register_external_waiter(cv),future_count)); 1000 registered_waiter waiter(f.future_,f.future_->notify_when_ready(cv),future_count);
1001 try {
1002 futures_.push_back(waiter);
1003 } catch(...) {
1004 f.future_->unnotify_when_ready(waiter.handle);
1005 throw;
1006 }
1109 } 1007 }
1110 ++future_count; 1008 ++future_count;
1111 } 1009 }
1112 1010
1011 #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1012 template<typename F1, typename... Fs>
1013 void add(F1& f1, Fs&... fs)
1014 {
1015 add(f1); add(fs...);
1016 }
1017 #endif
1018
1113 count_type wait() 1019 count_type wait()
1114 { 1020 {
1115 all_futures_lock lk(futures); 1021 all_futures_lock lk(futures_);
1116 for(;;) 1022 for(;;)
1117 { 1023 {
1118 for(count_type i=0;i<futures.size();++i) 1024 for(count_type i=0;i<futures_.size();++i)
1119 { 1025 {
1120 if(futures[i].future_->done) 1026 if(futures_[i].future_->done)
1121 { 1027 {
1122 return futures[i].index; 1028 return futures_[i].index;
1123 } 1029 }
1124 } 1030 }
1125 cv.wait(lk); 1031 cv.wait(lk);
1126 } 1032 }
1127 } 1033 }
1128 1034
1129 ~future_waiter() 1035 ~future_waiter()
1130 { 1036 {
1131 for(count_type i=0;i<futures.size();++i) 1037 for(count_type i=0;i<futures_.size();++i)
1132 { 1038 {
1133 futures[i].future_->remove_external_waiter(futures[i].wait_iterator); 1039 futures_[i].future_->unnotify_when_ready(futures_[i].handle);
1134 } 1040 }
1135 } 1041 }
1136
1137 }; 1042 };
1138 1043
1139 } 1044 }
1140 1045
1141 template <typename R> 1046 template <typename R>
1143 1048
1144 template <typename R> 1049 template <typename R>
1145 class shared_future; 1050 class shared_future;
1146 1051
1147 template<typename T> 1052 template<typename T>
1148 struct is_future_type 1053 struct is_future_type<BOOST_THREAD_FUTURE<T> > : true_type
1149 { 1054 {
1150 BOOST_STATIC_CONSTANT(bool, value=false);
1151 typedef void type;
1152 }; 1055 };
1153 1056
1154 template<typename T> 1057 template<typename T>
1155 struct is_future_type<BOOST_THREAD_FUTURE<T> > 1058 struct is_future_type<shared_future<T> > : true_type
1156 { 1059 {
1157 BOOST_STATIC_CONSTANT(bool, value=true);
1158 typedef T type;
1159 }; 1060 };
1160 1061
1161 template<typename T> 1062 // template<typename Iterator>
1162 struct is_future_type<shared_future<T> > 1063 // typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
1163 { 1064 // {
1164 BOOST_STATIC_CONSTANT(bool, value=true); 1065 // if(begin==end)
1165 typedef T type; 1066 // return end;
1166 }; 1067 //
1167 1068 // detail::future_waiter waiter;
1168 template<typename Iterator> 1069 // for(Iterator current=begin;current!=end;++current)
1169 typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end) 1070 // {
1170 { 1071 // waiter.add(*current);
1171 for(Iterator current=begin;current!=end;++current) 1072 // }
1172 { 1073 // return boost::next(begin,waiter.wait());
1173 current->wait(); 1074 // }
1174 } 1075
1175 } 1076 #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1176
1177 template<typename F1,typename F2>
1178 typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)
1179 {
1180 f1.wait();
1181 f2.wait();
1182 }
1183
1184 template<typename F1,typename F2,typename F3>
1185 void wait_for_all(F1& f1,F2& f2,F3& f3)
1186 {
1187 f1.wait();
1188 f2.wait();
1189 f3.wait();
1190 }
1191
1192 template<typename F1,typename F2,typename F3,typename F4>
1193 void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)
1194 {
1195 f1.wait();
1196 f2.wait();
1197 f3.wait();
1198 f4.wait();
1199 }
1200
1201 template<typename F1,typename F2,typename F3,typename F4,typename F5>
1202 void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
1203 {
1204 f1.wait();
1205 f2.wait();
1206 f3.wait();
1207 f4.wait();
1208 f5.wait();
1209 }
1210
1211 template<typename Iterator>
1212 typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
1213 {
1214 if(begin==end)
1215 return end;
1216
1217 detail::future_waiter waiter;
1218 for(Iterator current=begin;current!=end;++current)
1219 {
1220 waiter.add(*current);
1221 }
1222 return boost::next(begin,waiter.wait());
1223 }
1224
1225 template<typename F1,typename F2> 1077 template<typename F1,typename F2>
1226 typename boost::enable_if<is_future_type<F1>,unsigned>::type wait_for_any(F1& f1,F2& f2) 1078 typename boost::enable_if<is_future_type<F1>,unsigned>::type wait_for_any(F1& f1,F2& f2)
1227 { 1079 {
1228 detail::future_waiter waiter; 1080 detail::future_waiter waiter;
1229 waiter.add(f1); 1081 waiter.add(f1);
1261 waiter.add(f3); 1113 waiter.add(f3);
1262 waiter.add(f4); 1114 waiter.add(f4);
1263 waiter.add(f5); 1115 waiter.add(f5);
1264 return waiter.wait(); 1116 return waiter.wait();
1265 } 1117 }
1118 #else
1119 template<typename F1, typename... Fs>
1120 typename boost::enable_if<is_future_type<F1>, unsigned>::type wait_for_any(F1& f1, Fs&... fs)
1121 {
1122 detail::future_waiter waiter;
1123 waiter.add(f1, fs...);
1124 return waiter.wait();
1125 }
1126 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1266 1127
1267 template <typename R> 1128 template <typename R>
1268 class promise; 1129 class promise;
1269 1130
1270 template <typename R> 1131 template <typename R>
1273 namespace detail 1134 namespace detail
1274 { 1135 {
1275 /// Common implementation for all the futures independently of the return type 1136 /// Common implementation for all the futures independently of the return type
1276 class base_future 1137 class base_future
1277 { 1138 {
1278 //BOOST_THREAD_MOVABLE(base_future) 1139 public:
1279
1280 }; 1140 };
1281 /// Common implementation for future and shared_future. 1141 /// Common implementation for future and shared_future.
1282 template <typename R> 1142 template <typename R>
1283 class basic_future : public base_future 1143 class basic_future : public base_future
1284 { 1144 {
1285 protected: 1145 protected:
1286 public: 1146 public:
1287 1147
1288 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr; 1148 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
1149 typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
1150
1151 static //BOOST_CONSTEXPR
1152 future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
1153 promise<R> p;
1154 p.set_exception(ex.ptr_);
1155 return p.get_future().future_;
1156 }
1157
1158 void set_exceptional_if_invalid() {
1159 if (valid()) return;
1160 promise<R> p;
1161 p.set_exception(future_uninitialized());
1162 future_ = p.get_future().future_;
1163 }
1289 1164
1290 future_ptr future_; 1165 future_ptr future_;
1291 1166
1292 basic_future(future_ptr a_future): 1167 basic_future(future_ptr a_future):
1293 future_(a_future) 1168 future_(a_future)
1294 { 1169 {
1295 } 1170 if (a_future) a_future->inc();
1296 // Copy construction from a shared_future 1171 }
1297 explicit basic_future(const shared_future<R>&) BOOST_NOEXCEPT;
1298 1172
1299 public: 1173 public:
1300 typedef future_state::state state; 1174 typedef future_state::state state;
1301 1175
1302 BOOST_THREAD_MOVABLE(basic_future) 1176 BOOST_THREAD_MOVABLE_ONLY(basic_future)
1303 basic_future(): future_() {} 1177 basic_future(): future_() {}
1304 ~basic_future() {} 1178
1179
1180 //BOOST_CONSTEXPR
1181 basic_future(exceptional_ptr const& ex)
1182 : future_(make_exceptional_future_ptr(ex))
1183 {
1184 future_->inc();
1185 }
1186
1187 ~basic_future() {
1188 if (future_) future_->dec();
1189 }
1305 1190
1306 basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT: 1191 basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
1307 future_(BOOST_THREAD_RV(other).future_) 1192 future_(BOOST_THREAD_RV(other).future_)
1308 { 1193 {
1309 BOOST_THREAD_RV(other).future_.reset(); 1194 BOOST_THREAD_RV(other).future_.reset();
1310 } 1195 }
1311 basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT 1196 basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
1312 { 1197 {
1198 if (this->future_) {
1199 this->future_->dec();
1200 }
1313 future_=BOOST_THREAD_RV(other).future_; 1201 future_=BOOST_THREAD_RV(other).future_;
1314 BOOST_THREAD_RV(other).future_.reset(); 1202 BOOST_THREAD_RV(other).future_.reset();
1315 return *this; 1203 return *this;
1316 } 1204 }
1317 void swap(basic_future& that) BOOST_NOEXCEPT 1205 void swap(basic_future& that) BOOST_NOEXCEPT
1318 { 1206 {
1319 future_.swap(that.future_); 1207 future_.swap(that.future_);
1320 } 1208 }
1321 // functions to check state, and wait for ready 1209 // functions to check state, and wait for ready
1210 state get_state(boost::unique_lock<boost::mutex>& lk) const
1211 {
1212 if(!future_)
1213 {
1214 return future_state::uninitialized;
1215 }
1216 return future_->get_state(lk);
1217 }
1322 state get_state() const 1218 state get_state() const
1323 { 1219 {
1324 if(!future_) 1220 if(!future_)
1325 { 1221 {
1326 return future_state::uninitialized; 1222 return future_state::uninitialized;
1331 bool is_ready() const 1227 bool is_ready() const
1332 { 1228 {
1333 return get_state()==future_state::ready; 1229 return get_state()==future_state::ready;
1334 } 1230 }
1335 1231
1232 bool is_ready(boost::unique_lock<boost::mutex>& lk) const
1233 {
1234 return get_state(lk)==future_state::ready;
1235 }
1336 bool has_exception() const 1236 bool has_exception() const
1337 { 1237 {
1338 return future_ && future_->has_exception(); 1238 return future_ && future_->has_exception();
1339 } 1239 }
1340 1240
1356 : exception_ptr(); 1256 : exception_ptr();
1357 } 1257 }
1358 1258
1359 bool valid() const BOOST_NOEXCEPT 1259 bool valid() const BOOST_NOEXCEPT
1360 { 1260 {
1361 return future_ != 0; 1261 return future_ != 0 && future_->valid();
1362 } 1262 }
1363
1364 1263
1365 void wait() const 1264 void wait() const
1366 { 1265 {
1367 if(!future_) 1266 if(!future_)
1368 { 1267 {
1369 boost::throw_exception(future_uninitialized()); 1268 boost::throw_exception(future_uninitialized());
1370 } 1269 }
1371 future_->wait(false); 1270 future_->wait(false);
1271 }
1272
1273 typedef detail::shared_state_base::notify_when_ready_handle notify_when_ready_handle;
1274
1275 boost::mutex& mutex() {
1276 if(!future_)
1277 {
1278 boost::throw_exception(future_uninitialized());
1279 }
1280 return future_->mutex;
1281 };
1282
1283 notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
1284 {
1285 if(!future_)
1286 {
1287 boost::throw_exception(future_uninitialized());
1288 }
1289 return future_->notify_when_ready(cv);
1290 }
1291
1292 void unnotify_when_ready(notify_when_ready_handle h)
1293 {
1294 if(!future_)
1295 {
1296 boost::throw_exception(future_uninitialized());
1297 }
1298 return future_->unnotify_when_ready(h);
1372 } 1299 }
1373 1300
1374 #if defined BOOST_THREAD_USES_DATETIME 1301 #if defined BOOST_THREAD_USES_DATETIME
1375 template<typename Duration> 1302 template<typename Duration>
1376 bool timed_wait(Duration const& rel_time) const 1303 bool timed_wait(Duration const& rel_time) const
1490 template <class Rp, class Fp> 1417 template <class Rp, class Fp>
1491 friend BOOST_THREAD_FUTURE<Rp> 1418 friend BOOST_THREAD_FUTURE<Rp>
1492 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f); 1419 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1493 1420
1494 1421
1495 typedef typename detail::future_traits<R>::move_dest_type move_dest_type; 1422 typedef typename base_type::move_dest_type move_dest_type;
1423 public: // when_all
1496 1424
1497 BOOST_THREAD_FUTURE(future_ptr a_future): 1425 BOOST_THREAD_FUTURE(future_ptr a_future):
1498 base_type(a_future) 1426 base_type(a_future)
1499 { 1427 {
1500 } 1428 }
1503 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE) 1431 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1504 typedef future_state::state state; 1432 typedef future_state::state state;
1505 typedef R value_type; // EXTENSION 1433 typedef R value_type; // EXTENSION
1506 1434
1507 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {} 1435 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1436 //BOOST_CONSTEXPR
1437 BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1438 base_type(ex) {}
1508 1439
1509 ~BOOST_THREAD_FUTURE() {} 1440 ~BOOST_THREAD_FUTURE() {}
1510 1441
1511 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT: 1442 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1512 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other)))) 1443 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1513 { 1444 {
1514 } 1445 }
1515 inline BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION 1446 inline BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
1516 1447
1448 explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(shared_future<R>) other) :
1449 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1450 {}
1451
1517 BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT 1452 BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
1518 { 1453 {
1519 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other)))); 1454 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1520 return *this; 1455 return *this;
1521 } 1456 }
1538 // todo this function must be private and friendship provided to the internal users. 1473 // todo this function must be private and friendship provided to the internal users.
1539 void set_deferred() 1474 void set_deferred()
1540 { 1475 {
1541 this->future_->set_deferred(); 1476 this->future_->set_deferred();
1542 } 1477 }
1543 1478 bool run_if_is_deferred() {
1479 return this->future_->run_if_is_deferred();
1480 }
1481 bool run_if_is_deferred_or_ready() {
1482 return this->future_->run_if_is_deferred_or_ready();
1483 }
1544 // retrieving the value 1484 // retrieving the value
1545 move_dest_type get() 1485 move_dest_type get()
1546 { 1486 {
1547 if(!this->future_) 1487 if (this->future_ == 0)
1548 { 1488 {
1549 boost::throw_exception(future_uninitialized()); 1489 boost::throw_exception(future_uninitialized());
1550 } 1490 }
1551 future_ptr fut_=this->future_; 1491 unique_lock<boost::mutex> lk(this->future_->mutex);
1492 if (! this->future_->valid(lk))
1493 {
1494 boost::throw_exception(future_uninitialized());
1495 }
1552 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET 1496 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1553 this->future_.reset(); 1497 this->future_->invalidate(lk);
1554 #endif 1498 #endif
1555 return fut_->get(); 1499 return this->future_->get(lk);
1556 } 1500 }
1557 1501
1558 template <typename R2> 1502 template <typename R2>
1559 typename boost::disable_if< is_void<R2>, move_dest_type>::type 1503 typename boost::disable_if< is_void<R2>, move_dest_type>::type
1560 get_or(BOOST_THREAD_RV_REF(R2) v) 1504 get_or(BOOST_THREAD_RV_REF(R2) v)
1561 { 1505 {
1562 if(!this->future_) 1506
1507 if (this->future_ == 0)
1563 { 1508 {
1564 boost::throw_exception(future_uninitialized()); 1509 boost::throw_exception(future_uninitialized());
1565 } 1510 }
1566 this->future_->wait(false); 1511 unique_lock<boost::mutex> lk(this->future_->mutex);
1567 future_ptr fut_=this->future_; 1512 if (! this->future_->valid(lk))
1513 {
1514 boost::throw_exception(future_uninitialized());
1515 }
1516 this->future_->wait(lk, false);
1568 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET 1517 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1569 this->future_.reset(); 1518 this->future_->invalidate(lk);
1570 #endif 1519 #endif
1571 if (fut_->has_value()) { 1520
1572 return fut_->get(); 1521 if (this->future_->has_value(lk)) {
1522 return this->future_->get(lk);
1573 } 1523 }
1574 else { 1524 else {
1575 return boost::move(v); 1525 return boost::move(v);
1576 } 1526 }
1577 } 1527 }
1578 1528
1579 template <typename R2> 1529 template <typename R2>
1580 typename boost::disable_if< is_void<R2>, move_dest_type>::type 1530 typename boost::disable_if< is_void<R2>, move_dest_type>::type
1581 get_or(R2 const& v) // EXTENSION 1531 get_or(R2 const& v) // EXTENSION
1582 { 1532 {
1583 if(!this->future_) 1533 if (this->future_ == 0)
1584 { 1534 {
1585 boost::throw_exception(future_uninitialized()); 1535 boost::throw_exception(future_uninitialized());
1586 } 1536 }
1587 this->future_->wait(false); 1537 unique_lock<boost::mutex> lk(this->future_->mutex);
1588 future_ptr fut_=this->future_; 1538 if (! this->future_->valid(lk))
1539 {
1540 boost::throw_exception(future_uninitialized());
1541 }
1542 this->future_->wait(lk, false);
1589 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET 1543 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1590 this->future_.reset(); 1544 this->future_->invalidate(lk);
1591 #endif 1545 #endif
1592 if (fut_->has_value()) { 1546 if (this->future_->has_value(lk)) {
1593 return fut_->get(); 1547 return this->future_->get(lk);
1594 } 1548 }
1595 else { 1549 else {
1596 return v; 1550 return v;
1597 } 1551 }
1598 } 1552 }
1599 1553
1600
1601 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION 1554 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1602
1603 // template<typename F>
1604 // auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
1605
1606 //#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
1607 // template<typename RF>
1608 // inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(BOOST_THREAD_FUTURE&));
1609 // template<typename RF>
1610 // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
1611 //#endif
1612 template<typename F> 1555 template<typename F>
1613 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type> 1556 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1614 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION 1557 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1615 template<typename F> 1558 template<typename F>
1616 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type> 1559 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1617 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION 1560 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1561 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1562 template<typename Ex, typename F>
1563 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1564 then(Ex& ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1565 #endif
1618 1566
1619 template <typename R2> 1567 template <typename R2>
1620 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type 1568 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1621 fallback_to(BOOST_THREAD_RV_REF(R2) v); // EXTENSION 1569 fallback_to(BOOST_THREAD_RV_REF(R2) v); // EXTENSION
1622 template <typename R2> 1570 template <typename R2>
1623 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type 1571 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1624 fallback_to(R2 const& v); // EXTENSION 1572 fallback_to(R2 const& v); // EXTENSION
1625 1573
1626 #endif 1574 #endif
1627
1628 //#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1629 // inline
1630 // typename boost::enable_if<
1631 // is_future_type<value_type>,
1632 // value_type
1633 // //BOOST_THREAD_FUTURE<typename is_future_type<value_type>::type>
1634 // >::type
1635 // unwrap();
1636 //#endif
1637 1575
1638 }; 1576 };
1639 1577
1640 BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END 1578 BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
1641 1579
1684 1622
1685 template <class Rp, class Fp> 1623 template <class Rp, class Fp>
1686 friend BOOST_THREAD_FUTURE<Rp> 1624 friend BOOST_THREAD_FUTURE<Rp>
1687 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f); 1625 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1688 1626
1689 1627 typedef typename base_type::move_dest_type move_dest_type;
1690 typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
1691 1628
1692 BOOST_THREAD_FUTURE(future_ptr a_future): 1629 BOOST_THREAD_FUTURE(future_ptr a_future):
1693 base_type(a_future) 1630 base_type(a_future)
1694 { 1631 {
1695 } 1632 }
1698 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE) 1635 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1699 typedef future_state::state state; 1636 typedef future_state::state state;
1700 typedef R value_type; // EXTENSION 1637 typedef R value_type; // EXTENSION
1701 1638
1702 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {} 1639 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1640 //BOOST_CONSTEXPR
1641 BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1642 base_type(ex) {}
1703 1643
1704 ~BOOST_THREAD_FUTURE() {} 1644 ~BOOST_THREAD_FUTURE() {}
1705 1645
1706 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT: 1646 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1707 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other)))) 1647 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1732 // todo this function must be private and friendship provided to the internal users. 1672 // todo this function must be private and friendship provided to the internal users.
1733 void set_deferred() 1673 void set_deferred()
1734 { 1674 {
1735 this->future_->set_deferred(); 1675 this->future_->set_deferred();
1736 } 1676 }
1737 1677 bool run_if_is_deferred() {
1678 return this->future_->run_if_is_deferred();
1679 }
1680 bool run_if_is_deferred_or_ready() {
1681 return this->future_->run_if_is_deferred_or_ready();
1682 }
1738 // retrieving the value 1683 // retrieving the value
1739 move_dest_type get() 1684 move_dest_type get()
1740 { 1685 {
1741 if(!this->future_) 1686 if (this->future_ == 0)
1742 { 1687 {
1743 boost::throw_exception(future_uninitialized()); 1688 boost::throw_exception(future_uninitialized());
1744 } 1689 }
1745 future_ptr fut_=this->future_; 1690 unique_lock<boost::mutex> lk(this->future_->mutex);
1746 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET 1691 if (! this->future_->valid(lk))
1747 this->future_.reset();
1748 #endif
1749 return fut_->get();
1750 }
1751 move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
1752 {
1753 if(!this->future_)
1754 { 1692 {
1755 boost::throw_exception(future_uninitialized()); 1693 boost::throw_exception(future_uninitialized());
1756 } 1694 }
1757 this->future_->wait(false);
1758 future_ptr fut_=this->future_;
1759 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET 1695 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1760 this->future_.reset(); 1696 this->future_->invalidate(lk);
1761 #endif 1697 #endif
1762 if (fut_->has_value()) return fut_->get(); 1698 return this->future_->get(lk);
1763 else return boost::move(v); 1699 }
1764 } 1700 move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
1765 1701 {
1766 move_dest_type get_or(R const& v) // EXTENSION 1702 if (this->future_ == 0)
1767 {
1768 if(!this->future_)
1769 { 1703 {
1770 boost::throw_exception(future_uninitialized()); 1704 boost::throw_exception(future_uninitialized());
1771 } 1705 }
1772 this->future_->wait(false); 1706 unique_lock<boost::mutex> lk(this->future_->mutex);
1773 future_ptr fut_=this->future_; 1707 if (! this->future_->valid(lk))
1708 {
1709 boost::throw_exception(future_uninitialized());
1710 }
1711 this->future_->wait(lk, false);
1774 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET 1712 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1775 this->future_.reset(); 1713 this->future_->invalidate(lk);
1776 #endif 1714 #endif
1777 if (fut_->has_value()) return fut_->get(); 1715 if (this->future_->has_value(lk)) return this->future_->get(lk);
1716 else return boost::move(v);
1717 }
1718
1719 move_dest_type get_or(R const& v) // EXTENSION
1720 {
1721 if (this->future_ == 0)
1722 {
1723 boost::throw_exception(future_uninitialized());
1724 }
1725 unique_lock<boost::mutex> lk(this->future_->mutex);
1726 if (! this->future_->valid(lk))
1727 {
1728 boost::throw_exception(future_uninitialized());
1729 }
1730 this->future_->wait(lk, false);
1731 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1732 this->future_->invalidate(lk);
1733 #endif
1734 if (this->future_->has_value(lk)) return this->future_->get(lk);
1778 else return v; 1735 else return v;
1779 } 1736 }
1780 1737
1781 1738
1782 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION 1739 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1783
1784 // template<typename F>
1785 // auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
1786
1787 //#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
1788 // template<typename RF>
1789 // inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(BOOST_THREAD_FUTURE&));
1790 // template<typename RF>
1791 // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
1792 //#endif
1793 template<typename F> 1740 template<typename F>
1794 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type> 1741 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1795 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION 1742 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1796 template<typename F> 1743 template<typename F>
1797 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type> 1744 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1798 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION 1745 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1746 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1747 template<typename Ex, typename F>
1748 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1749 then(Ex &ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1750 #endif
1799 #endif 1751 #endif
1800 1752
1801 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP 1753 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1802 inline 1754 inline
1803 BOOST_THREAD_FUTURE<R2> 1755 BOOST_THREAD_FUTURE<R2>
1807 }; 1759 };
1808 1760
1809 template <typename R> 1761 template <typename R>
1810 class shared_future : public detail::basic_future<R> 1762 class shared_future : public detail::basic_future<R>
1811 { 1763 {
1812
1813 typedef detail::basic_future<R> base_type; 1764 typedef detail::basic_future<R> base_type;
1814 typedef typename base_type::future_ptr future_ptr; 1765 typedef typename base_type::future_ptr future_ptr;
1815 1766
1816 friend class detail::future_waiter; 1767 friend class detail::future_waiter;
1817 friend class promise<R>; 1768 friend class promise<R>;
1838 shared_future(future_ptr a_future): 1789 shared_future(future_ptr a_future):
1839 base_type(a_future) 1790 base_type(a_future)
1840 {} 1791 {}
1841 1792
1842 public: 1793 public:
1843 BOOST_THREAD_MOVABLE(shared_future) 1794 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_future)
1844 typedef R value_type; // EXTENSION 1795 typedef R value_type; // EXTENSION
1845 1796
1846 shared_future(shared_future const& other): 1797 shared_future(shared_future const& other):
1847 base_type(other) 1798 base_type(other.future_)
1848 {} 1799 {}
1849 1800
1850 typedef future_state::state state; 1801 typedef future_state::state state;
1851 1802
1852 BOOST_CONSTEXPR shared_future() 1803 BOOST_CONSTEXPR shared_future()
1853 {} 1804 {}
1854 1805 //BOOST_CONSTEXPR
1806 shared_future(exceptional_ptr const& ex):
1807 base_type(ex) {}
1855 ~shared_future() 1808 ~shared_future()
1856 {} 1809 {}
1857 1810
1858 shared_future& operator=(shared_future const& other) 1811 shared_future& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_future) other)
1859 { 1812 {
1860 shared_future(other).swap(*this); 1813 if (other.future_) {
1814 other.future_->inc();
1815 }
1816 if (this->future_) {
1817 this->future_->dec();
1818 }
1819 this->future_ = other.future_;
1861 return *this; 1820 return *this;
1862 } 1821 }
1822
1863 shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT : 1823 shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
1864 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other)))) 1824 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1865 { 1825 {
1866 BOOST_THREAD_RV(other).future_.reset();
1867 } 1826 }
1868 shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT : 1827 shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT :
1869 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other)))) 1828 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1870 { 1829 {
1871 } 1830 }
1883 1842
1884 void swap(shared_future& other) BOOST_NOEXCEPT 1843 void swap(shared_future& other) BOOST_NOEXCEPT
1885 { 1844 {
1886 static_cast<base_type*>(this)->swap(other); 1845 static_cast<base_type*>(this)->swap(other);
1887 } 1846 }
1888 1847 bool run_if_is_deferred() {
1848 return this->future_->run_if_is_deferred();
1849 }
1850 bool run_if_is_deferred_or_ready() {
1851 return this->future_->run_if_is_deferred_or_ready();
1852 }
1889 // retrieving the value 1853 // retrieving the value
1890 typename detail::shared_state<R>::shared_future_get_result_type get() 1854 typename detail::shared_state<R>::shared_future_get_result_type get() const
1891 { 1855 {
1892 if(!this->future_) 1856 if(!this->future_)
1893 { 1857 {
1894 boost::throw_exception(future_uninitialized()); 1858 boost::throw_exception(future_uninitialized());
1895 } 1859 }
1896
1897 return this->future_->get_sh(); 1860 return this->future_->get_sh();
1898 } 1861 }
1899 1862
1900 template <typename R2> 1863 template <typename R2>
1901 typename boost::disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type 1864 typename boost::disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type
1902 get_or(BOOST_THREAD_RV_REF(R2) v) // EXTENSION 1865 get_or(BOOST_THREAD_RV_REF(R2) v) const // EXTENSION
1903 { 1866 {
1904 if(!this->future_) 1867 if(!this->future_)
1905 { 1868 {
1906 boost::throw_exception(future_uninitialized()); 1869 boost::throw_exception(future_uninitialized());
1907 } 1870 }
1908 future_ptr fut_=this->future_; 1871 this->future_->wait();
1909 fut_->wait(); 1872 if (this->future_->has_value()) return this->future_->get_sh();
1910 if (fut_->has_value()) return fut_->get_sh();
1911 else return boost::move(v); 1873 else return boost::move(v);
1912 } 1874 }
1913 1875
1914 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION 1876 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1915
1916 // template<typename F>
1917 // auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
1918 // template<typename F>
1919 // auto then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
1920
1921 //#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
1922 // template<typename RF>
1923 // inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(shared_future&));
1924 // template<typename RF>
1925 // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(shared_future&));
1926 //#endif
1927 template<typename F> 1877 template<typename F>
1928 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type> 1878 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
1929 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION 1879 then(BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
1930 template<typename F> 1880 template<typename F>
1931 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type> 1881 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
1932 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION 1882 then(launch policy, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
1933 #endif 1883 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1934 //#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP 1884 template<typename Ex, typename F>
1935 // inline 1885 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
1936 // typename boost::enable_if_c< 1886 then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
1937 // is_future_type<value_type>::value, 1887 #endif
1938 // BOOST_THREAD_FUTURE<typename is_future_type<value_type>::type> 1888 #endif
1939 // >::type
1940 // unwrap();
1941 //#endif
1942 1889
1943 }; 1890 };
1944 1891
1945 BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END 1892 BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
1946
1947 namespace detail
1948 {
1949 /// Copy construction from a shared_future
1950 template <typename R>
1951 inline basic_future<R>::basic_future(const shared_future<R>& other) BOOST_NOEXCEPT
1952 : future_(other.future_)
1953 {
1954 }
1955 }
1956 1893
1957 template <typename R> 1894 template <typename R>
1958 class promise 1895 class promise
1959 { 1896 {
1960 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr; 1897 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
1898
1899 typedef typename detail::shared_state<R>::source_reference_type source_reference_type;
1900 typedef typename detail::shared_state<R>::rvalue_source_type rvalue_source_type;
1901 typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
1902 typedef typename detail::shared_state<R>::shared_future_get_result_type shared_future_get_result_type;
1961 1903
1962 future_ptr future_; 1904 future_ptr future_;
1963 bool future_obtained; 1905 bool future_obtained;
1964 1906
1965 void lazy_init() 1907 void lazy_init()
2047 } 1989 }
2048 future_obtained=true; 1990 future_obtained=true;
2049 return BOOST_THREAD_FUTURE<R>(future_); 1991 return BOOST_THREAD_FUTURE<R>(future_);
2050 } 1992 }
2051 1993
2052 void set_value(typename detail::future_traits<R>::source_reference_type r) 1994 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
1995 template <class TR>
1996 typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type set_value(TR const & r)
2053 { 1997 {
2054 lazy_init(); 1998 lazy_init();
2055 boost::unique_lock<boost::mutex> lock(future_->mutex); 1999 boost::unique_lock<boost::mutex> lock(future_->mutex);
2056 if(future_->done) 2000 if(future_->done)
2057 { 2001 {
2058 boost::throw_exception(promise_already_satisfied()); 2002 boost::throw_exception(promise_already_satisfied());
2059 } 2003 }
2060 future_->mark_finished_with_result_internal(r, lock); 2004 future_->mark_finished_with_result_internal(r, lock);
2061 } 2005 }
2062 2006 #else
2063 // void set_value(R && r); 2007 void set_value(source_reference_type r)
2064 void set_value(typename detail::future_traits<R>::rvalue_source_type r)
2065 { 2008 {
2066 lazy_init(); 2009 lazy_init();
2067 boost::unique_lock<boost::mutex> lock(future_->mutex); 2010 boost::unique_lock<boost::mutex> lock(future_->mutex);
2068 if(future_->done) 2011 if(future_->done)
2069 { 2012 {
2070 boost::throw_exception(promise_already_satisfied()); 2013 boost::throw_exception(promise_already_satisfied());
2071 } 2014 }
2072 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 2015 future_->mark_finished_with_result_internal(r, lock);
2073 future_->mark_finished_with_result_internal(boost::forward<R>(r), lock); 2016 }
2074 #else 2017 #endif
2075 future_->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r), lock); 2018
2076 #endif 2019 void set_value(rvalue_source_type r)
2077 }
2078
2079 void set_exception(boost::exception_ptr p)
2080 { 2020 {
2081 lazy_init(); 2021 lazy_init();
2082 boost::unique_lock<boost::mutex> lock(future_->mutex); 2022 boost::unique_lock<boost::mutex> lock(future_->mutex);
2083 if(future_->done) 2023 if(future_->done)
2084 { 2024 {
2085 boost::throw_exception(promise_already_satisfied()); 2025 boost::throw_exception(promise_already_satisfied());
2086 } 2026 }
2027 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
2028 future_->mark_finished_with_result_internal(boost::move(r), lock);
2029 #else
2030 future_->mark_finished_with_result_internal(static_cast<rvalue_source_type>(r), lock);
2031 #endif
2032 }
2033
2034 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
2035 template <class ...Args>
2036 void emplace(BOOST_THREAD_FWD_REF(Args) ...args)
2037 {
2038 lazy_init();
2039 boost::unique_lock<boost::mutex> lock(future_->mutex);
2040 if(future_->done)
2041 {
2042 boost::throw_exception(promise_already_satisfied());
2043 }
2044 future_->mark_finished_with_result_internal(lock, boost::forward<Args>(args)...);
2045 }
2046
2047 #endif
2048
2049 void set_exception(boost::exception_ptr p)
2050 {
2051 lazy_init();
2052 boost::unique_lock<boost::mutex> lock(future_->mutex);
2053 if(future_->done)
2054 {
2055 boost::throw_exception(promise_already_satisfied());
2056 }
2087 future_->mark_exceptional_finish_internal(p, lock); 2057 future_->mark_exceptional_finish_internal(p, lock);
2088 } 2058 }
2089 template <typename E> 2059 template <typename E>
2090 void set_exception(E ex) 2060 void set_exception(E ex)
2091 { 2061 {
2092 set_exception(copy_exception(ex)); 2062 set_exception(boost::copy_exception(ex));
2093 } 2063 }
2094 // setting the result with deferred notification 2064 // setting the result with deferred notification
2095 void set_value_at_thread_exit(const R& r) 2065 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
2066 template <class TR>
2067 typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type set_value_at_thread_exit(TR const& r)
2096 { 2068 {
2097 if (future_.get()==0) 2069 if (future_.get()==0)
2098 { 2070 {
2099 boost::throw_exception(promise_moved()); 2071 boost::throw_exception(promise_moved());
2100 } 2072 }
2101 future_->set_value_at_thread_exit(r); 2073 future_->set_value_at_thread_exit(r);
2102 } 2074 }
2103 2075 #else
2076 void set_value_at_thread_exit(source_reference_type r)
2077 {
2078 if (future_.get()==0)
2079 {
2080 boost::throw_exception(promise_moved());
2081 }
2082 future_->set_value_at_thread_exit(r);
2083 }
2084 #endif
2104 void set_value_at_thread_exit(BOOST_THREAD_RV_REF(R) r) 2085 void set_value_at_thread_exit(BOOST_THREAD_RV_REF(R) r)
2105 { 2086 {
2106 if (future_.get()==0) 2087 if (future_.get()==0)
2107 { 2088 {
2108 boost::throw_exception(promise_moved()); 2089 boost::throw_exception(promise_moved());
2118 future_->set_exception_at_thread_exit(e); 2099 future_->set_exception_at_thread_exit(e);
2119 } 2100 }
2120 template <typename E> 2101 template <typename E>
2121 void set_exception_at_thread_exit(E ex) 2102 void set_exception_at_thread_exit(E ex)
2122 { 2103 {
2123 set_exception_at_thread_exit(copy_exception(ex)); 2104 set_exception_at_thread_exit(boost::copy_exception(ex));
2124 } 2105 }
2125 2106
2126 template<typename F> 2107 template<typename F>
2127 void set_wait_callback(F f) 2108 void set_wait_callback(F f)
2128 { 2109 {
2249 future_->mark_exceptional_finish_internal(p, lock); 2230 future_->mark_exceptional_finish_internal(p, lock);
2250 } 2231 }
2251 template <typename E> 2232 template <typename E>
2252 void set_exception(E ex) 2233 void set_exception(E ex)
2253 { 2234 {
2254 set_exception(copy_exception(ex)); 2235 set_exception(boost::copy_exception(ex));
2255 } 2236 }
2256 2237
2257 // setting the result with deferred notification 2238 // setting the result with deferred notification
2258 void set_value_at_thread_exit(R& r) 2239 void set_value_at_thread_exit(R& r)
2259 { 2240 {
2273 future_->set_exception_at_thread_exit(e); 2254 future_->set_exception_at_thread_exit(e);
2274 } 2255 }
2275 template <typename E> 2256 template <typename E>
2276 void set_exception_at_thread_exit(E ex) 2257 void set_exception_at_thread_exit(E ex)
2277 { 2258 {
2278 set_exception_at_thread_exit(copy_exception(ex)); 2259 set_exception_at_thread_exit(boost::copy_exception(ex));
2279 } 2260 }
2280 2261
2281 template<typename F> 2262 template<typename F>
2282 void set_wait_callback(F f) 2263 void set_wait_callback(F f)
2283 { 2264 {
2284 lazy_init(); 2265 lazy_init();
2285 future_->set_wait_callback(f,this); 2266 future_->set_wait_callback(f,this);
2286 } 2267 }
2287
2288 }; 2268 };
2269
2289 template <> 2270 template <>
2290 class promise<void> 2271 class promise<void>
2291 { 2272 {
2292 typedef boost::shared_ptr<detail::shared_state<void> > future_ptr; 2273 typedef boost::shared_ptr<detail::shared_state<void> > future_ptr;
2293 2274
2377 if(future_obtained) 2358 if(future_obtained)
2378 { 2359 {
2379 boost::throw_exception(future_already_retrieved()); 2360 boost::throw_exception(future_already_retrieved());
2380 } 2361 }
2381 future_obtained=true; 2362 future_obtained=true;
2363 //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<void>(future_));
2382 return BOOST_THREAD_FUTURE<void>(future_); 2364 return BOOST_THREAD_FUTURE<void>(future_);
2383 } 2365 }
2384 2366
2385 void set_value() 2367 void set_value()
2386 { 2368 {
2404 future_->mark_exceptional_finish_internal(p,lock); 2386 future_->mark_exceptional_finish_internal(p,lock);
2405 } 2387 }
2406 template <typename E> 2388 template <typename E>
2407 void set_exception(E ex) 2389 void set_exception(E ex)
2408 { 2390 {
2409 set_exception(copy_exception(ex)); 2391 set_exception(boost::copy_exception(ex));
2410 } 2392 }
2411 2393
2412 // setting the result with deferred notification 2394 // setting the result with deferred notification
2413 void set_value_at_thread_exit() 2395 void set_value_at_thread_exit()
2414 { 2396 {
2428 future_->set_exception_at_thread_exit(e); 2410 future_->set_exception_at_thread_exit(e);
2429 } 2411 }
2430 template <typename E> 2412 template <typename E>
2431 void set_exception_at_thread_exit(E ex) 2413 void set_exception_at_thread_exit(E ex)
2432 { 2414 {
2433 set_exception_at_thread_exit(copy_exception(ex)); 2415 set_exception_at_thread_exit(boost::copy_exception(ex));
2434 } 2416 }
2435 2417
2436 template<typename F> 2418 template<typename F>
2437 void set_wait_callback(F f) 2419 void set_wait_callback(F f)
2438 { 2420 {
2439 lazy_init(); 2421 lazy_init();
2440 future_->set_wait_callback(f,this); 2422 future_->set_wait_callback(f,this);
2441 } 2423 }
2442 2424
2443 }; 2425 };
2444 2426 }
2445 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS 2427 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2446 namespace container 2428 namespace boost { namespace container {
2429 template <class R, class Alloc>
2430 struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2447 { 2431 {
2448 template <class R, class Alloc> 2432 };
2449 struct uses_allocator<promise<R> , Alloc> : true_type 2433 }}
2450 { 2434 #if ! defined BOOST_NO_CXX11_ALLOCATOR
2451 }; 2435 namespace std {
2452 } 2436 template <class R, class Alloc>
2453 #endif 2437 struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2438 {
2439 };
2440 }
2441 #endif
2442 #endif
2443
2444 namespace boost
2445 {
2454 2446
2455 BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END 2447 BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
2456 2448
2457 namespace detail 2449 namespace detail
2458 { 2450 {
2478 started(false) 2470 started(false)
2479 {} 2471 {}
2480 2472
2481 void reset() 2473 void reset()
2482 { 2474 {
2475 // todo The packaged_task::reset must be as if an assignemnt froma new packaged_task with the same function
2476 // the reset function is an optimization that avoids reallocating a new task.
2483 started=false; 2477 started=false;
2478 this->validate();
2484 } 2479 }
2485 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2480 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2486 virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0; 2481 virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
2487 void run(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2482 void run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2488 #else 2483 #else
2497 boost::throw_exception(task_already_started()); 2492 boost::throw_exception(task_already_started());
2498 } 2493 }
2499 started=true; 2494 started=true;
2500 } 2495 }
2501 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2496 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2502 do_run(boost::forward<ArgTypes>(args)...); 2497 do_run(boost::move(args)...);
2503 #else 2498 #else
2504 do_run(); 2499 do_run();
2505 #endif 2500 #endif
2506 } 2501 }
2507 2502
2520 boost::throw_exception(task_already_started()); 2515 boost::throw_exception(task_already_started());
2521 } 2516 }
2522 started=true; 2517 started=true;
2523 } 2518 }
2524 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2519 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2525 do_apply(boost::forward<ArgTypes>(args)...); 2520 do_apply(boost::move(args)...);
2526 #else 2521 #else
2527 do_apply(); 2522 do_apply();
2528 #endif 2523 #endif
2529 } 2524 }
2530 2525
2535 { 2530 {
2536 started=true; 2531 started=true;
2537 this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk); 2532 this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk);
2538 } 2533 }
2539 } 2534 }
2540
2541 }; 2535 };
2542 2536
2543 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK 2537 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2544 template<typename F, typename R> 2538 template<typename F, typename R>
2545 struct task_shared_state; 2539 struct task_shared_state;
2567 {} 2561 {}
2568 task_shared_state(BOOST_THREAD_RV_REF(F) f_): 2562 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
2569 f(boost::move(f_)) 2563 f(boost::move(f_))
2570 {} 2564 {}
2571 2565
2566 F callable()
2567 {
2568 return boost::move(f);
2569 }
2570
2572 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2571 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2573 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2572 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2574 { 2573 {
2575 try 2574 try
2576 { 2575 {
2577 this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...)); 2576 this->set_value_at_thread_exit(f(boost::move(args)...));
2578 } 2577 }
2579 #else 2578 #else
2580 void do_apply() 2579 void do_apply()
2581 { 2580 {
2582 try 2581 try
2583 { 2582 {
2584 this->set_value_at_thread_exit(f()); 2583 this->set_value_at_thread_exit(f());
2585 } 2584 }
2586 #endif 2585 #endif
2587 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2588 catch(thread_interrupted& )
2589 {
2590 this->set_interrupted_at_thread_exit();
2591 }
2592 #endif
2593 catch(...) 2586 catch(...)
2594 { 2587 {
2595 this->set_exception_at_thread_exit(current_exception()); 2588 this->set_exception_at_thread_exit(current_exception());
2596 } 2589 }
2597 } 2590 }
2599 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2592 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2600 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2593 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2601 { 2594 {
2602 try 2595 try
2603 { 2596 {
2604 this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...)); 2597 this->mark_finished_with_result(f(boost::move(args)...));
2605 } 2598 }
2606 #else 2599 #else
2607 void do_run() 2600 void do_run()
2608 { 2601 {
2609 try 2602 try
2613 this->mark_finished_with_result(boost::move(res)); 2606 this->mark_finished_with_result(boost::move(res));
2614 #else 2607 #else
2615 this->mark_finished_with_result(f()); 2608 this->mark_finished_with_result(f());
2616 #endif 2609 #endif
2617 } 2610 }
2618 #endif
2619 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2620 catch(thread_interrupted& )
2621 {
2622 this->mark_interrupted_finish();
2623 }
2624 #endif 2611 #endif
2625 catch(...) 2612 catch(...)
2626 { 2613 {
2627 this->mark_exceptional_finish(); 2614 this->mark_exceptional_finish();
2628 } 2615 }
2654 {} 2641 {}
2655 task_shared_state(BOOST_THREAD_RV_REF(F) f_): 2642 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
2656 f(boost::move(f_)) 2643 f(boost::move(f_))
2657 {} 2644 {}
2658 2645
2646 F callable()
2647 {
2648 return f;
2649 }
2650
2659 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2651 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2660 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2652 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2661 { 2653 {
2662 try 2654 try
2663 { 2655 {
2664 this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...)); 2656 this->set_value_at_thread_exit(f(boost::move(args)...));
2665 } 2657 }
2666 #else 2658 #else
2667 void do_apply() 2659 void do_apply()
2668 { 2660 {
2669 try 2661 try
2670 { 2662 {
2671 this->set_value_at_thread_exit(f()); 2663 this->set_value_at_thread_exit(f());
2672 } 2664 }
2673 #endif 2665 #endif
2674 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2675 catch(thread_interrupted& )
2676 {
2677 this->set_interrupted_at_thread_exit();
2678 }
2679 #endif
2680 catch(...) 2666 catch(...)
2681 { 2667 {
2682 this->set_exception_at_thread_exit(current_exception()); 2668 this->set_exception_at_thread_exit(current_exception());
2683 } 2669 }
2684 } 2670 }
2686 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2672 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2687 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2673 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2688 { 2674 {
2689 try 2675 try
2690 { 2676 {
2691 this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...)); 2677 this->mark_finished_with_result(f(boost::move(args)...));
2692 } 2678 }
2693 #else 2679 #else
2694 void do_run() 2680 void do_run()
2695 { 2681 {
2696 try 2682 try
2697 { 2683 {
2698 R& res((f())); 2684 R& res((f()));
2699 this->mark_finished_with_result(res); 2685 this->mark_finished_with_result(res);
2700 }
2701 #endif
2702 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2703 catch(thread_interrupted& )
2704 {
2705 this->mark_interrupted_finish();
2706 } 2686 }
2707 #endif 2687 #endif
2708 catch(...) 2688 catch(...)
2709 { 2689 {
2710 this->mark_exceptional_finish(); 2690 this->mark_exceptional_finish();
2730 task_base_shared_state<R> 2710 task_base_shared_state<R>
2731 #endif 2711 #endif
2732 { 2712 {
2733 private: 2713 private:
2734 task_shared_state(task_shared_state&); 2714 task_shared_state(task_shared_state&);
2715 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2716 typedef R (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes) ... );
2717 #else
2718 typedef R (*CallableType)();
2719 #endif
2735 public: 2720 public:
2736 R (*f)(); 2721 CallableType f;
2737 task_shared_state(R (*f_)()): 2722 task_shared_state(CallableType f_):
2738 f(f_) 2723 f(f_)
2739 {} 2724 {}
2740 2725
2726 CallableType callable()
2727 {
2728 return f;
2729 }
2741 2730
2742 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2731 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2743 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2732 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2744 { 2733 {
2745 try 2734 try
2746 { 2735 {
2747 this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...)); 2736 this->set_value_at_thread_exit(f(boost::move(args)...));
2748 } 2737 }
2749 #else 2738 #else
2750 void do_apply() 2739 void do_apply()
2751 { 2740 {
2752 try 2741 try
2753 { 2742 {
2754 R r((f())); 2743 R r((f()));
2755 this->set_value_at_thread_exit(boost::move(r)); 2744 this->set_value_at_thread_exit(boost::move(r));
2756 } 2745 }
2757 #endif 2746 #endif
2758 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2759 catch(thread_interrupted& )
2760 {
2761 this->set_interrupted_at_thread_exit();
2762 }
2763 #endif
2764 catch(...) 2747 catch(...)
2765 { 2748 {
2766 this->set_exception_at_thread_exit(current_exception()); 2749 this->set_exception_at_thread_exit(current_exception());
2767 } 2750 }
2768 } 2751 }
2771 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2754 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2772 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2755 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2773 { 2756 {
2774 try 2757 try
2775 { 2758 {
2776 this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...)); 2759 this->mark_finished_with_result(f(boost::move(args)...));
2777 } 2760 }
2778 #else 2761 #else
2779 void do_run() 2762 void do_run()
2780 { 2763 {
2781 try 2764 try
2782 { 2765 {
2783 R res((f())); 2766 R res((f()));
2784 this->mark_finished_with_result(boost::move(res)); 2767 this->mark_finished_with_result(boost::move(res));
2785 }
2786 #endif
2787 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2788 catch(thread_interrupted& )
2789 {
2790 this->mark_interrupted_finish();
2791 } 2768 }
2792 #endif 2769 #endif
2793 catch(...) 2770 catch(...)
2794 { 2771 {
2795 this->mark_exceptional_finish(); 2772 this->mark_exceptional_finish();
2813 #endif 2790 #endif
2814 { 2791 {
2815 private: 2792 private:
2816 task_shared_state(task_shared_state&); 2793 task_shared_state(task_shared_state&);
2817 public: 2794 public:
2818 R& (*f)(); 2795 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2819 task_shared_state(R& (*f_)()): 2796 typedef R& (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes) ... );
2797 #else
2798 typedef R& (*CallableType)();
2799 #endif
2800 CallableType f;
2801 task_shared_state(CallableType f_):
2820 f(f_) 2802 f(f_)
2821 {} 2803 {}
2822 2804
2805 CallableType callable()
2806 {
2807 return boost::move(f);
2808 }
2823 2809
2824 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2810 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2825 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2811 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2826 { 2812 {
2827 try 2813 try
2828 { 2814 {
2829 this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...)); 2815 this->set_value_at_thread_exit(f(boost::move(args)...));
2830 } 2816 }
2831 #else 2817 #else
2832 void do_apply() 2818 void do_apply()
2833 { 2819 {
2834 try 2820 try
2835 { 2821 {
2836 this->set_value_at_thread_exit(f()); 2822 this->set_value_at_thread_exit(f());
2837 }
2838 #endif
2839 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2840 catch(thread_interrupted& )
2841 {
2842 this->set_interrupted_at_thread_exit();
2843 } 2823 }
2844 #endif 2824 #endif
2845 catch(...) 2825 catch(...)
2846 { 2826 {
2847 this->set_exception_at_thread_exit(current_exception()); 2827 this->set_exception_at_thread_exit(current_exception());
2852 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2832 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2853 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2833 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2854 { 2834 {
2855 try 2835 try
2856 { 2836 {
2857 this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...)); 2837 this->mark_finished_with_result(f(boost::move(args)...));
2858 } 2838 }
2859 #else 2839 #else
2860 void do_run() 2840 void do_run()
2861 { 2841 {
2862 try 2842 try
2863 { 2843 {
2864 this->mark_finished_with_result(f()); 2844 this->mark_finished_with_result(f());
2865 }
2866 #endif
2867 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2868 catch(thread_interrupted& )
2869 {
2870 this->mark_interrupted_finish();
2871 } 2845 }
2872 #endif 2846 #endif
2873 catch(...) 2847 catch(...)
2874 { 2848 {
2875 this->mark_exceptional_finish(); 2849 this->mark_exceptional_finish();
2894 #endif 2868 #endif
2895 { 2869 {
2896 private: 2870 private:
2897 task_shared_state(task_shared_state&); 2871 task_shared_state(task_shared_state&);
2898 public: 2872 public:
2873 typedef F CallableType;
2899 F f; 2874 F f;
2900 task_shared_state(F const& f_): 2875 task_shared_state(F const& f_):
2901 f(f_) 2876 f(f_)
2902 {} 2877 {}
2903 task_shared_state(BOOST_THREAD_RV_REF(F) f_): 2878 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
2904 f(boost::move(f_)) 2879 f(boost::move(f_))
2905 {} 2880 {}
2906 2881 F callable()
2882 {
2883 return boost::move(f);
2884 }
2907 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2885 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2908 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2886 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2909 { 2887 {
2910 try 2888 try
2911 { 2889 {
2912 f(boost::forward<ArgTypes>(args)...); 2890 f(boost::move(args)...);
2913 #else 2891 #else
2914 void do_apply() 2892 void do_apply()
2915 { 2893 {
2916 try 2894 try
2917 { 2895 {
2918 f(); 2896 f();
2919 #endif 2897 #endif
2920 this->set_value_at_thread_exit(); 2898 this->set_value_at_thread_exit();
2921 } 2899 }
2922 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2923 catch(thread_interrupted& )
2924 {
2925 this->set_interrupted_at_thread_exit();
2926 }
2927 #endif
2928 catch(...) 2900 catch(...)
2929 { 2901 {
2930 this->set_exception_at_thread_exit(current_exception()); 2902 this->set_exception_at_thread_exit(current_exception());
2931 } 2903 }
2932 } 2904 }
2934 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2906 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2935 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2907 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2936 { 2908 {
2937 try 2909 try
2938 { 2910 {
2939 f(boost::forward<ArgTypes>(args)...); 2911 f(boost::move(args)...);
2940 #else 2912 #else
2941 void do_run() 2913 void do_run()
2942 { 2914 {
2943 try 2915 try
2944 { 2916 {
2945 f(); 2917 f();
2946 #endif 2918 #endif
2947 this->mark_finished_with_result(); 2919 this->mark_finished_with_result();
2948 } 2920 }
2949 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2950 catch(thread_interrupted& )
2951 {
2952 this->mark_interrupted_finish();
2953 }
2954 #endif
2955 catch(...) 2921 catch(...)
2956 { 2922 {
2957 this->mark_exceptional_finish(); 2923 this->mark_exceptional_finish();
2958 } 2924 }
2959 } 2925 }
2975 task_base_shared_state<void> 2941 task_base_shared_state<void>
2976 #endif 2942 #endif
2977 { 2943 {
2978 private: 2944 private:
2979 task_shared_state(task_shared_state&); 2945 task_shared_state(task_shared_state&);
2946 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2947 typedef void (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes)...);
2948 #else
2949 typedef void (*CallableType)();
2950 #endif
2980 public: 2951 public:
2981 void (*f)(); 2952 CallableType f;
2982 task_shared_state(void (*f_)()): 2953 task_shared_state(CallableType f_):
2983 f(f_) 2954 f(f_)
2984 {} 2955 {}
2985 2956 CallableType callable()
2957 {
2958 return f;
2959 }
2986 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2960 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2987 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2961 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2988 { 2962 {
2989 try 2963 try
2990 { 2964 {
2991 f(boost::forward<ArgTypes>(args)...); 2965 f(boost::move(args)...);
2992 #else 2966 #else
2993 void do_apply() 2967 void do_apply()
2994 { 2968 {
2995 try 2969 try
2996 { 2970 {
2997 f(); 2971 f();
2998 #endif 2972 #endif
2999 this->set_value_at_thread_exit(); 2973 this->set_value_at_thread_exit();
3000 } 2974 }
3001 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3002 catch(thread_interrupted& )
3003 {
3004 this->set_interrupted_at_thread_exit();
3005 }
3006 #endif
3007 catch(...) 2975 catch(...)
3008 { 2976 {
3009 this->set_exception_at_thread_exit(current_exception()); 2977 this->set_exception_at_thread_exit(current_exception());
3010 } 2978 }
3011 } 2979 }
3013 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 2981 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3014 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args) 2982 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3015 { 2983 {
3016 try 2984 try
3017 { 2985 {
3018 f(boost::forward<ArgTypes>(args)...); 2986 f(boost::move(args)...);
3019 #else 2987 #else
3020 void do_run() 2988 void do_run()
3021 { 2989 {
3022 try 2990 try
3023 { 2991 {
3024 f(); 2992 f();
3025 #endif 2993 #endif
3026 this->mark_finished_with_result(); 2994 this->mark_finished_with_result();
3027 } 2995 }
3028 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3029 catch(thread_interrupted& )
3030 {
3031 this->mark_interrupted_finish();
3032 }
3033 #endif
3034 catch(...) 2996 catch(...)
3035 { 2997 {
3036 this->mark_exceptional_finish(); 2998 this->mark_exceptional_finish();
3037 } 2999 }
3038 } 3000 }
3078 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3040 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3079 explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args) 3041 explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args)
3080 { 3042 {
3081 typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...); 3043 typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3082 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type; 3044 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3083 task= task_ptr(new task_shared_state_type(f, boost::forward<ArgTypes>(args)...)); 3045 task= task_ptr(new task_shared_state_type(f, boost::move(args)...));
3084 future_obtained=false; 3046 future_obtained=false;
3085 } 3047 }
3086 #else 3048 #else
3087 explicit packaged_task(R(*f)()) 3049 explicit packaged_task(R(*f)())
3088 { 3050 {
3106 template <class F> 3068 template <class F>
3107 explicit packaged_task(BOOST_THREAD_FWD_REF(F) f 3069 explicit packaged_task(BOOST_THREAD_FWD_REF(F) f
3108 , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0 3070 , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3109 ) 3071 )
3110 { 3072 {
3111 typedef typename remove_cv<typename remove_reference<F>::type>::type FR; 3073 typedef typename decay<F>::type FR;
3112 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK 3074 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3113 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3075 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3114 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type; 3076 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3115 #else 3077 #else
3116 typedef detail::task_shared_state<FR,R()> task_shared_state_type; 3078 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3145 explicit packaged_task(BOOST_THREAD_RV_REF(F) f) 3107 explicit packaged_task(BOOST_THREAD_RV_REF(F) f)
3146 { 3108 {
3147 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK 3109 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3148 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3110 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3149 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type; 3111 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3150 task = task_ptr(new task_shared_state_type(boost::forward<F>(f))); 3112 task = task_ptr(new task_shared_state_type(boost::move(f)));
3151 #else 3113 #else
3152 typedef detail::task_shared_state<F,R()> task_shared_state_type; 3114 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3153 task = task_ptr(new task_shared_state_type(boost::move(f))); // TODO forward 3115 task = task_ptr(new task_shared_state_type(boost::move(f)));
3154 #endif 3116 #endif
3155 #else 3117 #else
3156 typedef detail::task_shared_state<F,R> task_shared_state_type; 3118 typedef detail::task_shared_state<F,R> task_shared_state_type;
3157 task = task_ptr(new task_shared_state_type(boost::forward<F>(f))); 3119 task = task_ptr(new task_shared_state_type(boost::move(f)));
3158 #endif 3120 #endif
3159 future_obtained=false; 3121 future_obtained=false;
3160 3122
3161 } 3123 }
3162 #endif 3124 #endif
3187 3149
3188 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 3150 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3189 template <class F, class Allocator> 3151 template <class F, class Allocator>
3190 packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f) 3152 packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
3191 { 3153 {
3192 typedef typename remove_cv<typename remove_reference<F>::type>::type FR; 3154 typedef typename decay<F>::type FR;
3155
3193 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK 3156 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3194 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3157 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3195 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type; 3158 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3196 #else 3159 #else
3197 typedef detail::task_shared_state<FR,R()> task_shared_state_type; 3160 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3240 #endif 3203 #endif
3241 typedef typename Allocator::template rebind<task_shared_state_type>::other A2; 3204 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3242 A2 a2(a); 3205 A2 a2(a);
3243 typedef thread_detail::allocator_destructor<A2> D; 3206 typedef thread_detail::allocator_destructor<A2> D;
3244 3207
3245 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3208 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) );
3246 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
3247 #else
3248 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) ); // TODO forward
3249 #endif
3250 future_obtained = false; 3209 future_obtained = false;
3251 } 3210 }
3252 3211
3253 #endif //BOOST_NO_CXX11_RVALUE_REFERENCES 3212 #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
3254 #endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS 3213 #endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3255 3214
3256 ~packaged_task() 3215 ~packaged_task() {
3257 { 3216 if(task) {
3258 if(task)
3259 {
3260 task->owner_destroyed(); 3217 task->owner_destroyed();
3261 } 3218 }
3262 } 3219 }
3263 3220
3264 // assignment 3221 // assignment
3265 packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT : 3222 packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
3266 future_obtained(BOOST_THREAD_RV(other).future_obtained) 3223 : future_obtained(BOOST_THREAD_RV(other).future_obtained) {
3267 {
3268 task.swap(BOOST_THREAD_RV(other).task); 3224 task.swap(BOOST_THREAD_RV(other).task);
3269 BOOST_THREAD_RV(other).future_obtained=false; 3225 BOOST_THREAD_RV(other).future_obtained=false;
3270 } 3226 }
3271 packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT 3227 packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT {
3272 { 3228
3273
3274 // todo use forward
3275 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 3229 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3276 packaged_task temp(boost::move(other)); 3230 packaged_task temp(boost::move(other));
3277 #else 3231 #else
3278 packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other)); 3232 packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
3279 #endif 3233 #endif
3280 swap(temp); 3234 swap(temp);
3281 return *this; 3235 return *this;
3282 } 3236 }
3283 3237
3284 void reset() 3238 void reset() {
3285 {
3286 if (!valid()) 3239 if (!valid())
3287 throw future_error(system::make_error_code(future_errc::no_state)); 3240 throw future_error(system::make_error_code(future_errc::no_state));
3241
3242 // As if *this = packaged_task(task->callable());
3243
3288 task->reset(); 3244 task->reset();
3289 future_obtained=false; 3245 future_obtained=false;
3290 } 3246 }
3291 3247
3292 void swap(packaged_task& other) BOOST_NOEXCEPT 3248 void swap(packaged_task& other) BOOST_NOEXCEPT {
3293 {
3294 task.swap(other.task); 3249 task.swap(other.task);
3295 std::swap(future_obtained,other.future_obtained); 3250 std::swap(future_obtained,other.future_obtained);
3296 } 3251 }
3297 bool valid() const BOOST_NOEXCEPT 3252 bool valid() const BOOST_NOEXCEPT {
3298 {
3299 return task.get()!=0; 3253 return task.get()!=0;
3300 } 3254 }
3301 3255
3302 // result retrieval 3256 // result retrieval
3303 BOOST_THREAD_FUTURE<R> get_future() 3257 BOOST_THREAD_FUTURE<R> get_future() {
3304 { 3258 if(!task) {
3305 if(!task)
3306 {
3307 boost::throw_exception(task_moved()); 3259 boost::throw_exception(task_moved());
3308 } 3260 } else if(!future_obtained) {
3309 else if(!future_obtained)
3310 {
3311 future_obtained=true; 3261 future_obtained=true;
3312 return BOOST_THREAD_FUTURE<R>(task); 3262 return BOOST_THREAD_FUTURE<R>(task);
3313 } 3263 } else {
3314 else
3315 {
3316 boost::throw_exception(future_already_retrieved()); 3264 boost::throw_exception(future_already_retrieved());
3317 } 3265 }
3318 //return BOOST_THREAD_FUTURE<R>();
3319 } 3266 }
3320 3267
3321 // execution 3268 // execution
3322 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3269 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3323 void operator()(BOOST_THREAD_RV_REF(ArgTypes)... args) 3270 void operator()(BOOST_THREAD_RV_REF(ArgTypes)... args) {
3324 { 3271 if(!task) {
3325 if(!task)
3326 {
3327 boost::throw_exception(task_moved()); 3272 boost::throw_exception(task_moved());
3328 } 3273 }
3329 task->run(boost::forward<ArgTypes>(args)...); 3274 task->run(boost::move(args)...);
3330 } 3275 }
3331 void make_ready_at_thread_exit(ArgTypes... args) 3276 void make_ready_at_thread_exit(ArgTypes... args) {
3332 { 3277 if(!task) {
3333 if(!task)
3334 {
3335 boost::throw_exception(task_moved()); 3278 boost::throw_exception(task_moved());
3336 } 3279 }
3337 if (task->has_value()) 3280 if (task->has_value()) {
3338 {
3339 boost::throw_exception(promise_already_satisfied()); 3281 boost::throw_exception(promise_already_satisfied());
3340 } 3282 }
3341 task->apply(boost::forward<ArgTypes>(args)...); 3283 task->apply(boost::move(args)...);
3342 } 3284 }
3343 #else 3285 #else
3344 void operator()() 3286 void operator()() {
3345 { 3287 if(!task) {
3346 if(!task)
3347 {
3348 boost::throw_exception(task_moved()); 3288 boost::throw_exception(task_moved());
3349 } 3289 }
3350 task->run(); 3290 task->run();
3351 } 3291 }
3352 void make_ready_at_thread_exit() 3292 void make_ready_at_thread_exit() {
3353 { 3293 if(!task) {
3354 if(!task)
3355 {
3356 boost::throw_exception(task_moved()); 3294 boost::throw_exception(task_moved());
3357 } 3295 }
3358 if (task->has_value()) 3296 if (task->has_value()) boost::throw_exception(promise_already_satisfied());
3359 boost::throw_exception(promise_already_satisfied());
3360 task->apply(); 3297 task->apply();
3361 } 3298 }
3362 #endif 3299 #endif
3363 template<typename F> 3300 template<typename F>
3364 void set_wait_callback(F f) 3301 void set_wait_callback(F f) {
3365 {
3366 task->set_wait_callback(f,this); 3302 task->set_wait_callback(f,this);
3367 } 3303 }
3368 }; 3304 };
3369 3305 }
3370 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS 3306 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3371 namespace container 3307 namespace boost { namespace container {
3372 { 3308 template <class R, class Alloc>
3373 template <class R, class Alloc> 3309 struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3374 struct uses_allocator<packaged_task<R>, Alloc> 3310 {};
3375 : public true_type {}; 3311 }}
3376 } 3312 #if ! defined BOOST_NO_CXX11_ALLOCATOR
3377 #endif 3313 namespace std {
3378 3314 template <class R, class Alloc>
3379 BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END 3315 struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3380 3316 {};
3381 namespace detail 3317 }
3382 { 3318 #endif
3383 //////////////////////////////// 3319 #endif
3384 // make_future_deferred_shared_state 3320
3385 //////////////////////////////// 3321 namespace boost
3386 template <class Rp, class Fp> 3322 {
3387 BOOST_THREAD_FUTURE<Rp> 3323 BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
3388 make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) 3324
3389 { 3325 namespace detail
3390 shared_ptr<future_deferred_shared_state<Rp, Fp> > 3326 {
3391 h(new future_deferred_shared_state<Rp, Fp>(boost::forward<Fp>(f))); 3327 ////////////////////////////////
3392 return BOOST_THREAD_FUTURE<Rp>(h); 3328 // make_future_deferred_shared_state
3393 } 3329 ////////////////////////////////
3394 3330 template <class Rp, class Fp>
3395 //////////////////////////////// 3331 BOOST_THREAD_FUTURE<Rp>
3396 // make_future_async_shared_state 3332 make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3397 //////////////////////////////// 3333 shared_ptr<future_deferred_shared_state<Rp, Fp> >
3398 template <class Rp, class Fp> 3334 h(new future_deferred_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
3399 BOOST_THREAD_FUTURE<Rp> 3335 return BOOST_THREAD_FUTURE<Rp>(h);
3400 make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) 3336 }
3401 { 3337
3402 shared_ptr<future_async_shared_state<Rp, Fp> > 3338 ////////////////////////////////
3403 h(new future_async_shared_state<Rp, Fp>(boost::forward<Fp>(f))); 3339 // make_future_async_shared_state
3404 return BOOST_THREAD_FUTURE<Rp>(h); 3340 ////////////////////////////////
3405 } 3341 template <class Rp, class Fp>
3406 3342 BOOST_THREAD_FUTURE<Rp>
3407 } 3343 make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3344 shared_ptr<future_async_shared_state<Rp, Fp> >
3345 h(new future_async_shared_state<Rp, Fp>());
3346 h->init(boost::forward<Fp>(f));
3347 return BOOST_THREAD_FUTURE<Rp>(h);
3348 }
3349 }
3408 3350
3409 //////////////////////////////// 3351 ////////////////////////////////
3410 // template <class F, class... ArgTypes> 3352 // template <class F, class... ArgTypes>
3411 // future<R> async(launch policy, F&&, ArgTypes&&...); 3353 // future<R> async(launch policy, F&&, ArgTypes&&...);
3412 //////////////////////////////// 3354 ////////////////////////////////
3413 3355
3414 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR 3356 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3415 3357
3416 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK 3358 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3417 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3359 template <class R, class... ArgTypes>
3418 template <class R, class... ArgTypes> 3360 BOOST_THREAD_FUTURE<R>
3419 BOOST_THREAD_FUTURE<R> 3361 async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3420 async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) 3362 typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3421 { 3363 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3422 typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...); 3364 typedef typename BF::result_type Rp;
3423 typedef detail::async_func<typename decay<F>::type, typename decay<ArgTypes>::type...> BF; 3365
3424 typedef typename BF::result_type Rp; 3366 if (underlying_cast<int>(policy) & int(launch::async)) {
3425 #else 3367 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3426 template <class R>
3427 BOOST_THREAD_FUTURE<R>
3428 async(launch policy, R(*f)())
3429 {
3430 typedef packaged_task<R()> packaged_task_type;
3431 #endif
3432 #else
3433 template <class R>
3434 BOOST_THREAD_FUTURE<R>
3435 async(launch policy, R(*f)())
3436 {
3437 typedef packaged_task<R> packaged_task_type;
3438 #endif
3439 if (int(policy) & int(launch::async))
3440 {
3441 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3442 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3443 BF( 3368 BF(
3444 thread_detail::decay_copy(boost::forward<F>(f)) 3369 f
3445 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))... 3370 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3446 ) 3371 )
3447 )); 3372 ));
3448 #else 3373 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3449 packaged_task_type pt( f ); 3374 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3450
3451 BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
3452 ret.set_async();
3453 boost::thread( boost::move(pt) ).detach();
3454 return ::boost::move(ret);
3455 #endif
3456 }
3457 else if (int(policy) & int(launch::deferred))
3458 {
3459 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3460 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3461 BF( 3375 BF(
3462 thread_detail::decay_copy(boost::forward<F>(f)) 3376 f
3463 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))... 3377 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3464 ) 3378 )
3465 )); 3379 ));
3466 #else 3380 } else {
3467 std::terminate(); 3381 std::terminate();
3468 BOOST_THREAD_FUTURE<R> ret; 3382 BOOST_THREAD_FUTURE<R> ret;
3469 return ::boost::move(ret); 3383 return ::boost::move(ret);
3470 3384 }
3471 #endif 3385 }
3472 } else { 3386
3473 std::terminate(); 3387 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3474 BOOST_THREAD_FUTURE<R> ret; 3388
3475 return ::boost::move(ret); 3389 template <class R>
3476 } 3390 BOOST_THREAD_FUTURE<R>
3477 } 3391 async(launch policy, R(*f)()) {
3478 3392 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3479 #endif 3393 typedef packaged_task<R()> packaged_task_type;
3480
3481 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3482 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3483
3484 template <class F, class ...ArgTypes>
3485 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3486 typename decay<ArgTypes>::type...
3487 )>::type>
3488 async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args)
3489 {
3490
3491 typedef typename boost::result_of<typename decay<F>::type(
3492 typename decay<ArgTypes>::type...
3493 )>::type R;
3494
3495 typedef detail::async_func<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3496 typedef typename BF::result_type Rp;
3497
3498 #else 3394 #else
3499 template <class F> 3395 typedef packaged_task<R> packaged_task_type;
3500 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3501 async(launch policy, BOOST_THREAD_FWD_REF(F) f)
3502 {
3503 typedef typename boost::result_of<typename decay<F>::type()>::type R;
3504 typedef packaged_task<R()> packaged_task_type;
3505
3506 #endif 3396 #endif
3507 #else 3397
3508 template <class F> 3398 if (underlying_cast<int>(policy) & int(launch::async)) {
3509 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type> 3399 packaged_task_type pt( f );
3510 async(launch policy, BOOST_THREAD_FWD_REF(F) f) 3400 BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
3511 { 3401 ret.set_async();
3512 typedef typename boost::result_of<typename decay<F>::type()>::type R; 3402 boost::thread( boost::move(pt) ).detach();
3513 typedef packaged_task<R> packaged_task_type; 3403 return ::boost::move(ret);
3514 3404 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3515 #endif 3405 std::terminate();
3516 3406 BOOST_THREAD_FUTURE<R> ret;
3517 if (int(policy) & int(launch::async)) 3407 return ::boost::move(ret);
3518 { 3408 } else {
3519 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3409 std::terminate();
3520 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>( 3410 BOOST_THREAD_FUTURE<R> ret;
3411 return ::boost::move(ret);
3412 }
3413 }
3414 #endif
3415 #endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3416
3417 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3418
3419 template <class F, class ...ArgTypes>
3420 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3421 typename decay<ArgTypes>::type...
3422 )>::type>
3423 async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3424 typedef typename boost::result_of<typename decay<F>::type(
3425 typename decay<ArgTypes>::type...
3426 )>::type R;
3427 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3428 typedef typename BF::result_type Rp;
3429
3430 if (underlying_cast<int>(policy) & int(launch::async)) {
3431 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3521 BF( 3432 BF(
3522 thread_detail::decay_copy(boost::forward<F>(f)) 3433 thread_detail::decay_copy(boost::forward<F>(f))
3523 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))... 3434 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3524 ) 3435 )
3525 )); 3436 ));
3526 #else 3437 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3527 packaged_task_type pt( boost::forward<F>(f) ); 3438 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3528
3529 BOOST_THREAD_FUTURE<R> ret = pt.get_future();
3530 ret.set_async();
3531 boost::thread( boost::move(pt) ).detach();
3532 return ::boost::move(ret);
3533 #endif
3534 }
3535 else if (int(policy) & int(launch::deferred))
3536 {
3537 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3538 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3539 BF( 3439 BF(
3540 thread_detail::decay_copy(boost::forward<F>(f)) 3440 thread_detail::decay_copy(boost::forward<F>(f))
3541 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))... 3441 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3542 ) 3442 )
3543 )); 3443 ));
3544 #else 3444 } else {
3545 std::terminate(); 3445 std::terminate();
3546 BOOST_THREAD_FUTURE<R> ret; 3446 BOOST_THREAD_FUTURE<R> ret;
3547 return ::boost::move(ret); 3447 return ::boost::move(ret);
3548 // return boost::detail::make_future_deferred_shared_state<Rp>( 3448 }
3549 // BF( 3449 }
3550 // thread_detail::decay_copy(boost::forward<F>(f)) 3450
3551 // ) 3451 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3552 // ); 3452
3553 #endif 3453 template <class F>
3554 3454 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3555 } else { 3455 async(launch policy, BOOST_THREAD_FWD_REF(F) f) {
3556 std::terminate(); 3456 typedef typename boost::result_of<typename decay<F>::type()>::type R;
3557 BOOST_THREAD_FUTURE<R> ret; 3457 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3558 return ::boost::move(ret); 3458 typedef packaged_task<R()> packaged_task_type;
3559 } 3459 #else // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3560 } 3460 typedef packaged_task<R> packaged_task_type;
3561 3461 #endif // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3562 //////////////////////////////// 3462
3563 // template <class F, class... ArgTypes> 3463 if (underlying_cast<int>(policy) & int(launch::async)) {
3564 // future<R> async(F&&, ArgTypes&&...); 3464 packaged_task_type pt( boost::forward<F>(f) );
3565 //////////////////////////////// 3465 BOOST_THREAD_FUTURE<R> ret = pt.get_future();
3566 3466 ret.set_async();
3567 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR 3467 boost::thread( boost::move(pt) ).detach();
3568 3468 return ::boost::move(ret);
3569 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3469 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3570 template <class R, class... ArgTypes> 3470 std::terminate();
3571 BOOST_THREAD_FUTURE<R> 3471 BOOST_THREAD_FUTURE<R> ret;
3572 async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) 3472 return ::boost::move(ret);
3573 { 3473 // return boost::detail::make_future_deferred_shared_state<Rp>(
3574 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...)); 3474 // BF(
3575 } 3475 // thread_detail::decay_copy(boost::forward<F>(f))
3576 #else 3476 // )
3577 template <class R> 3477 // );
3578 BOOST_THREAD_FUTURE<R> 3478 } else {
3579 async(R(*f)()) 3479 std::terminate();
3580 { 3480 BOOST_THREAD_FUTURE<R> ret;
3581 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f)); 3481 return ::boost::move(ret);
3582 } 3482 }
3583 #endif 3483 }
3584 #endif 3484 #endif // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3585 3485
3586 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 3486 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3587 template <class F, class ...ArgTypes> 3487 namespace detail {
3588 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type( 3488 /////////////////////////
3589 typename decay<ArgTypes>::type... 3489 /// shared_state_nullary_task
3590 )>::type> 3490 /////////////////////////
3591 async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) 3491 template<typename Rp, typename Fp>
3592 { 3492 struct shared_state_nullary_task
3593 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
3594 }
3595 #else
3596 template <class F>
3597 BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
3598 async(BOOST_THREAD_RV_REF(F) f)
3599 { 3493 {
3600 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f))); 3494 shared_state<Rp>* that;
3601 } 3495 Fp f_;
3602 #endif 3496 public:
3603 3497
3498 shared_state_nullary_task(shared_state<Rp>* st, BOOST_THREAD_FWD_REF(Fp) f)
3499 : that(st), f_(boost::move(f))
3500 {};
3501 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
3502 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
3503 shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
3504 : that(x.that), f_(x.f_)
3505 {}
3506 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3507 {
3508 if (this != &x) {
3509 that=x.that;
3510 f_=x.f_;
3511 }
3512 return *this;
3513 }
3514 // move
3515 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3516 : that(x.that), f_(boost::move(x.f_))
3517 {
3518 x.that=0;
3519 }
3520 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3521 {
3522 if (this != &x) {
3523 that=x.that;
3524 f_=boost::move(x.f_);
3525 x.that=0;
3526 }
3527 return *this;
3528 }
3529 #endif
3530 void operator()() {
3531 try {
3532 that->mark_finished_with_result(f_());
3533 } catch(...) {
3534 that->mark_exceptional_finish();
3535 }
3536 }
3537 };
3538
3539 template<typename Fp>
3540 struct shared_state_nullary_task<void, Fp>
3541 {
3542 shared_state<void>* that;
3543 Fp f_;
3544 public:
3545 shared_state_nullary_task(shared_state<void>* st, BOOST_THREAD_FWD_REF(Fp) f)
3546 : that(st), f_(boost::move(f))
3547 {};
3548 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
3549 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
3550 shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
3551 : that(x.that), f_(x.f_)
3552 {}
3553 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3554 {
3555 if (this != &x) {
3556 that=x.that;
3557 f_=x.f_;
3558 }
3559 return *this;
3560 }
3561 // move
3562 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
3563 : that(x.that), f_(boost::move(x.f_))
3564 {
3565 x.that=0;
3566 }
3567 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
3568 if (this != &x) {
3569 that=x.that;
3570 f_=boost::move(x.f_);
3571 x.that=0;
3572 }
3573 return *this;
3574 }
3575 #endif
3576 void operator()() {
3577 try {
3578 f_();
3579 that->mark_finished_with_result();
3580 } catch(...) {
3581 that->mark_exceptional_finish();
3582 }
3583 }
3584 };
3585
3586 template<typename Rp, typename Fp>
3587 struct shared_state_nullary_task<Rp&, Fp>
3588 {
3589 shared_state<Rp&>* that;
3590 Fp f_;
3591 public:
3592 shared_state_nullary_task(shared_state<Rp&>* st, BOOST_THREAD_FWD_REF(Fp) f)
3593 : that(st), f_(boost::move(f))
3594 {}
3595 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
3596 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
3597 shared_state_nullary_task(shared_state_nullary_task const& x) BOOST_NOEXCEPT
3598 : that(x.that), f_(x.f_) {}
3599
3600 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
3601 if (this != &x){
3602 that=x.that;
3603 f_=x.f_;
3604 }
3605 return *this;
3606 }
3607 // move
3608 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
3609 : that(x.that), f_(boost::move(x.f_))
3610 {
3611 x.that=0;
3612 }
3613 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
3614 if (this != &x) {
3615 that=x.that;
3616 f_=boost::move(x.f_);
3617 x.that=0;
3618 }
3619 return *this;
3620 }
3621 #endif
3622 void operator()() {
3623 try {
3624 that->mark_finished_with_result(f_());
3625 } catch(...) {
3626 that->mark_exceptional_finish();
3627 }
3628 }
3629 };
3630
3631 /////////////////////////
3632 /// future_executor_shared_state_base
3633 /////////////////////////
3634 template<typename Rp, typename Executor>
3635 struct future_executor_shared_state: shared_state<Rp>
3636 {
3637 typedef shared_state<Rp> base_type;
3638 protected:
3639 public:
3640 template<typename Fp>
3641 future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
3642 this->set_executor();
3643 shared_state_nullary_task<Rp,Fp> t(this, boost::forward<Fp>(f));
3644 ex.submit(boost::move(t));
3645 }
3646
3647 virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
3648 {
3649 this->wait(lk, false);
3650 }
3651
3652 ~future_executor_shared_state() {}
3653 };
3654
3655 ////////////////////////////////
3656 // make_future_executor_shared_state
3657 ////////////////////////////////
3658 template <class Rp, class Fp, class Executor>
3659 BOOST_THREAD_FUTURE<Rp>
3660 make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
3661 shared_ptr<future_executor_shared_state<Rp, Executor> >
3662 h(new future_executor_shared_state<Rp, Executor>(ex, boost::forward<Fp>(f)));
3663 return BOOST_THREAD_FUTURE<Rp>(h);
3664 }
3665
3666 } // detail
3667
3668 ////////////////////////////////
3669 // template <class Executor, class F, class... ArgTypes>
3670 // future<R> async(Executor& ex, F&&, ArgTypes&&...);
3671 ////////////////////////////////
3672
3673 //#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3674 #if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
3675
3676 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3677
3678 template <class Executor, class R, class... ArgTypes>
3679 BOOST_THREAD_FUTURE<R>
3680 async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3681 typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3682 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3683 typedef typename BF::result_type Rp;
3684
3685 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3686 BF(
3687 f
3688 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3689 )
3690 ));
3691 }
3692 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3693
3694 template <class Executor, class F, class ...ArgTypes>
3695 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3696 typename decay<ArgTypes>::type...
3697 )>::type>
3698 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3699 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3700 typedef typename BF::result_type Rp;
3701
3702 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3703 BF(
3704 thread_detail::decay_copy(boost::forward<F>(f))
3705 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3706 )
3707 ));
3708 }
3709
3710 #else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3711 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3712
3713 template <class Executor, class R>
3714 BOOST_THREAD_FUTURE<R>
3715 async(Executor& ex, R(*f)()) {
3716 typedef R(*F)();
3717 typedef detail::invoker<F> BF;
3718 typedef typename BF::result_type Rp;
3719
3720 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3721 BF(
3722 f
3723 )
3724 ));
3725 }
3726
3727 template <class Executor, class R, class A1>
3728 BOOST_THREAD_FUTURE<R>
3729 async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1) {
3730 typedef R(*F)(BOOST_THREAD_FWD_REF(A1));
3731 typedef detail::invoker<F, typename decay<A1>::type> BF;
3732 typedef typename BF::result_type Rp;
3733
3734 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3735 BF(
3736 f
3737 , thread_detail::decay_copy(boost::forward<A1>(a1))
3738 )
3739 ));
3740 }
3741 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3742
3743 template <class Executor, class F>
3744 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3745 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f) {
3746 typedef detail::invoker<typename decay<F>::type> BF;
3747 typedef typename BF::result_type Rp;
3748
3749 return boost::detail::make_future_executor_shared_state<Rp>(ex,
3750 BF(
3751 thread_detail::decay_copy(boost::forward<F>(f))
3752 )
3753 );
3754 }
3755
3756 template <class Executor, class F, class A1>
3757 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3758 typename decay<A1>::type
3759 )>::type>
3760 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) {
3761 typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type> BF;
3762 typedef typename BF::result_type Rp;
3763
3764 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3765 BF(
3766 thread_detail::decay_copy(boost::forward<F>(f))
3767 , thread_detail::decay_copy(boost::forward<A1>(a1))
3768 )
3769 ));
3770 }
3771
3772 template <class Executor, class F, class A1, class A2>
3773 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3774 typename decay<A1>::type, typename decay<A2>::type
3775 )>::type>
3776 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) {
3777 typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type, typename decay<A2>::type> BF;
3778 typedef typename BF::result_type Rp;
3779
3780 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3781 BF(
3782 thread_detail::decay_copy(boost::forward<F>(f))
3783 , thread_detail::decay_copy(boost::forward<A1>(a1))
3784 , thread_detail::decay_copy(boost::forward<A2>(a2))
3785 )
3786 ));
3787 }
3788
3789 #endif //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3790 #endif
3791
3792 ////////////////////////////////
3793 // template <class F, class... ArgTypes>
3794 // future<R> async(F&&, ArgTypes&&...);
3795 ////////////////////////////////
3796
3797 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3798 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3799 template <class R, class... ArgTypes>
3800 BOOST_THREAD_FUTURE<R>
3801 async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3802 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
3803 }
3804 #else
3805 template <class R>
3806 BOOST_THREAD_FUTURE<R>
3807 async(R(*f)()) {
3808 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
3809 }
3810 #endif
3811 #endif
3812
3813 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3814 template <class F, class ...ArgTypes>
3815 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3816 typename decay<ArgTypes>::type...
3817 )>::type>
3818 async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3819 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
3820 }
3821 #else
3822 template <class F>
3823 BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
3824 async(BOOST_THREAD_FWD_REF(F) f) {
3825 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
3826 }
3827 #endif
3604 3828
3605 //////////////////////////////// 3829 ////////////////////////////////
3606 // make_future deprecated 3830 // make_future deprecated
3607 //////////////////////////////// 3831 ////////////////////////////////
3608 template <typename T> 3832 template <typename T>
3609 BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value) 3833 BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value) {
3610 {
3611 typedef typename decay<T>::type future_value_type; 3834 typedef typename decay<T>::type future_value_type;
3612 promise<future_value_type> p; 3835 promise<future_value_type> p;
3613 p.set_value(boost::forward<future_value_type>(value)); 3836 p.set_value(boost::forward<future_value_type>(value));
3614 return BOOST_THREAD_MAKE_RV_REF(p.get_future()); 3837 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3615 } 3838 }
3616 3839
3617 #if defined BOOST_THREAD_USES_MOVE 3840 #if defined BOOST_THREAD_USES_MOVE
3618 inline BOOST_THREAD_FUTURE<void> make_future() 3841 inline BOOST_THREAD_FUTURE<void> make_future() {
3619 {
3620 promise<void> p; 3842 promise<void> p;
3621 p.set_value(); 3843 p.set_value();
3622 return BOOST_THREAD_MAKE_RV_REF(p.get_future()); 3844 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3623 } 3845 }
3624 #endif 3846 #endif
3625 3847
3626 //////////////////////////////// 3848 ////////////////////////////////
3627 // make_ready_future 3849 // make_ready_future
3628 //////////////////////////////// 3850 ////////////////////////////////
3629 template <typename T> 3851 namespace detail {
3630 BOOST_THREAD_FUTURE<typename decay<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) 3852 template <class T>
3853 struct deduced_type_impl
3854 {
3855 typedef T type;
3856 };
3857
3858 template <class T>
3859 struct deduced_type_impl<reference_wrapper<T> const>
3860 {
3861 typedef T& type;
3862 };
3863 template <class T>
3864 struct deduced_type_impl<reference_wrapper<T> >
3865 {
3866 typedef T& type;
3867 };
3868 #if __cplusplus > 201103L
3869 template <class T>
3870 struct deduced_type_impl<std::reference_wrapper<T> >
3871 {
3872 typedef T& type;
3873 };
3874 #endif
3875 template <class T>
3876 struct deduced_type
3877 {
3878 typedef typename detail::deduced_type_impl<typename decay<T>::type>::type type;
3879 };
3880
3881 }
3882
3883
3884 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3885 template <int = 0, int..., class T>
3886 #else
3887 template <class T>
3888 #endif
3889 BOOST_THREAD_FUTURE<typename detail::deduced_type<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
3890 typedef typename detail::deduced_type<T>::type future_value_type;
3891 promise<future_value_type> p;
3892 p.set_value(boost::forward<T>(value));
3893 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3894 }
3895
3896 // explicit overloads
3897 template <class T>
3898 BOOST_THREAD_FUTURE<T> make_ready_future(typename remove_reference<T>::type & x)
3631 { 3899 {
3632 typedef typename decay<T>::type future_value_type; 3900 promise<T> p;
3901 p.set_value(x);
3902 return p.get_future();
3903 }
3904
3905 template <class T>
3906 BOOST_THREAD_FUTURE<T> make_ready_future(BOOST_THREAD_FWD_REF(typename remove_reference<T>::type) x)
3907 {
3908 promise<T> p;
3909 p.set_value(forward<typename remove_reference<T>::type>(x));
3910 return p.get_future();
3911 }
3912
3913 // variadic overload
3914 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3915 template <class T, class ...Args>
3916 BOOST_THREAD_FUTURE<T> make_ready_future(Args&&... args)
3917 {
3918 promise<T> p;
3919 p.emplace(forward<Args>(args)...);
3920 return p.get_future();
3921
3922 }
3923 #endif
3924
3925 template <typename T, typename T1>
3926 BOOST_THREAD_FUTURE<T> make_ready_no_decay_future(T1 value) {
3927 typedef T future_value_type;
3633 promise<future_value_type> p; 3928 promise<future_value_type> p;
3634 p.set_value(boost::forward<future_value_type>(value)); 3929 p.set_value(value);
3635 return BOOST_THREAD_MAKE_RV_REF(p.get_future()); 3930 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3636 } 3931 }
3637 3932
3638 #if defined BOOST_THREAD_USES_MOVE 3933 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
3639 inline BOOST_THREAD_FUTURE<void> make_ready_future() 3934 inline BOOST_THREAD_FUTURE<void> make_ready_future() {
3640 {
3641 promise<void> p; 3935 promise<void> p;
3642 p.set_value(); 3936 p.set_value();
3643 return BOOST_THREAD_MAKE_RV_REF(p.get_future()); 3937 return p.get_future();
3644 } 3938 }
3645 #endif 3939 #endif
3646 3940
3647 template <typename T> 3941 template <typename T>
3648 BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex) 3942 BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex) {
3649 {
3650 promise<T> p; 3943 promise<T> p;
3651 p.set_exception(ex); 3944 p.set_exception(ex);
3652 return BOOST_THREAD_MAKE_RV_REF(p.get_future()); 3945 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3653 } 3946 }
3947
3948 template <typename T>
3949 BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
3950 promise<T> p;
3951 p.set_exception(ex);
3952 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3953 }
3954
3654 template <typename T, typename E> 3955 template <typename T, typename E>
3655 BOOST_THREAD_FUTURE<T> make_ready_future(E ex) 3956 BOOST_THREAD_FUTURE<T> make_exceptional_future(E ex) {
3656 {
3657 promise<T> p; 3957 promise<T> p;
3658 p.set_exception(boost::copy_exception(ex)); 3958 p.set_exception(boost::copy_exception(ex));
3659 return BOOST_THREAD_MAKE_RV_REF(p.get_future()); 3959 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3960 }
3961
3962 template <typename T>
3963 BOOST_THREAD_FUTURE<T> make_exceptional_future() {
3964 promise<T> p;
3965 p.set_exception(boost::current_exception());
3966 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3967 }
3968
3969 template <typename T>
3970 BOOST_THREAD_FUTURE<T> make_exceptional_future_if_invalid(BOOST_THREAD_FWD_REF(BOOST_THREAD_FUTURE<T>) fut) {
3971 fut.set_exceptional_if_invalid();
3972 return boost::move(fut);
3973 }
3974 template <typename T>
3975 shared_future<T> make_exceptional_future_if_invalid(shared_future<T> fut) {
3976 fut.set_exceptional_if_invalid();
3977 return fut;
3660 } 3978 }
3661 3979
3662 #if 0 3980 #if 0
3663 template<typename CLOSURE> 3981 template<typename CLOSURE>
3664 make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE<decltype(closure())> { 3982 make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE<decltype(closure())> {
3665 typedef decltype(closure()) T; 3983 typedef decltype(closure()) T;
3666 promise<T> p; 3984 promise<T> p;
3667 try 3985 try {
3668 {
3669 p.set_value(closure()); 3986 p.set_value(closure());
3670 } 3987 } catch(...) {
3671 catch(...)
3672 {
3673 p.set_exception(std::current_exception()); 3988 p.set_exception(std::current_exception());
3674 } 3989 }
3675 return BOOST_THREAD_MAKE_RV_REF(p.get_future()); 3990 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3676 } 3991 }
3677 #endif 3992 #endif
3678 3993
3679 //////////////////////////////// 3994 ////////////////////////////////
3680 // make_shared_future deprecated 3995 // make_shared_future deprecated
3681 //////////////////////////////// 3996 ////////////////////////////////
3682 template <typename T> 3997 template <typename T>
3683 shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value) 3998 shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value) {
3684 {
3685 typedef typename decay<T>::type future_type; 3999 typedef typename decay<T>::type future_type;
3686 promise<future_type> p; 4000 promise<future_type> p;
3687 p.set_value(boost::forward<T>(value)); 4001 p.set_value(boost::forward<T>(value));
3688 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share()); 4002 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
3689 } 4003 }
3690 4004
3691 4005 inline shared_future<void> make_shared_future() {
3692 inline shared_future<void> make_shared_future()
3693 {
3694 promise<void> p; 4006 promise<void> p;
3695 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share()); 4007 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
3696 4008 }
3697 }
3698
3699 // ////////////////////////////////
3700 // // make_ready_shared_future
3701 // ////////////////////////////////
3702 // template <typename T>
3703 // shared_future<typename decay<T>::type> make_ready_shared_future(BOOST_THREAD_FWD_REF(T) value)
3704 // {
3705 // typedef typename decay<T>::type future_type;
3706 // promise<future_type> p;
3707 // p.set_value(boost::forward<T>(value));
3708 // return p.get_future().share();
3709 // }
3710 //
3711 //
3712 // inline shared_future<void> make_ready_shared_future()
3713 // {
3714 // promise<void> p;
3715 // return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
3716 //
3717 // }
3718 //
3719 // ////////////////////////////////
3720 // // make_exceptional_shared_future
3721 // ////////////////////////////////
3722 // template <typename T>
3723 // shared_future<T> make_exceptional_shared_future(exception_ptr ex)
3724 // {
3725 // promise<T> p;
3726 // p.set_exception(ex);
3727 // return p.get_future().share();
3728 // }
3729 4009
3730 //////////////////////////////// 4010 ////////////////////////////////
3731 // detail::future_async_continuation_shared_state 4011 // detail::future_async_continuation_shared_state
3732 //////////////////////////////// 4012 ////////////////////////////////
3733 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION 4013 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
3734 namespace detail 4014 namespace detail
4015 {
4016
4017 /////////////////////////
4018 /// future_async_continuation_shared_state
4019 /////////////////////////
4020
4021 template<typename F, typename Rp, typename Fp>
4022 struct future_async_continuation_shared_state: future_async_shared_state_base<Rp>
3735 { 4023 {
3736 4024 F parent;
3737 ///////////////////////// 4025 Fp continuation;
3738 /// future_async_continuation_shared_state 4026 shared_ptr<shared_state_base> centinel;
3739 ///////////////////////// 4027
3740 4028 public:
3741 template<typename F, typename Rp, typename Fp> 4029 future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
3742 struct future_async_continuation_shared_state: future_async_shared_state_base<Rp> 4030 : parent(boost::move(f)),
4031 continuation(boost::move(c)),
4032 centinel(parent.future_) {
4033 }
4034
4035
4036 void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
4037 this->thr_ = thread(&future_async_continuation_shared_state::run, that);
4038 }
4039
4040 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
4041 future_async_continuation_shared_state* that = dynamic_cast<future_async_continuation_shared_state*>(that_.get());
4042 try {
4043 that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
4044 } catch(...) {
4045 that->mark_exceptional_finish();
4046 }
4047 }
4048
4049 ~future_async_continuation_shared_state() {
4050 }
4051 };
4052
4053 template<typename F, typename Fp>
4054 struct future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void>
4055 {
4056 F parent;
4057 Fp continuation;
4058 shared_ptr<shared_state_base> centinel;
4059
4060 public:
4061 future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4062 : parent(boost::move(f)),
4063 continuation(boost::move(c)),
4064 centinel(parent.future_) {
4065 }
4066
4067 void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
4068 this->thr_ = thread(&future_async_continuation_shared_state::run, that);
4069 }
4070
4071 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
4072 future_async_continuation_shared_state* that = dynamic_cast<future_async_continuation_shared_state*>(that_.get());
4073 try {
4074 that->continuation(boost::move(that->parent));
4075 that->mark_finished_with_result();
4076 } catch(...) {
4077 that->mark_exceptional_finish();
4078 }
4079 }
4080
4081 ~future_async_continuation_shared_state() {}
4082
4083 };
4084
4085 /////////////////////////
4086 /// future_executor_continuation_shared_state
4087 /////////////////////////
4088 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4089
4090 template <typename FutureExecutorContinuationSharedState>
4091 struct run_it {
4092 shared_ptr<boost::detail::shared_state_base> that_;
4093
4094 run_it(shared_ptr<boost::detail::shared_state_base> that) : that_ (that) {}
4095 void operator()()
3743 { 4096 {
3744 F parent; 4097 FutureExecutorContinuationSharedState* that = dynamic_cast<FutureExecutorContinuationSharedState*>(that_.get());
3745 Fp continuation; 4098 that->run(that_);
3746 4099 }
3747 public: 4100 };
3748 future_async_continuation_shared_state( 4101
3749 BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c 4102 template<typename Ex, typename F, typename Rp, typename Fp>
3750 ) : 4103 struct future_executor_continuation_shared_state: shared_state<Rp>
3751 parent(boost::move(f)), 4104 {
3752 continuation(boost::move(c)) 4105 Ex* ex;
3753 { 4106 F parent;
4107 Fp continuation;
4108 shared_ptr<shared_state_base> centinel;
4109
4110 public:
4111 future_executor_continuation_shared_state(Ex& ex, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4112 : ex(&ex), parent(boost::move(f)),
4113 continuation(boost::move(c)),
4114 centinel(parent.future_) {
4115 this->set_executor();
4116 }
4117
4118 void launch_continuation(boost::unique_lock<boost::mutex>& lck, shared_ptr<shared_state_base> that ) {
4119 relocker relock(lck);
4120 run_it<future_executor_continuation_shared_state> fct(that);
4121 ex->submit(fct);
4122 }
4123
4124 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
4125 future_executor_continuation_shared_state* that = dynamic_cast<future_executor_continuation_shared_state*>(that_.get());
4126 try {
4127 that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
4128 } catch(...) {
4129 that->mark_exceptional_finish();
3754 } 4130 }
3755 4131 }
3756 void launch_continuation(boost::unique_lock<boost::mutex>& lock) 4132
3757 { 4133 virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
3758 lock.unlock(); 4134 {
3759 this->thr_ = thread(&future_async_continuation_shared_state::run, this); 4135 this->wait(lk, false);
4136 }
4137
4138 ~future_executor_continuation_shared_state() {}
4139 };
4140
4141 template<typename Ex, typename F, typename Fp>
4142 struct future_executor_continuation_shared_state<Ex, F, void, Fp>: public shared_state<void>
4143 {
4144 Ex* ex;
4145 F parent;
4146 Fp continuation;
4147 shared_ptr<shared_state_base> centinel;
4148
4149 public:
4150 future_executor_continuation_shared_state(Ex& ex, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4151 : ex(&ex), parent(boost::move(f)),
4152 continuation(boost::move(c)),
4153 centinel(parent.future_) {
4154 this->set_executor();
4155 }
4156
4157 void launch_continuation(boost::unique_lock<boost::mutex>& lck, shared_ptr<shared_state_base> that ) {
4158 relocker relock(lck);
4159 run_it<future_executor_continuation_shared_state> fct(that);
4160 ex->submit(fct);
4161 }
4162
4163 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
4164 future_executor_continuation_shared_state* that = dynamic_cast<future_executor_continuation_shared_state*>(that_.get());
4165 try {
4166 that->continuation(boost::move(that->parent));
4167 that->mark_finished_with_result();
4168 } catch(...) {
4169 that->mark_exceptional_finish();
3760 } 4170 }
3761 4171 }
3762 static void run(future_async_continuation_shared_state* that) 4172
3763 { 4173 virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
3764 try 4174 {
3765 { 4175 this->wait(lk, false);
3766 that->mark_finished_with_result(that->continuation(boost::move(that->parent))); 4176 }
3767 } 4177
3768 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 4178 ~future_executor_continuation_shared_state() {}
3769 catch(thread_interrupted& ) 4179 };
3770 { 4180 #endif
3771 that->mark_interrupted_finish(); 4181
3772 } 4182 /////////////////////////
3773 #endif 4183 /// shared_future_async_continuation_shared_state
3774 catch(...) 4184 /////////////////////////
3775 { 4185
3776 that->mark_exceptional_finish(); 4186 template<typename F, typename Rp, typename Fp>
3777 } 4187 struct shared_future_async_continuation_shared_state: future_async_shared_state_base<Rp>
4188 {
4189 F parent;
4190 Fp continuation;
4191 shared_ptr<shared_state_base> centinel;
4192
4193 public:
4194 shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4195 : parent(f),
4196 continuation(boost::move(c)),
4197 centinel(parent.future_) {
4198 }
4199
4200 void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
4201 this->thr_ = thread(&shared_future_async_continuation_shared_state::run, that);
4202 }
4203
4204 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
4205 shared_future_async_continuation_shared_state* that = dynamic_cast<shared_future_async_continuation_shared_state*>(that_.get());
4206 try {
4207 that->mark_finished_with_result(that->continuation(that->parent));
4208 } catch(...) {
4209 that->mark_exceptional_finish();
3778 } 4210 }
3779 ~future_async_continuation_shared_state() 4211 }
3780 { 4212
3781 this->join(); 4213 ~shared_future_async_continuation_shared_state() {}
4214 };
4215
4216 template<typename F, typename Fp>
4217 struct shared_future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void>
4218 {
4219 F parent;
4220 Fp continuation;
4221 shared_ptr<shared_state_base> centinel;
4222
4223 public:
4224 shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4225 : parent(f),
4226 continuation(boost::move(c)),
4227 centinel(parent.future_) {
4228 }
4229
4230 void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
4231 this->thr_ = thread(&shared_future_async_continuation_shared_state::run, that);
4232 }
4233
4234 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
4235 shared_future_async_continuation_shared_state* that = dynamic_cast<shared_future_async_continuation_shared_state*>(that_.get());
4236 try {
4237 that->continuation(that->parent);
4238 that->mark_finished_with_result();
4239 } catch(...) {
4240 that->mark_exceptional_finish();
3782 } 4241 }
3783 }; 4242 }
3784 4243
3785 template<typename F, typename Fp> 4244 ~shared_future_async_continuation_shared_state() {}
3786 struct future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void> 4245 };
4246
4247 /////////////////////////
4248 /// shared_future_executor_continuation_shared_state
4249 /////////////////////////
4250 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4251
4252 template<typename Ex, typename F, typename Rp, typename Fp>
4253 struct shared_future_executor_continuation_shared_state: shared_state<Rp>
4254 {
4255 Ex* ex;
4256 F parent;
4257 Fp continuation;
4258 shared_ptr<shared_state_base> centinel;
4259
4260 public:
4261 shared_future_executor_continuation_shared_state(Ex& ex, F f, BOOST_THREAD_FWD_REF(Fp) c)
4262 : ex(&ex), parent(f),
4263 continuation(boost::move(c)),
4264 centinel(parent.future_) {
4265 this->set_executor();
4266 }
4267
4268 void launch_continuation(boost::unique_lock<boost::mutex>& lck, shared_ptr<shared_state_base> that) {
4269 relocker relock(lck);
4270 run_it<shared_future_executor_continuation_shared_state> fct(that);
4271 ex->submit(fct);
4272 }
4273
4274 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
4275 shared_future_executor_continuation_shared_state* that = dynamic_cast<shared_future_executor_continuation_shared_state*>(that_.get());
4276 try {
4277 that->mark_finished_with_result(that->continuation(that->parent));
4278 } catch(...) {
4279 that->mark_exceptional_finish();
4280 }
4281 }
4282
4283 virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
3787 { 4284 {
3788 F parent; 4285 this->wait(lk, false);
3789 Fp continuation; 4286 }
3790 4287
3791 public: 4288 ~shared_future_executor_continuation_shared_state() {}
3792 future_async_continuation_shared_state( 4289 };
3793 BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c 4290
3794 ) : 4291 template<typename Ex, typename F, typename Fp>
3795 parent(boost::move(f)), 4292 struct shared_future_executor_continuation_shared_state<Ex, F, void, Fp>: public shared_state<void>
3796 continuation(boost::move(c)) 4293 {
3797 { 4294 Ex* ex;
4295 F parent;
4296 Fp continuation;
4297 shared_ptr<shared_state_base> centinel;
4298
4299 public:
4300 shared_future_executor_continuation_shared_state(Ex& ex, F f, BOOST_THREAD_FWD_REF(Fp) c)
4301 : ex(&ex), parent(f),
4302 continuation(boost::move(c)),
4303 centinel(parent.future_) {
4304 }
4305
4306 void launch_continuation(boost::unique_lock<boost::mutex>& lck, shared_ptr<shared_state_base> that) {
4307 relocker relock(lck);
4308 run_it<shared_future_executor_continuation_shared_state> fct(that);
4309 ex->submit(fct);
4310 }
4311
4312 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
4313 shared_future_executor_continuation_shared_state* that = dynamic_cast<shared_future_executor_continuation_shared_state*>(that_.get());
4314 try {
4315 that->continuation(that->parent);
4316 that->mark_finished_with_result();
4317 } catch(...) {
4318 that->mark_exceptional_finish();
3798 } 4319 }
3799 4320 }
3800 void launch_continuation(boost::unique_lock<boost::mutex>& lk) 4321
3801 { 4322 virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
3802 lk.unlock(); 4323 {
3803 this->thr_ = thread(&future_async_continuation_shared_state::run, this); 4324 this->wait(lk, false);
4325 }
4326
4327 ~shared_future_executor_continuation_shared_state() {}
4328 };
4329 #endif
4330 //////////////////////////
4331 /// future_deferred_continuation_shared_state
4332 //////////////////////////
4333 template<typename F, typename Rp, typename Fp>
4334 struct future_deferred_continuation_shared_state: shared_state<Rp>
4335 {
4336 F parent;
4337 Fp continuation;
4338 shared_ptr<shared_state_base> centinel;
4339
4340 public:
4341 future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4342 : parent(boost::move(f)),
4343 continuation(boost::move(c)),
4344 centinel(parent.future_) {
4345 this->set_deferred();
4346 }
4347
4348 virtual void launch_continuation(boost::unique_lock<boost::mutex>&lk, shared_ptr<shared_state_base> ) {
4349 if (this->is_deferred_) {
4350 this->is_deferred_=false;
4351 this->execute(lk);
3804 } 4352 }
3805 4353 }
3806 static void run(future_async_continuation_shared_state* that) 4354
3807 { 4355 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
3808 try 4356 try {
3809 { 4357 Fp local_fuct=boost::move(continuation);
3810 that->continuation(boost::move(that->parent)); 4358 F ftmp = boost::move(parent);
3811 that->mark_finished_with_result(); 4359 relocker relock(lck);
3812 } 4360 Rp res = local_fuct(boost::move(ftmp));
3813 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 4361 relock.lock();
3814 catch(thread_interrupted& ) 4362 this->mark_finished_with_result_internal(boost::move(res), lck);
3815 { 4363 } catch (...) {
3816 that->mark_interrupted_finish(); 4364 this->mark_exceptional_finish_internal(current_exception(), lck);
3817 }
3818 #endif
3819 catch(...)
3820 {
3821 that->mark_exceptional_finish();
3822 }
3823 } 4365 }
3824 ~future_async_continuation_shared_state() 4366 }
3825 { 4367 };
3826 this->join(); 4368
4369 template<typename F, typename Fp>
4370 struct future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void>
4371 {
4372 F parent;
4373 Fp continuation;
4374 shared_ptr<shared_state_base> centinel;
4375
4376 public:
4377 future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4378 : parent(boost::move(f)),
4379 continuation(boost::move(c)),
4380 centinel(parent.future_) {
4381 this->set_deferred();
4382 }
4383
4384 ~future_deferred_continuation_shared_state() {
4385 }
4386 virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk, shared_ptr<shared_state_base> ) {
4387 if (this->is_deferred_) {
4388 this->is_deferred_=false;
4389 this->execute(lk);
3827 } 4390 }
3828 }; 4391 }
3829 4392
3830 4393 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
3831 ////////////////////////// 4394 try {
3832 /// future_deferred_continuation_shared_state 4395 Fp local_fuct=boost::move(continuation);
3833 ////////////////////////// 4396 F ftmp = boost::move(parent);
3834 template<typename F, typename Rp, typename Fp> 4397 relocker relock(lck);
3835 struct future_deferred_continuation_shared_state: shared_state<Rp> 4398 local_fuct(boost::move(ftmp));
3836 { 4399 relock.lock();
3837 F parent; 4400 this->mark_finished_with_result_internal(lck);
3838 Fp continuation; 4401 } catch (...) {
3839 4402 this->mark_exceptional_finish_internal(current_exception(), lck);
3840 public:
3841 future_deferred_continuation_shared_state(
3842 BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
3843 ) :
3844 parent(boost::move(f)),
3845 continuation(boost::move(c))
3846 {
3847 this->set_deferred();
3848 } 4403 }
3849 4404 }
3850 virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk) 4405 };
3851 { 4406
3852 execute(lk); 4407 //////////////////////////
4408 /// shared_future_deferred_continuation_shared_state
4409 //////////////////////////
4410 template<typename F, typename Rp, typename Fp>
4411 struct shared_future_deferred_continuation_shared_state: shared_state<Rp>
4412 {
4413 F parent;
4414 Fp continuation;
4415 shared_ptr<shared_state_base> centinel;
4416
4417 public:
4418 shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4419 : parent(f),
4420 continuation(boost::move(c)),
4421 centinel(parent.future_) {
4422 this->set_deferred();
4423 }
4424
4425 virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk, shared_ptr<shared_state_base> ) {
4426 if (this->is_deferred_) {
4427 this->is_deferred_=false;
4428 this->execute(lk);
3853 } 4429 }
3854 4430 }
3855 virtual void execute(boost::unique_lock<boost::mutex>& lck) { 4431
3856 try 4432 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
3857 { 4433 try {
3858 Fp local_fuct=boost::move(continuation); 4434 Fp local_fuct=boost::move(continuation);
3859 F ftmp = boost::move(parent); 4435 F ftmp = parent;
3860 relocker relock(lck); 4436 relocker relock(lck);
3861 Rp res = local_fuct(boost::move(ftmp)); 4437 Rp res = local_fuct(ftmp);
3862 relock.lock(); 4438 relock.lock();
3863 this->mark_finished_with_result_internal(boost::move(res), lck); 4439 this->mark_finished_with_result_internal(boost::move(res), lck);
3864 } 4440 } catch (...) {
3865 catch (...) 4441 this->mark_exceptional_finish_internal(current_exception(), lck);
3866 {
3867 this->mark_exceptional_finish_internal(current_exception(), lck);
3868 }
3869 } 4442 }
3870 }; 4443 }
3871 4444 };
3872 template<typename F, typename Fp> 4445
3873 struct future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void> 4446 template<typename F, typename Fp>
3874 { 4447 struct shared_future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void>
3875 F parent; 4448 {
3876 Fp continuation; 4449 F parent;
3877 4450 Fp continuation;
3878 public: 4451 shared_ptr<shared_state_base> centinel;
3879 future_deferred_continuation_shared_state( 4452
3880 BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c 4453 public:
3881 ): 4454 shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
3882 parent(boost::move(f)), 4455 : parent(f),
3883 continuation(boost::move(c)) 4456 continuation(boost::move(c)),
3884 { 4457 centinel(parent.future_) {
3885 this->set_deferred(); 4458 this->set_deferred();
4459 }
4460
4461 virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk, shared_ptr<shared_state_base> ) {
4462 if (this->is_deferred_) {
4463 this->is_deferred_=false;
4464 this->execute(lk);
3886 } 4465 }
3887 4466 }
3888 virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk) 4467
3889 { 4468 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
3890 execute(lk); 4469 try {
4470 Fp local_fuct=boost::move(continuation);
4471 F ftmp = parent;
4472 relocker relock(lck);
4473 local_fuct(ftmp);
4474 relock.lock();
4475 this->mark_finished_with_result_internal(lck);
4476 } catch (...) {
4477 this->mark_exceptional_finish_internal(current_exception(), lck);
3891 } 4478 }
3892 virtual void execute(boost::unique_lock<boost::mutex>& lck) { 4479 }
3893 try 4480 };
3894 { 4481
3895 Fp local_fuct=boost::move(continuation); 4482 ////////////////////////////////
3896 F ftmp = boost::move(parent); 4483 // make_future_deferred_continuation_shared_state
3897 relocker relock(lck); 4484 ////////////////////////////////
3898 local_fuct(boost::move(ftmp)); 4485 template<typename F, typename Rp, typename Fp>
3899 relock.lock(); 4486 BOOST_THREAD_FUTURE<Rp>
3900 this->mark_finished_with_result_internal(lck); 4487 make_future_deferred_continuation_shared_state(
3901 } 4488 boost::unique_lock<boost::mutex> &lock,
3902 catch (...) 4489 BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c) {
3903 { 4490 shared_ptr<future_deferred_continuation_shared_state<F, Rp, Fp> >
3904 this->mark_exceptional_finish_internal(current_exception(), lck); 4491 h(new future_deferred_continuation_shared_state<F, Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
3905 } 4492 lock.lock();
3906 } 4493 h->parent.future_->set_continuation_ptr(h, lock);
3907 }; 4494 lock.unlock();
3908 4495 return BOOST_THREAD_FUTURE<Rp>(h);
3909 //////////////////////////////// 4496 }
3910 // make_future_deferred_continuation_shared_state 4497
3911 //////////////////////////////// 4498 ////////////////////////////////
3912 template<typename F, typename Rp, typename Fp> 4499 // make_future_async_continuation_shared_state
3913 BOOST_THREAD_FUTURE<Rp> 4500 ////////////////////////////////
3914 make_future_deferred_continuation_shared_state( 4501 template<typename F, typename Rp, typename Fp>
3915 boost::unique_lock<boost::mutex> &lock, 4502 BOOST_THREAD_FUTURE<Rp>
3916 BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c 4503 make_future_async_continuation_shared_state(
3917 ) 4504 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
3918 { 4505 BOOST_THREAD_FWD_REF(Fp) c) {
3919 shared_ptr<future_deferred_continuation_shared_state<F, Rp, Fp> > 4506 shared_ptr<future_async_continuation_shared_state<F,Rp, Fp> >
3920 h(new future_deferred_continuation_shared_state<F, Rp, Fp>(boost::move(f), boost::forward<Fp>(c))); 4507 h(new future_async_continuation_shared_state<F,Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
3921 h->parent.future_->set_continuation_ptr(h, lock); 4508 lock.lock();
3922 return BOOST_THREAD_FUTURE<Rp>(h); 4509 h->parent.future_->set_continuation_ptr(h, lock);
3923 } 4510 lock.unlock();
3924 4511
3925 //////////////////////////////// 4512 return BOOST_THREAD_FUTURE<Rp>(h);
3926 // make_future_async_continuation_shared_state 4513 }
3927 //////////////////////////////// 4514
3928 template<typename F, typename Rp, typename Fp> 4515 ////////////////////////////////
3929 BOOST_THREAD_FUTURE<Rp> 4516 // make_future_executor_continuation_shared_state
3930 make_future_async_continuation_shared_state( 4517 ////////////////////////////////
3931 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c 4518 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3932 ) 4519
3933 { 4520 template<typename Ex, typename F, typename Rp, typename Fp>
3934 shared_ptr<future_async_continuation_shared_state<F,Rp, Fp> > 4521 BOOST_THREAD_FUTURE<Rp>
3935 h(new future_async_continuation_shared_state<F,Rp, Fp>(boost::move(f), boost::forward<Fp>(c))); 4522 make_future_executor_continuation_shared_state(Ex& ex,
3936 h->parent.future_->set_continuation_ptr(h, lock); 4523 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
3937 4524 BOOST_THREAD_FWD_REF(Fp) c) {
3938 return BOOST_THREAD_FUTURE<Rp>(h); 4525 shared_ptr<future_executor_continuation_shared_state<Ex,F,Rp, Fp> >
3939 } 4526 h(new future_executor_continuation_shared_state<Ex, F,Rp, Fp>(ex, boost::move(f), boost::forward<Fp>(c)));
3940 4527 lock.lock();
3941 } 4528 h->parent.future_->set_continuation_ptr(h, lock);
4529 lock.unlock();
4530
4531 return BOOST_THREAD_FUTURE<Rp>(h);
4532 }
4533 #endif
4534
4535 ////////////////////////////////
4536 // make_shared_future_deferred_continuation_shared_state
4537 ////////////////////////////////
4538 template<typename F, typename Rp, typename Fp>
4539 BOOST_THREAD_FUTURE<Rp>
4540 make_shared_future_deferred_continuation_shared_state(
4541 boost::unique_lock<boost::mutex> &lock,
4542 F f, BOOST_THREAD_FWD_REF(Fp) c) {
4543 shared_ptr<shared_future_deferred_continuation_shared_state<F, Rp, Fp> >
4544 h(new shared_future_deferred_continuation_shared_state<F, Rp, Fp>(f, boost::forward<Fp>(c)));
4545 lock.lock();
4546 h->parent.future_->set_continuation_ptr(h, lock);
4547 lock.unlock();
4548
4549 return BOOST_THREAD_FUTURE<Rp>(h);
4550 }
4551 ////////////////////////////////
4552 // make_shared_future_async_continuation_shared_state
4553 ////////////////////////////////
4554 template<typename F, typename Rp, typename Fp>
4555 BOOST_THREAD_FUTURE<Rp>
4556 make_shared_future_async_continuation_shared_state(
4557 boost::unique_lock<boost::mutex> &lock, F f,
4558 BOOST_THREAD_FWD_REF(Fp) c) {
4559 shared_ptr<shared_future_async_continuation_shared_state<F,Rp, Fp> >
4560 h(new shared_future_async_continuation_shared_state<F,Rp, Fp>(f, boost::forward<Fp>(c)));
4561 lock.lock();
4562 h->parent.future_->set_continuation_ptr(h, lock);
4563 lock.unlock();
4564
4565 return BOOST_THREAD_FUTURE<Rp>(h);
4566 }
4567 ////////////////////////////////
4568 // make_shared_future_executor_continuation_shared_state
4569 ////////////////////////////////
4570 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4571 template<typename Ex, typename F, typename Rp, typename Fp>
4572 BOOST_THREAD_FUTURE<Rp>
4573 make_shared_future_executor_continuation_shared_state(Ex& ex,
4574 boost::unique_lock<boost::mutex> &lock, F f,
4575 BOOST_THREAD_FWD_REF(Fp) c) {
4576 shared_ptr<shared_future_executor_continuation_shared_state<Ex, F, Rp, Fp> >
4577 h(new shared_future_executor_continuation_shared_state<Ex, F, Rp, Fp>(ex, f, boost::forward<Fp>(c)));
4578 lock.lock();
4579 h->parent.future_->set_continuation_ptr(h, lock);
4580 lock.unlock();
4581
4582 return BOOST_THREAD_FUTURE<Rp>(h);
4583 }
4584 #endif
4585 }
3942 4586
3943 //////////////////////////////// 4587 ////////////////////////////////
3944 // template<typename F> 4588 // template<typename F>
3945 // auto future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>; 4589 // auto future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
3946 //////////////////////////////// 4590 ////////////////////////////////
3947 4591
3948 template <typename R> 4592 template <typename R>
3949 template <typename F> 4593 template <typename F>
3950 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type> 4594 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
3951 BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) 4595 BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
3952 {
3953
3954 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type; 4596 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
3955 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); 4597 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
3956 4598
3957 boost::unique_lock<boost::mutex> lock(this->future_->mutex); 4599 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
3958 if (int(policy) & int(launch::async)) 4600 if (underlying_cast<int>(policy) & int(launch::async)) {
3959 { 4601 lock.unlock();
3960 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>( 4602 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
3961 lock, boost::move(*this), boost::forward<F>(func) 4603 lock, boost::move(*this), boost::forward<F>(func)
3962 ))); 4604 )));
3963 } 4605 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3964 else if (int(policy) & int(launch::deferred)) 4606 this->future_->wait_internal(lock);
3965 { 4607 lock.unlock();
3966 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>( 4608 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
3967 lock, boost::move(*this), boost::forward<F>(func) 4609 lock, boost::move(*this), boost::forward<F>(func)
3968 ))); 4610 )));
3969 } 4611 } else {
3970 else 4612 lock.unlock();
3971 {
3972 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>( 4613 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
3973 lock, boost::move(*this), boost::forward<F>(func) 4614 lock, boost::move(*this), boost::forward<F>(func)
3974 ))); 4615 )));
3975 4616 }
3976 } 4617 }
3977 4618 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3978 } 4619 template <typename R>
4620 template <typename Ex, typename F>
4621 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4622 BOOST_THREAD_FUTURE<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
4623 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4624 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4625
4626 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4627 lock.unlock();
4628 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
4629 lock, boost::move(*this), boost::forward<F>(func)
4630 )));
4631 }
4632 #endif
3979 template <typename R> 4633 template <typename R>
3980 template <typename F> 4634 template <typename F>
3981 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type> 4635 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
3982 BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func) 4636 BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func) {
3983 {
3984
3985 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type; 4637 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
3986 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); 4638 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
3987 4639
3988 boost::unique_lock<boost::mutex> lock(this->future_->mutex); 4640 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
3989 if (int(this->launch_policy(lock)) & int(launch::async)) 4641 if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
3990 { 4642 lock.unlock();
3991 return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>( 4643 return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
3992 lock, boost::move(*this), boost::forward<F>(func) 4644 lock, boost::move(*this), boost::forward<F>(func)
3993 ); 4645 );
3994 } 4646 } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
3995 else if (int(this->launch_policy(lock)) & int(launch::deferred)) 4647 this->future_->wait_internal(lock);
3996 { 4648 lock.unlock();
4649 return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4650 lock, boost::move(*this), boost::forward<F>(func)
4651 );
4652 } else {
4653 lock.unlock();
4654 return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4655 lock, boost::move(*this), boost::forward<F>(func)
4656 );
4657 }
4658 }
4659
4660 ////////////////////////////////
4661 // template<typename F>
4662 // auto future<future<R2>>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4663 ////////////////////////////////
4664
4665 template <typename R2>
4666 template <typename F>
4667 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
4668 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
4669 typedef BOOST_THREAD_FUTURE<R2> R;
4670 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4671 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4672
4673 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4674 if (underlying_cast<int>(policy) & int(launch::async)) {
4675 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4676 lock, boost::move(*this), boost::forward<F>(func)
4677 )));
4678 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
4679 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4680 lock, boost::move(*this), boost::forward<F>(func)
4681 )));
4682 } else {
4683 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4684 lock, boost::move(*this), boost::forward<F>(func)
4685 )));
4686 }
4687 }
4688 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4689 template <typename R2>
4690 template <typename Ex, typename F>
4691 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
4692 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
4693 typedef BOOST_THREAD_FUTURE<R2> R;
4694 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4695 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4696
4697 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4698 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
4699 lock, boost::move(*this), boost::forward<F>(func)
4700 )));
4701 }
4702 #endif
4703 template <typename R2>
4704 template <typename F>
4705 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
4706 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(BOOST_THREAD_FWD_REF(F) func) {
4707 typedef BOOST_THREAD_FUTURE<R2> R;
4708 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4709 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4710
4711 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4712 if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
4713 return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4714 lock, boost::move(*this), boost::forward<F>(func)
4715 );
4716 } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
3997 this->future_->wait_internal(lock); 4717 this->future_->wait_internal(lock);
3998 return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>( 4718 return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
3999 lock, boost::move(*this), boost::forward<F>(func) 4719 lock, boost::move(*this), boost::forward<F>(func)
4000 ); 4720 );
4001 } 4721 } else {
4002 else
4003 {
4004 return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>( 4722 return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4005 lock, boost::move(*this), boost::forward<F>(func) 4723 lock, boost::move(*this), boost::forward<F>(func)
4006 ); 4724 );
4007 } 4725 }
4008 } 4726 }
4009 4727
4010 4728 ////////////////////////////////
4011 //#if 0 && defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR) 4729 // template<typename F>
4012 // template <typename R> 4730 // auto shared_future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4013 // template<typename RF> 4731 ////////////////////////////////
4014 // BOOST_THREAD_FUTURE<RF>
4015 // BOOST_THREAD_FUTURE<R>::then(RF(*func)(BOOST_THREAD_FUTURE<R>&))
4016 // {
4017 //
4018 // typedef RF future_type;
4019 //
4020 // if (this->future_)
4021 // {
4022 // boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4023 // detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
4024 // new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func);
4025 // if (ptr==0)
4026 // {
4027 // return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
4028 // }
4029 // this->future_->set_continuation_ptr(ptr, lock);
4030 // return ptr->get_future();
4031 // } else {
4032 // // fixme what to do when the future has no associated state?
4033 // return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
4034 // }
4035 //
4036 // }
4037 // template <typename R>
4038 // template<typename RF>
4039 // BOOST_THREAD_FUTURE<RF>
4040 // BOOST_THREAD_FUTURE<R>::then(launch policy, RF(*func)(BOOST_THREAD_FUTURE<R>&))
4041 // {
4042 //
4043 // typedef RF future_type;
4044 //
4045 // if (this->future_)
4046 // {
4047 // boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4048 // detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
4049 // new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func, policy);
4050 // if (ptr==0)
4051 // {
4052 // return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
4053 // }
4054 // this->future_->set_continuation_ptr(ptr, lock);
4055 // return ptr->get_future();
4056 // } else {
4057 // // fixme what to do when the future has no associated state?
4058 // return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
4059 // }
4060 //
4061 // }
4062 //#endif
4063 4732
4064 template <typename R> 4733 template <typename R>
4065 template <typename F> 4734 template <typename F>
4066 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type> 4735 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
4067 shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) 4736 shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) const
4068 { 4737 {
4069
4070 typedef typename boost::result_of<F(shared_future<R>)>::type future_type; 4738 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
4071 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); 4739 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4072 4740
4073 boost::unique_lock<boost::mutex> lock(this->future_->mutex); 4741 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4074 if (int(policy) & int(launch::async)) 4742 if (underlying_cast<int>(policy) & int(launch::async)) {
4075 { 4743 lock.unlock();
4076 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>( 4744 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
4077 lock, boost::move(*this), boost::forward<F>(func) 4745 lock, *this, boost::forward<F>(func)
4078 ))); 4746 )));
4079 } 4747 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
4080 else if (int(policy) & int(launch::deferred)) 4748 this->future_->wait_internal(lock);
4081 { 4749 lock.unlock();
4082 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>( 4750 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
4083 lock, boost::move(*this), boost::forward<F>(func) 4751 lock, *this, boost::forward<F>(func)
4084 ))); 4752 )));
4085 } 4753 } else {
4086 else 4754 lock.unlock();
4087 { 4755 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
4088 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>( 4756 lock, *this, boost::forward<F>(func)
4089 lock, boost::move(*this), boost::forward<F>(func)
4090 ))); 4757 )));
4091 } 4758 }
4092 4759 }
4093 } 4760 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4761 template <typename R>
4762 template <typename Ex, typename F>
4763 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
4764 shared_future<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const
4765 {
4766 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
4767 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4768
4769 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4770 lock.unlock();
4771 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type, F>(ex,
4772 lock, *this, boost::forward<F>(func)
4773 )));
4774 }
4775 #endif
4776
4094 template <typename R> 4777 template <typename R>
4095 template <typename F> 4778 template <typename F>
4096 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type> 4779 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
4097 shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func) 4780 shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func) const {
4781 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
4782
4783 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4784
4785 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4786 if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
4787 lock.unlock();
4788 return boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
4789 lock, *this, boost::forward<F>(func));
4790 } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
4791 this->future_->wait_internal(lock);
4792 lock.unlock();
4793 return boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
4794 lock, *this, boost::forward<F>(func));
4795 } else {
4796 lock.unlock();
4797 return boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
4798 lock, *this, boost::forward<F>(func));
4799 }
4800 }
4801
4802 namespace detail
4803 {
4804 template <typename T>
4805 struct mfallbacker_to
4098 { 4806 {
4099 4807 T value_;
4100 typedef typename boost::result_of<F(shared_future<R>)>::type future_type; 4808 typedef T result_type;
4101 4809 mfallbacker_to(BOOST_THREAD_RV_REF(T) v)
4102 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); 4810 : value_(boost::move(v))
4103 4811 {}
4104 boost::unique_lock<boost::mutex> lock(this->future_->mutex); 4812
4105 if (int(this->launch_policy(lock)) & int(launch::async)) 4813 T operator()(BOOST_THREAD_FUTURE<T> fut) {
4106 { 4814 return fut.get_or(boost::move(value_));
4107 return boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>( 4815 }
4108 lock, boost::move(*this), boost::forward<F>(func) 4816 };
4109 ); 4817 template <typename T>
4110 } 4818 struct cfallbacker_to
4111 else if (int(this->launch_policy(lock)) & int(launch::deferred))
4112 {
4113 this->future_->wait_internal(lock);
4114 return boost::detail::make_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
4115 lock, boost::move(*this), boost::forward<F>(func)
4116 );
4117 }
4118 else
4119 {
4120 return boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
4121 lock, boost::move(*this), boost::forward<F>(func)
4122 );
4123 }
4124 }
4125 namespace detail
4126 { 4819 {
4127 template <typename T> 4820 T value_;
4128 struct mfallbacker_to 4821 typedef T result_type;
4129 { 4822 cfallbacker_to(T const& v)
4130 T value_; 4823 : value_(v)
4131 typedef T result_type; 4824 {}
4132 mfallbacker_to(BOOST_THREAD_RV_REF(T) v) 4825
4133 : value_(boost::move(v)) 4826 T operator()(BOOST_THREAD_FUTURE<T> fut) const {
4134 {} 4827 return fut.get_or(value_);
4135 4828
4136 T operator()(BOOST_THREAD_FUTURE<T> fut) 4829 }
4137 { 4830 };
4138 return fut.get_or(boost::move(value_)); 4831 }
4139
4140 }
4141 };
4142 template <typename T>
4143 struct cfallbacker_to
4144 {
4145 T value_;
4146 typedef T result_type;
4147 cfallbacker_to(T const& v)
4148 : value_(v)
4149 {}
4150
4151 T operator()(BOOST_THREAD_FUTURE<T> fut)
4152 {
4153 return fut.get_or(value_);
4154
4155 }
4156 };
4157 }
4158 //////////////////////////////// 4832 ////////////////////////////////
4159 // future<R> future<R>::fallback_to(R&& v); 4833 // future<R> future<R>::fallback_to(R&& v);
4160 //////////////////////////////// 4834 ////////////////////////////////
4161 4835
4162 template <typename R> 4836 template <typename R>
4163 template <typename R2> 4837 template <typename R2>
4164 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type 4838 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
4165 BOOST_THREAD_FUTURE<R>::fallback_to(BOOST_THREAD_RV_REF(R2) v) 4839 BOOST_THREAD_FUTURE<R>::fallback_to(BOOST_THREAD_RV_REF(R2) v) {
4166 {
4167 return then(detail::mfallbacker_to<R>(boost::move(v))); 4840 return then(detail::mfallbacker_to<R>(boost::move(v)));
4168 } 4841 }
4169 4842
4170 template <typename R> 4843 template <typename R>
4171 template <typename R2> 4844 template <typename R2>
4172 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type 4845 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
4173 BOOST_THREAD_FUTURE<R>::fallback_to(R2 const& v) 4846 BOOST_THREAD_FUTURE<R>::fallback_to(R2 const& v) {
4847 return then(detail::cfallbacker_to<R>(v));
4848 }
4849
4850 #endif
4851
4852 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
4853 namespace detail
4854 {
4855 /////////////////////////
4856 /// future_unwrap_shared_state
4857 /////////////////////////
4858
4859 template<typename F, typename Rp>
4860 struct future_unwrap_shared_state: shared_state<Rp>
4174 { 4861 {
4175 return then(detail::cfallbacker_to<R>(v)); 4862 F parent;
4176 } 4863 public:
4177 4864 explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
4178 #endif 4865 : parent(boost::move(f)) {}
4179 4866
4180 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP 4867 typename F::value_type parent_value(boost::unique_lock<boost::mutex>& ) {
4181 namespace detail 4868 typename F::value_type r = parent.get();
4182 { 4869 r.set_exceptional_if_invalid();
4183 4870 return boost::move(r);
4184 ///////////////////////// 4871 }
4185 /// future_unwrap_shared_state 4872
4186 ///////////////////////// 4873 virtual void wait(boost::unique_lock<boost::mutex>& lk, bool ) { // todo see if rethrow must be used
4187 4874 parent_value(lk).wait();
4188 template<typename F, typename Rp> 4875 }
4189 struct future_unwrap_shared_state: shared_state<Rp> 4876 virtual Rp get(boost::unique_lock<boost::mutex>& lk) {
4877 return parent_value(lk).get();
4878 }
4879 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
4880 typedef shared_ptr<shared_state_base> continuation_ptr_type;
4881
4882 virtual void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
4190 { 4883 {
4191 F parent; 4884 boost::unique_lock<boost::mutex> lk(parent.future_->mutex);
4192 public: 4885 parent.future_->set_continuation_ptr(continuation, lk);
4193 explicit future_unwrap_shared_state( 4886 }
4194 BOOST_THREAD_RV_REF(F) f 4887 #endif
4195 ) : 4888 };
4196 parent(boost::move(f)) 4889
4197 { 4890 template <class F, class Rp>
4198 } 4891 BOOST_THREAD_FUTURE<Rp>
4199 virtual void wait(bool ) // todo see if rethrow must be used 4892 make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f) {
4200 { 4893 shared_ptr<future_unwrap_shared_state<F, Rp> >
4201 boost::unique_lock<boost::mutex> lock(mutex); 4894 h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
4202 parent.get().wait(); 4895 lock.lock();
4203 } 4896 h->parent.future_->set_continuation_ptr(h, lock);
4204 virtual Rp get() 4897 lock.unlock();
4205 { 4898 return BOOST_THREAD_FUTURE<Rp>(h);
4206 boost::unique_lock<boost::mutex> lock(mutex); 4899 }
4207 return parent.get().get(); 4900 }
4208 }
4209
4210 };
4211
4212 template <class F, class Rp>
4213 BOOST_THREAD_FUTURE<Rp>
4214 make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f)
4215 {
4216 shared_ptr<future_unwrap_shared_state<F, Rp> >
4217 h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
4218 h->parent.future_->set_continuation_ptr(h, lock);
4219 return BOOST_THREAD_FUTURE<Rp>(h);
4220 }
4221 }
4222 4901
4223 template <typename R> 4902 template <typename R>
4224 inline BOOST_THREAD_FUTURE<R>::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other): 4903 inline BOOST_THREAD_FUTURE<R>::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other)
4225 base_type(other.unwrap()) 4904 : base_type(other.unwrap()) {}
4226 {
4227 }
4228 4905
4229 template <typename R2> 4906 template <typename R2>
4230 BOOST_THREAD_FUTURE<R2> 4907 BOOST_THREAD_FUTURE<R2>
4231 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap() 4908 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
4232 { 4909 {
4233 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); 4910 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4234 boost::unique_lock<boost::mutex> lock(this->future_->mutex); 4911 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4912 lock.unlock();
4235 return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this)); 4913 return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
4236 } 4914 }
4237 #endif 4915 #endif
4916
4917 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
4918 namespace detail
4919 {
4920 struct input_iterator_tag {};
4921 struct vector_tag {};
4922 struct values_tag {};
4923 template <typename T>
4924 struct alias_t { typedef T type; };
4925
4926 BOOST_CONSTEXPR_OR_CONST input_iterator_tag input_iterator_tag_value = {};
4927 BOOST_CONSTEXPR_OR_CONST vector_tag vector_tag_value = {};
4928 BOOST_CONSTEXPR_OR_CONST values_tag values_tag_value = {};
4929 ////////////////////////////////
4930 // detail::future_async_when_all_shared_state
4931 ////////////////////////////////
4932 template<typename F>
4933 struct future_when_all_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
4934 {
4935 typedef csbl::vector<F> vector_type;
4936 typedef typename F::value_type value_type;
4937 vector_type vec_;
4938
4939 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
4940 future_when_all_vector_shared_state* that = dynamic_cast<future_when_all_vector_shared_state*>(that_.get());
4941 try {
4942 boost::wait_for_all(that->vec_.begin(), that->vec_.end());
4943 that->mark_finished_with_result(boost::move(that->vec_));
4944 } catch(...) {
4945 that->mark_exceptional_finish();
4946 }
4947 }
4948 bool run_deferred() {
4949
4950 bool res = false;
4951 for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
4952 if (! it->run_if_is_deferred())
4953 {
4954 res = true;
4955 }
4956 }
4957 return res;
4958 }
4959 void init() {
4960 if (! run_deferred())
4961 {
4962 future_when_all_vector_shared_state::run(this->shared_from_this());
4963 return;
4964 }
4965 this->thr_ = thread(&future_when_all_vector_shared_state::run, this->shared_from_this());
4966 }
4967
4968 public:
4969 template< typename InputIterator>
4970 future_when_all_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
4971 : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
4972 {
4973 }
4974
4975 future_when_all_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
4976 : vec_(boost::move(v))
4977 {
4978 }
4979
4980 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4981 template< typename T0, typename ...T>
4982 future_when_all_vector_shared_state(values_tag, BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
4983 vec_.push_back(boost::forward<T0>(f));
4984 typename alias_t<char[]>::type{
4985 ( //first part of magic unpacker
4986 vec_.push_back(boost::forward<T>(futures)),'0'
4987 )..., '0'
4988 }; //second part of magic unpacker
4989 }
4990 #endif
4991
4992 ~future_when_all_vector_shared_state() {}
4993 };
4994
4995 ////////////////////////////////
4996 // detail::future_async_when_any_shared_state
4997 ////////////////////////////////
4998 template<typename F>
4999 struct future_when_any_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
5000 {
5001 typedef csbl::vector<F> vector_type;
5002 typedef typename F::value_type value_type;
5003 vector_type vec_;
5004
5005 static void run(shared_ptr<boost::detail::shared_state_base> that_)
5006 {
5007 future_when_any_vector_shared_state* that = dynamic_cast<future_when_any_vector_shared_state*>(that_.get());
5008 try {
5009 boost::wait_for_any(that->vec_.begin(), that->vec_.end());
5010 that->mark_finished_with_result(boost::move(that->vec_));
5011 } catch(...) {
5012 that->mark_exceptional_finish();
5013 }
5014 }
5015 bool run_deferred() {
5016
5017 for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
5018 if (it->run_if_is_deferred_or_ready())
5019 {
5020 return true;
5021 }
5022 }
5023 return false;
5024 }
5025 void init() {
5026 if (run_deferred())
5027 {
5028 future_when_any_vector_shared_state::run(this->shared_from_this());
5029 return;
5030 }
5031
5032 this->thr_ = thread(&future_when_any_vector_shared_state::run, this->shared_from_this());
5033 }
5034
5035 public:
5036 template< typename InputIterator>
5037 future_when_any_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
5038 : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
5039 {
5040 }
5041
5042 future_when_any_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
5043 : vec_(boost::move(v))
5044 {
5045 }
5046
5047 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5048 template< typename T0, typename ...T>
5049 future_when_any_vector_shared_state(values_tag,
5050 BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures
5051 ) {
5052 vec_.push_back(boost::forward<T0>(f));
5053 typename alias_t<char[]>::type{
5054 ( //first part of magic unpacker
5055 vec_.push_back(boost::forward<T>(futures))
5056 ,'0'
5057 )...,
5058 '0'
5059 }; //second part of magic unpacker
5060 }
5061 #endif
5062
5063 ~future_when_any_vector_shared_state() {}
5064 };
5065
5066 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5067 struct wait_for_all_fctr {
5068 template <class ...T>
5069 void operator()(T&&... v) {
5070 boost::wait_for_all(boost::forward<T>(v)...);
5071 }
5072 };
5073
5074 struct wait_for_any_fctr {
5075 template <class ...T>
5076 void operator()(T&&... v) {
5077 boost::wait_for_any(boost::forward<T>(v)...);
5078 }
5079 };
5080
5081
5082 template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5083 struct accumulate_run_if_is_deferred {
5084 bool operator ()(Tuple& t)
5085 {
5086 return (! csbl::get<i-1>(t).run_if_is_deferred()) || accumulate_run_if_is_deferred<Tuple,i-1>()(t);
5087 }
5088 };
5089 template <class Tuple>
5090 struct accumulate_run_if_is_deferred<Tuple, 0> {
5091 bool operator ()(Tuple& )
5092 {
5093 return false;
5094 }
5095 };
5096
5097
5098 template< typename Tuple, typename T0, typename ...T>
5099 struct future_when_all_tuple_shared_state: future_async_shared_state_base<Tuple>
5100 {
5101 Tuple tup_;
5102 typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5103
5104 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
5105 future_when_all_tuple_shared_state* that = dynamic_cast<future_when_all_tuple_shared_state*>(that_.get());
5106 try {
5107 // TODO make use of apply(that->tup_, boost::detail::wait_for_all_fctor());
5108 that->wait_for_all(Index());
5109
5110 that->mark_finished_with_result(boost::move(that->tup_));
5111 } catch(...) {
5112 that->mark_exceptional_finish();
5113 }
5114 }
5115
5116 template <size_t ...Indices>
5117 void wait_for_all(tuple_indices<Indices...>) {
5118 #if defined BOOST_THREAD_PROVIDES_INVOKE
5119 return invoke<void>(wait_for_all_fctr(), csbl::get<Indices>(tup_)...);
5120 #else
5121 return wait_for_all_fctr()(csbl::get<Indices>(tup_)...);
5122 #endif
5123 }
5124
5125 bool run_deferred() {
5126
5127 return accumulate_run_if_is_deferred<Tuple>()(tup_);
5128 }
5129 void init() {
5130 if (! run_deferred())
5131 {
5132 future_when_all_tuple_shared_state::run(this->shared_from_this());
5133 return;
5134 }
5135
5136 this->thr_ = thread(&future_when_all_tuple_shared_state::run, this->shared_from_this());
5137 }
5138 public:
5139 template< typename F, typename ...Fs>
5140 future_when_all_tuple_shared_state(values_tag, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures) :
5141 tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5142 {
5143 }
5144
5145 ~future_when_all_tuple_shared_state() {}
5146
5147 };
5148
5149
5150 template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5151 struct apply_any_run_if_is_deferred_or_ready {
5152 bool operator ()(Tuple& t)
5153 {
5154 if (csbl::get<i-1>(t).run_if_is_deferred_or_ready()) return true;
5155 return apply_any_run_if_is_deferred_or_ready<Tuple,i-1>()(t);
5156 }
5157 };
5158 template <class Tuple>
5159 struct apply_any_run_if_is_deferred_or_ready<Tuple, 0> {
5160 bool operator ()(Tuple& )
5161 {
5162 return false;
5163 }
5164 };
5165
5166 template< typename Tuple, typename T0, typename ...T >
5167 struct future_when_any_tuple_shared_state: future_async_shared_state_base<Tuple>
5168 {
5169 Tuple tup_;
5170 typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5171
5172 static void run(shared_ptr<boost::detail::shared_state_base> that_)
5173 {
5174 future_when_any_tuple_shared_state* that = dynamic_cast<future_when_any_tuple_shared_state*>(that_.get());
5175 try {
5176 // TODO make use of apply(that->tup_, wait_for_any_fctr);
5177 that->wait_for_any(Index());
5178
5179 that->mark_finished_with_result(boost::move(that->tup_));
5180 } catch(...) {
5181 that->mark_exceptional_finish();
5182 }
5183 }
5184 template <size_t ...Indices>
5185 void wait_for_any(tuple_indices<Indices...>) {
5186 #if defined BOOST_THREAD_PROVIDES_INVOKE
5187 return invoke<void>(wait_for_any_fctr(), csbl::get<Indices>(tup_)...);
5188 #else
5189 return wait_for_any_fctr()(csbl::get<Indices>(tup_)...);
5190 #endif
5191 }
5192 bool run_deferred() {
5193 return apply_any_run_if_is_deferred_or_ready<Tuple>()(tup_);
5194 }
5195 void init() {
5196 if (run_deferred())
5197 {
5198 future_when_any_tuple_shared_state::run(this->shared_from_this());
5199 return;
5200 }
5201
5202 this->thr_ = thread(&future_when_any_tuple_shared_state::run, this->shared_from_this());
5203 }
5204
5205 public:
5206 template< typename F, typename ...Fs>
5207 future_when_any_tuple_shared_state(values_tag,
5208 BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures
5209 ) :
5210 tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5211 {
5212 }
5213
5214 ~future_when_any_tuple_shared_state() {}
5215 };
5216 #endif
5217
5218 }
5219
5220 template< typename InputIterator>
5221 typename boost::disable_if<is_future_type<InputIterator>,
5222 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
5223 >::type
5224 when_all(InputIterator first, InputIterator last) {
5225 typedef typename InputIterator::value_type value_type;
5226 typedef csbl::vector<value_type> container_type;
5227 typedef detail::future_when_all_vector_shared_state<value_type> factory_type;
5228
5229 if (first==last) return make_ready_future(container_type());
5230 shared_ptr<factory_type >
5231 h(new factory_type(detail::input_iterator_tag_value, first,last));
5232 h->init();
5233 return BOOST_THREAD_FUTURE<container_type>(h);
5234 }
5235
5236 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all() {
5237 return make_ready_future(csbl::tuple<>());
5238 }
5239
5240 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5241 template< typename T0, typename ...T>
5242 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5243 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5244 typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5245 typedef detail::future_when_all_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5246
5247 shared_ptr<factory_type>
5248 h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5249 h->init();
5250 return BOOST_THREAD_FUTURE<container_type>(h);
5251 }
5252 #endif
5253
5254 template< typename InputIterator>
5255 typename boost::disable_if<is_future_type<InputIterator>,
5256 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
5257 >::type
5258 when_any(InputIterator first, InputIterator last) {
5259 typedef typename InputIterator::value_type value_type;
5260 typedef csbl::vector<value_type> container_type;
5261 typedef detail::future_when_any_vector_shared_state<value_type> factory_type;
5262
5263 if (first==last) return make_ready_future(container_type());
5264 shared_ptr<factory_type >
5265 h(new factory_type(detail::input_iterator_tag_value, first,last));
5266 h->init();
5267 return BOOST_THREAD_FUTURE<container_type>(h);
5268 }
5269
5270 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any() {
5271 return make_ready_future(csbl::tuple<>());
5272 }
5273
5274 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5275 template< typename T0, typename ...T>
5276 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5277 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5278 typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5279 typedef detail::future_when_any_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5280
5281 shared_ptr<factory_type>
5282 h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5283 h->init();
5284 return BOOST_THREAD_FUTURE<container_type>(h);
5285 }
5286 #endif
5287 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
4238 } 5288 }
4239 5289
4240 #endif // BOOST_NO_EXCEPTION 5290 #endif // BOOST_NO_EXCEPTION
4241 #endif // header 5291 #endif // header