• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  (C) Copyright 2008-10 Anthony Williams
2 //  (C) Copyright 2011-2015 Vicente J. Botet Escriba
3 //
4 //  Distributed under the Boost Software License, Version 1.0. (See
5 //  accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 
8 #ifndef BOOST_THREAD_FUTURE_HPP
9 #define BOOST_THREAD_FUTURE_HPP
10 
11 #include <boost/thread/detail/config.hpp>
12 
13 // boost::thread::future requires exception handling
14 // due to boost::exception::exception_ptr dependency
15 
16 //#define BOOST_THREAD_CONTINUATION_SYNC
17 
18 #ifdef BOOST_NO_EXCEPTIONS
19 namespace boost
20 {
21 namespace detail {
22 struct shared_state_base {
notify_deferredboost::detail::shared_state_base23     void notify_deferred() {}
24 };
25 }
26 }
27 #else
28 
29 #include <boost/thread/condition_variable.hpp>
30 #include <boost/thread/detail/move.hpp>
31 #include <boost/thread/detail/invoker.hpp>
32 #include <boost/thread/detail/invoke.hpp>
33 #include <boost/thread/detail/is_convertible.hpp>
34 #include <boost/thread/exceptional_ptr.hpp>
35 #include <boost/thread/futures/future_error.hpp>
36 #include <boost/thread/futures/future_error_code.hpp>
37 #include <boost/thread/futures/future_status.hpp>
38 #include <boost/thread/futures/is_future_type.hpp>
39 #include <boost/thread/futures/launch.hpp>
40 #include <boost/thread/futures/wait_for_all.hpp>
41 #include <boost/thread/futures/wait_for_any.hpp>
42 #include <boost/thread/lock_algorithms.hpp>
43 #include <boost/thread/lock_types.hpp>
44 #include <boost/thread/mutex.hpp>
45 #include <boost/thread/thread_only.hpp>
46 #include <boost/thread/thread_time.hpp>
47 #include <boost/thread/executor.hpp>
48 #include <boost/thread/executors/generic_executor_ref.hpp>
49 
50 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
51 #include <boost/optional.hpp>
52 #else
53 #include <boost/thread/csbl/memory/unique_ptr.hpp>
54 #endif
55 
56 #include <boost/assert.hpp>
57 #include <boost/bind/bind.hpp>
58 #ifdef BOOST_THREAD_USES_CHRONO
59 #include <boost/chrono/system_clocks.hpp>
60 #endif
61 #include <boost/core/enable_if.hpp>
62 #include <boost/core/ref.hpp>
63 #include <boost/enable_shared_from_this.hpp>
64 #include <boost/exception_ptr.hpp>
65 #include <boost/function.hpp>
66 #include <boost/next_prior.hpp>
67 #include <boost/scoped_array.hpp>
68 #include <boost/shared_ptr.hpp>
69 #include <boost/smart_ptr/make_shared.hpp>
70 #include <boost/throw_exception.hpp>
71 #include <boost/type_traits/conditional.hpp>
72 #include <boost/type_traits/decay.hpp>
73 #include <boost/type_traits/is_copy_constructible.hpp>
74 #include <boost/type_traits/is_fundamental.hpp>
75 #include <boost/type_traits/is_void.hpp>
76 #include <boost/utility/result_of.hpp>
77 
78 
79 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
80 #include <boost/thread/detail/memory.hpp>
81 #include <boost/container/scoped_allocator.hpp>
82 #if ! defined  BOOST_NO_CXX11_ALLOCATOR
83 #include <memory>
84 #endif
85 #endif
86 
87 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
88 #include <boost/thread/csbl/tuple.hpp>
89 #include <boost/thread/csbl/vector.hpp>
90 #endif
91 
92 #include <algorithm>
93 #include <list>
94 #include <vector>
95 #include <utility>
96 
97 #if defined BOOST_THREAD_PROVIDES_FUTURE
98 #define BOOST_THREAD_FUTURE future
99 #else
100 #define BOOST_THREAD_FUTURE unique_future
101 #endif
102 
103 namespace boost
104 {
105   template <class T>
static_shared_from_this(T * that)106   shared_ptr<T> static_shared_from_this(T* that)
107   {
108     return static_pointer_cast<T>(that->shared_from_this());
109   }
110   template <class T>
static_shared_from_this(T const * that)111   shared_ptr<T const> static_shared_from_this(T const* that)
112   {
113     return static_pointer_cast<T const>(that->shared_from_this());
114   }
115 
116 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
117 #else
118     namespace executors {
119         class executor;
120     }
121     using executors::executor;
122 #endif
123     typedef shared_ptr<executor> executor_ptr_type;
124 
125     namespace detail
126     {
127 
128         struct relocker
129         {
130             boost::unique_lock<boost::mutex>& lock_;
131 
relockerboost::detail::relocker132             relocker(boost::unique_lock<boost::mutex>& lk):
133                 lock_(lk)
134             {
135                 lock_.unlock();
136             }
~relockerboost::detail::relocker137             ~relocker()
138             {
139               if (! lock_.owns_lock()) {
140                 lock_.lock();
141               }
142             }
lockboost::detail::relocker143             void lock() {
144               if (! lock_.owns_lock()) {
145                 lock_.lock();
146               }
147             }
148         private:
149             relocker& operator=(relocker const&);
150         };
151 
152         struct shared_state_base : enable_shared_from_this<shared_state_base>
153         {
154             typedef std::list<boost::condition_variable_any*> waiter_list;
155             typedef waiter_list::iterator notify_when_ready_handle;
156             // This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
157             typedef shared_ptr<shared_state_base> continuation_ptr_type;
158             typedef std::vector<continuation_ptr_type> continuations_type;
159 
160             boost::exception_ptr exception;
161             bool done;
162             bool is_valid_;
163             bool is_deferred_;
164             bool is_constructed;
165             launch policy_;
166             mutable boost::mutex mutex;
167             boost::condition_variable waiters;
168             waiter_list external_waiters;
169             boost::function<void()> callback;
170             // This declaration should be only included conditionally, but is included to maintain the same layout.
171             continuations_type continuations;
172             executor_ptr_type ex_;
173 
174             // This declaration should be only included conditionally, but is included to maintain the same layout.
launch_continuationboost::detail::shared_state_base175             virtual void launch_continuation()
176             {
177             }
178 
shared_state_baseboost::detail::shared_state_base179             shared_state_base():
180                 done(false),
181                 is_valid_(true),
182                 is_deferred_(false),
183                 is_constructed(false),
184                 policy_(launch::none),
185                 continuations(),
186                 ex_()
187             {}
188 
shared_state_baseboost::detail::shared_state_base189             shared_state_base(exceptional_ptr const& ex):
190                 exception(ex.ptr_),
191                 done(true),
192                 is_valid_(true),
193                 is_deferred_(false),
194                 is_constructed(false),
195                 policy_(launch::none),
196                 continuations(),
197                 ex_()
198             {}
199 
200 
~shared_state_baseboost::detail::shared_state_base201             virtual ~shared_state_base()
202             {
203             }
204 
is_doneboost::detail::shared_state_base205             bool is_done()
206             {
207                 return done;
208             }
209 
get_executorboost::detail::shared_state_base210             executor_ptr_type get_executor()
211             {
212               return ex_;
213             }
214 
set_executor_policyboost::detail::shared_state_base215             void set_executor_policy(executor_ptr_type aex)
216             {
217               set_executor();
218               ex_ = aex;
219             }
set_executor_policyboost::detail::shared_state_base220             void set_executor_policy(executor_ptr_type aex, boost::lock_guard<boost::mutex>&)
221             {
222               set_executor();
223               ex_ = aex;
224             }
set_executor_policyboost::detail::shared_state_base225             void set_executor_policy(executor_ptr_type aex, boost::unique_lock<boost::mutex>&)
226             {
227               set_executor();
228               ex_ = aex;
229             }
230 
validboost::detail::shared_state_base231             bool valid(boost::unique_lock<boost::mutex>&) { return is_valid_; }
validboost::detail::shared_state_base232             bool valid() {
233               boost::unique_lock<boost::mutex> lk(this->mutex);
234               return valid(lk);
235             }
invalidateboost::detail::shared_state_base236             void invalidate(boost::unique_lock<boost::mutex>&) { is_valid_ = false; }
invalidateboost::detail::shared_state_base237             void invalidate() {
238               boost::unique_lock<boost::mutex> lk(this->mutex);
239               invalidate(lk);
240             }
validateboost::detail::shared_state_base241             void validate(boost::unique_lock<boost::mutex>&) { is_valid_ = true; }
validateboost::detail::shared_state_base242             void validate() {
243               boost::unique_lock<boost::mutex> lk(this->mutex);
244               validate(lk);
245             }
246 
set_deferredboost::detail::shared_state_base247             void set_deferred()
248             {
249               is_deferred_ = true;
250               policy_ = launch::deferred;
251             }
set_asyncboost::detail::shared_state_base252             void set_async()
253             {
254               is_deferred_ = false;
255               policy_ = launch::async;
256             }
257 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
set_executorboost::detail::shared_state_base258             void set_executor()
259             {
260               is_deferred_ = false;
261               policy_ = launch::executor;
262             }
263 #else
set_executorboost::detail::shared_state_base264             void set_executor()
265             {
266             }
267 #endif
notify_when_readyboost::detail::shared_state_base268             notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
269             {
270                 boost::unique_lock<boost::mutex> lock(this->mutex);
271                 do_callback(lock);
272                 return external_waiters.insert(external_waiters.end(),&cv);
273             }
274 
unnotify_when_readyboost::detail::shared_state_base275             void unnotify_when_ready(notify_when_ready_handle it)
276             {
277                 boost::lock_guard<boost::mutex> lock(this->mutex);
278                 external_waiters.erase(it);
279             }
280 
281 #if 0
282             // this inline definition results in ODR. See https://github.com/boostorg/thread/issues/193
283             // to avoid it, we define the function on the derived templates using the macro BOOST_THREAD_DO_CONTINUATION
284 #define BOOST_THREAD_DO_CONTINUATION
285 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
286             void do_continuation(boost::unique_lock<boost::mutex>& lock)
287             {
288                 if (! continuations.empty()) {
289                   continuations_type the_continuations = continuations;
290                   continuations.clear();
291                   relocker rlk(lock);
292                   for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) {
293                     (*it)->launch_continuation();
294                   }
295                 }
296             }
297 #else
298             void do_continuation(boost::unique_lock<boost::mutex>&)
299             {
300             }
301 #endif
302 
303 #else
304 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
305 #define BOOST_THREAD_DO_CONTINUATION \
306             void do_continuation(boost::unique_lock<boost::mutex>& lock) \
307             { \
308                 if (! this->continuations.empty()) { \
309                   continuations_type the_continuations = this->continuations; \
310                   this->continuations.clear(); \
311                   relocker rlk(lock); \
312                   for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) { \
313                     (*it)->launch_continuation(); \
314                   } \
315                 } \
316             }
317 #else
318 #define BOOST_THREAD_DO_CONTINUATION \
319             void do_continuation(boost::unique_lock<boost::mutex>&) \
320             { \
321             }
322 #endif
323 
324             virtual void do_continuation(boost::unique_lock<boost::mutex>&) = 0;
325 #endif
326 
327 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
set_continuation_ptrboost::detail::shared_state_base328             virtual void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
329             {
330               continuations.push_back(continuation);
331               if (done) {
332                 do_continuation(lock);
333               }
334             }
335 #endif
mark_finished_internalboost::detail::shared_state_base336             void mark_finished_internal(boost::unique_lock<boost::mutex>& lock)
337             {
338                 done=true;
339                 waiters.notify_all();
340                 for(waiter_list::const_iterator it=external_waiters.begin(),
341                         end=external_waiters.end();it!=end;++it)
342                 {
343                     (*it)->notify_all();
344                 }
345                 do_continuation(lock);
346             }
notify_deferredboost::detail::shared_state_base347             void notify_deferred()
348             {
349               boost::unique_lock<boost::mutex> lock(this->mutex);
350               mark_finished_internal(lock);
351             }
352 
do_callbackboost::detail::shared_state_base353             void do_callback(boost::unique_lock<boost::mutex>& lock)
354             {
355                 if(callback && !done)
356                 {
357                     boost::function<void()> local_callback=callback;
358                     relocker relock(lock);
359                     local_callback();
360                 }
361             }
362 
run_if_is_deferredboost::detail::shared_state_base363             virtual bool run_if_is_deferred()
364             {
365               boost::unique_lock<boost::mutex> lk(this->mutex);
366               if (is_deferred_)
367               {
368                 is_deferred_=false;
369                 execute(lk);
370                 return true;
371               }
372               else
373                 return false;
374             }
run_if_is_deferred_or_readyboost::detail::shared_state_base375             virtual bool run_if_is_deferred_or_ready()
376             {
377               boost::unique_lock<boost::mutex> lk(this->mutex);
378               if (is_deferred_)
379               {
380                 is_deferred_=false;
381                 execute(lk);
382 
383                 return true;
384               }
385               else
386                 return done;
387             }
wait_internalboost::detail::shared_state_base388             void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true)
389             {
390               do_callback(lk);
391               if (is_deferred_)
392               {
393                 is_deferred_=false;
394                 execute(lk);
395               }
396               waiters.wait(lk, boost::bind(&shared_state_base::is_done, boost::ref(*this)));
397               if(rethrow && exception)
398               {
399                   boost::rethrow_exception(exception);
400               }
401             }
402 
waitboost::detail::shared_state_base403             virtual void wait(boost::unique_lock<boost::mutex>& lock, bool rethrow=true)
404             {
405                 wait_internal(lock, rethrow);
406             }
407 
waitboost::detail::shared_state_base408             void wait(bool rethrow=true)
409             {
410                 boost::unique_lock<boost::mutex> lock(this->mutex);
411                 wait(lock, rethrow);
412             }
413 
414 #if defined BOOST_THREAD_USES_DATETIME
415             template<typename Duration>
timed_waitboost::detail::shared_state_base416             bool timed_wait(Duration const& rel_time)
417             {
418                 boost::unique_lock<boost::mutex> lock(this->mutex);
419                 if (is_deferred_)
420                     return false;
421 
422                 do_callback(lock);
423                 return waiters.timed_wait(lock, rel_time, boost::bind(&shared_state_base::is_done, boost::ref(*this)));
424             }
425 
timed_wait_untilboost::detail::shared_state_base426             bool timed_wait_until(boost::system_time const& target_time)
427             {
428                 boost::unique_lock<boost::mutex> lock(this->mutex);
429                 if (is_deferred_)
430                     return false;
431 
432                 do_callback(lock);
433                 return waiters.timed_wait(lock, target_time, boost::bind(&shared_state_base::is_done, boost::ref(*this)));
434             }
435 #endif
436 #ifdef BOOST_THREAD_USES_CHRONO
437 
438             template <class Clock, class Duration>
439             future_status
wait_untilboost::detail::shared_state_base440             wait_until(const chrono::time_point<Clock, Duration>& abs_time)
441             {
442               boost::unique_lock<boost::mutex> lock(this->mutex);
443               if (is_deferred_)
444                   return future_status::deferred;
445               do_callback(lock);
446               if(!waiters.wait_until(lock, abs_time, boost::bind(&shared_state_base::is_done, boost::ref(*this))))
447               {
448                   return future_status::timeout;
449               }
450               return future_status::ready;
451             }
452 #endif
mark_exceptional_finish_internalboost::detail::shared_state_base453             void mark_exceptional_finish_internal(boost::exception_ptr const& e, boost::unique_lock<boost::mutex>& lock)
454             {
455                 exception=e;
456                 mark_finished_internal(lock);
457             }
458 
mark_exceptional_finishboost::detail::shared_state_base459             void mark_exceptional_finish()
460             {
461                 boost::unique_lock<boost::mutex> lock(this->mutex);
462                 mark_exceptional_finish_internal(boost::current_exception(), lock);
463             }
464 
set_exception_deferredboost::detail::shared_state_base465             void set_exception_deferred(exception_ptr e)
466             {
467               unique_lock<boost::mutex> lk(this->mutex);
468               if (has_value(lk))
469               {
470                   throw_exception(promise_already_satisfied());
471               }
472               exception=e;
473               this->is_constructed = true;
474             }
set_exception_at_thread_exitboost::detail::shared_state_base475             void set_exception_at_thread_exit(exception_ptr e)
476             {
477               set_exception_deferred(e);
478 //              unique_lock<boost::mutex> lk(this->mutex);
479 //              if (has_value(lk))
480 //              {
481 //                  throw_exception(promise_already_satisfied());
482 //              }
483 //              exception=e;
484 //              this->is_constructed = true;
485               detail::make_ready_at_thread_exit(shared_from_this());
486             }
487 
has_valueboost::detail::shared_state_base488             bool has_value() const
489             {
490                 boost::lock_guard<boost::mutex> lock(this->mutex);
491                 return done && ! exception;
492             }
493 
has_valueboost::detail::shared_state_base494             bool has_value(unique_lock<boost::mutex>& )  const
495             {
496                 return done && ! exception;
497             }
498 
has_exceptionboost::detail::shared_state_base499             bool has_exception()  const
500             {
501                 boost::lock_guard<boost::mutex> lock(this->mutex);
502                 return done && exception;
503             }
504 
launch_policyboost::detail::shared_state_base505             launch launch_policy(boost::unique_lock<boost::mutex>&) const
506             {
507                 return policy_;
508             }
509 
get_stateboost::detail::shared_state_base510             future_state::state get_state(boost::unique_lock<boost::mutex>&) const
511             {
512                 if(!done)
513                 {
514                     return future_state::waiting;
515                 }
516                 else
517                 {
518                     return future_state::ready;
519                 }
520             }
get_stateboost::detail::shared_state_base521             future_state::state get_state() const
522             {
523                 boost::lock_guard<boost::mutex> guard(this->mutex);
524                 if(!done)
525                 {
526                     return future_state::waiting;
527                 }
528                 else
529                 {
530                     return future_state::ready;
531                 }
532             }
533 
get_exception_ptrboost::detail::shared_state_base534             exception_ptr get_exception_ptr()
535             {
536                 boost::unique_lock<boost::mutex> lock(this->mutex);
537                 wait_internal(lock, false);
538                 return exception;
539             }
540 
541             template<typename F,typename U>
set_wait_callbackboost::detail::shared_state_base542             void set_wait_callback(F f,U* u)
543             {
544                 boost::lock_guard<boost::mutex> lock(this->mutex);
545                 callback=boost::bind(f,boost::ref(*u));
546             }
547 
executeboost::detail::shared_state_base548             virtual void execute(boost::unique_lock<boost::mutex>&) {}
549 
550         private:
551             shared_state_base(shared_state_base const&);
552             shared_state_base& operator=(shared_state_base const&);
553         };
554 
555         // Used to create stand-alone futures
556         template<typename T>
557         struct shared_state:
558             detail::shared_state_base
559         {
560 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
561               typedef boost::optional<T> storage_type;
562 #else
563               typedef boost::csbl::unique_ptr<T> storage_type;
564 #endif
565 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
566             typedef T const& source_reference_type;
567             typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
568             typedef T move_dest_type;
569 #elif defined BOOST_THREAD_USES_MOVE
570             typedef typename conditional<boost::is_fundamental<T>::value,T,T const&>::type source_reference_type;
571             typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
572             typedef T move_dest_type;
573 #else
574             typedef T& source_reference_type;
575             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;
576             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;
577 #endif
578 
579             typedef const T& shared_future_get_result_type;
580 
581             storage_type result;
582 
shared_stateboost::detail::shared_state583             shared_state():
584                 result()
585             {}
shared_stateboost::detail::shared_state586             shared_state(exceptional_ptr const& ex):
587               detail::shared_state_base(ex), result()
588             {}
589 
590             // locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
591             BOOST_THREAD_DO_CONTINUATION
592 
mark_finished_with_result_internalboost::detail::shared_state593             void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
594             {
595 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
596                 result = result_;
597 #else
598                 result.reset(new T(result_));
599 #endif
600                 this->mark_finished_internal(lock);
601             }
602 
mark_finished_with_result_internalboost::detail::shared_state603             void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
604             {
605 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
606                 result = boost::move(result_);
607 #elif ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
608                 result.reset(new T(boost::move(result_)));
609 #else
610                 result.reset(new T(static_cast<rvalue_source_type>(result_)));
611 #endif
612                 this->mark_finished_internal(lock);
613             }
614 
615 
616 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
617             template <class ...Args>
mark_finished_with_result_internalboost::detail::shared_state618             void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock, BOOST_THREAD_FWD_REF(Args)... args)
619             {
620 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
621                 result.emplace(boost::forward<Args>(args)...);
622 #else
623                 result.reset(new T(boost::forward<Args>(args)...));
624 #endif
625                 this->mark_finished_internal(lock);
626             }
627 #endif
628 
mark_finished_with_resultboost::detail::shared_state629             void mark_finished_with_result(source_reference_type result_)
630             {
631                 boost::unique_lock<boost::mutex> lock(this->mutex);
632                 this->mark_finished_with_result_internal(result_, lock);
633             }
634 
mark_finished_with_resultboost::detail::shared_state635             void mark_finished_with_result(rvalue_source_type result_)
636             {
637                 boost::unique_lock<boost::mutex> lock(this->mutex);
638 
639 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
640                 mark_finished_with_result_internal(boost::move(result_), lock);
641 #else
642                 mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
643 #endif
644             }
645 
get_storageboost::detail::shared_state646             storage_type& get_storage(boost::unique_lock<boost::mutex>& lk)
647             {
648                 wait_internal(lk);
649                 return result;
650             }
getboost::detail::shared_state651             virtual move_dest_type get(boost::unique_lock<boost::mutex>& lk)
652             {
653                 return boost::move(*get_storage(lk));
654             }
getboost::detail::shared_state655             move_dest_type get()
656             {
657                 boost::unique_lock<boost::mutex> lk(this->mutex);
658                 return this->get(lk);
659             }
660 
get_shboost::detail::shared_state661             virtual shared_future_get_result_type get_sh(boost::unique_lock<boost::mutex>& lk)
662             {
663                 return *get_storage(lk);
664             }
get_shboost::detail::shared_state665             shared_future_get_result_type get_sh()
666             {
667                 boost::unique_lock<boost::mutex> lk(this->mutex);
668                 return this->get_sh(lk);
669             }
set_value_deferredboost::detail::shared_state670             void set_value_deferred(source_reference_type result_)
671             {
672               unique_lock<boost::mutex> lk(this->mutex);
673               if (this->has_value(lk))
674               {
675                   throw_exception(promise_already_satisfied());
676               }
677 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
678               result = result_;
679 #else
680               result.reset(new T(result_));
681 #endif
682 
683               this->is_constructed = true;
684             }
set_value_deferredboost::detail::shared_state685             void set_value_deferred(rvalue_source_type result_)
686             {
687               unique_lock<boost::mutex> lk(this->mutex);
688               if (this->has_value(lk))
689               {
690                   throw_exception(promise_already_satisfied());
691               }
692 
693 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
694 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
695                 result = boost::move(result_);
696 #else
697                 result.reset(new T(boost::move(result_)));
698 #endif
699 #else
700 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
701                 result = boost::move(result_);
702 #else
703                 result.reset(new T(static_cast<rvalue_source_type>(result_)));
704 #endif
705 #endif
706               this->is_constructed = true;
707             }
708 
set_value_at_thread_exitboost::detail::shared_state709             void set_value_at_thread_exit(source_reference_type result_)
710             {
711                 set_value_deferred(result_);
712 //              unique_lock<boost::mutex> lk(this->mutex);
713 //              if (this->has_value(lk))
714 //              {
715 //                  throw_exception(promise_already_satisfied());
716 //              }
717 //#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
718 //              result = result_;
719 //#else
720 //              result.reset(new T(result_));
721 //#endif
722 //
723 //              this->is_constructed = true;
724               detail::make_ready_at_thread_exit(shared_from_this());
725             }
set_value_at_thread_exitboost::detail::shared_state726             void set_value_at_thread_exit(rvalue_source_type result_)
727             {
728                 set_value_deferred(boost::move(result_));
729 //              unique_lock<boost::mutex> lk(this->mutex);
730 //              if (this->has_value(lk))
731 //                  throw_exception(promise_already_satisfied());
732 //
733 //#if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
734 //#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
735 //                result = boost::move(result_);
736 //#else
737 //                result.reset(new T(boost::move(result_)));
738 //#endif
739 //#else
740 //#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
741 //                result = boost::move(result_);
742 //#else
743 //                result.reset(new T(static_cast<rvalue_source_type>(result_)));
744 //#endif
745 //#endif
746 //              this->is_constructed = true;
747               detail::make_ready_at_thread_exit(shared_from_this());
748             }
749 
750         private:
751             shared_state(shared_state const&);
752             shared_state& operator=(shared_state const&);
753         };
754 
755         template<typename T>
756         struct shared_state<T&>:
757             detail::shared_state_base
758         {
759             typedef T* storage_type;
760             typedef T& source_reference_type;
761             typedef T& move_dest_type;
762             typedef T& shared_future_get_result_type;
763 
764             T* result;
765 
shared_stateboost::detail::shared_state766             shared_state():
767                 result(0)
768             {}
769 
shared_stateboost::detail::shared_state770             shared_state(exceptional_ptr const& ex):
771               detail::shared_state_base(ex), result(0)
772             {}
773 
774             // locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
775             BOOST_THREAD_DO_CONTINUATION
776 
mark_finished_with_result_internalboost::detail::shared_state777             void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
778             {
779                 result= &result_;
780                 mark_finished_internal(lock);
781             }
782 
mark_finished_with_resultboost::detail::shared_state783             void mark_finished_with_result(source_reference_type result_)
784             {
785                 boost::unique_lock<boost::mutex> lock(this->mutex);
786                 mark_finished_with_result_internal(result_, lock);
787             }
788 
getboost::detail::shared_state789             virtual T& get(boost::unique_lock<boost::mutex>& lock)
790             {
791                 wait_internal(lock);
792                 return *result;
793             }
getboost::detail::shared_state794             T& get()
795             {
796                 boost::unique_lock<boost::mutex> lk(this->mutex);
797                 return get(lk);
798             }
799 
get_shboost::detail::shared_state800             virtual T& get_sh(boost::unique_lock<boost::mutex>& lock)
801             {
802                 wait_internal(lock);
803                 return *result;
804             }
get_shboost::detail::shared_state805             T& get_sh()
806             {
807                 boost::unique_lock<boost::mutex> lock(this->mutex);
808                 return get_sh(lock);
809             }
810 
set_value_deferredboost::detail::shared_state811             void set_value_deferred(T& result_)
812             {
813               unique_lock<boost::mutex> lk(this->mutex);
814               if (this->has_value(lk))
815               {
816                   throw_exception(promise_already_satisfied());
817               }
818               result= &result_;
819               this->is_constructed = true;
820             }
821 
set_value_at_thread_exitboost::detail::shared_state822             void set_value_at_thread_exit(T& result_)
823             {
824               set_value_deferred(result_);
825 //              unique_lock<boost::mutex> lk(this->mutex);
826 //              if (this->has_value(lk))
827 //                  throw_exception(promise_already_satisfied());
828 //              result= &result_;
829 //              this->is_constructed = true;
830               detail::make_ready_at_thread_exit(shared_from_this());
831             }
832 
833         private:
834             shared_state(shared_state const&);
835             shared_state& operator=(shared_state const&);
836         };
837 
838         template<>
839         struct shared_state<void>:
840             detail::shared_state_base
841         {
842             typedef void shared_future_get_result_type;
843             typedef void move_dest_type;
844 
shared_stateboost::detail::shared_state845             shared_state()
846             {}
847 
shared_stateboost::detail::shared_state848             shared_state(exceptional_ptr const& ex):
849               detail::shared_state_base(ex)
850             {}
851 
852             // locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
853             BOOST_THREAD_DO_CONTINUATION
854 
mark_finished_with_result_internalboost::detail::shared_state855             void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
856             {
857                 mark_finished_internal(lock);
858             }
859 
mark_finished_with_resultboost::detail::shared_state860             void mark_finished_with_result()
861             {
862                 boost::unique_lock<boost::mutex> lock(this->mutex);
863                 mark_finished_with_result_internal(lock);
864             }
865 
getboost::detail::shared_state866             virtual void get(boost::unique_lock<boost::mutex>& lock)
867             {
868                 this->wait_internal(lock);
869             }
getboost::detail::shared_state870             void get()
871             {
872                 boost::unique_lock<boost::mutex> lock(this->mutex);
873                 this->get(lock);
874             }
875 
get_shboost::detail::shared_state876             virtual void get_sh(boost::unique_lock<boost::mutex>& lock)
877             {
878                 this->wait_internal(lock);
879             }
get_shboost::detail::shared_state880             void get_sh()
881             {
882                 boost::unique_lock<boost::mutex> lock(this->mutex);
883                 this->get_sh(lock);
884             }
885 
set_value_deferredboost::detail::shared_state886             void set_value_deferred()
887             {
888               unique_lock<boost::mutex> lk(this->mutex);
889               if (this->has_value(lk))
890               {
891                   throw_exception(promise_already_satisfied());
892               }
893               this->is_constructed = true;
894             }
set_value_at_thread_exitboost::detail::shared_state895             void set_value_at_thread_exit()
896             {
897               set_value_deferred();
898 //              unique_lock<boost::mutex> lk(this->mutex);
899 //              if (this->has_value(lk))
900 //              {
901 //                  throw_exception(promise_already_satisfied());
902 //              }
903 //              this->is_constructed = true;
904               detail::make_ready_at_thread_exit(shared_from_this());
905             }
906         private:
907             shared_state(shared_state const&);
908             shared_state& operator=(shared_state const&);
909         };
910 
911         /////////////////////////
912         /// future_async_shared_state_base
913         /////////////////////////
914         template<typename Rp>
915         struct future_async_shared_state_base: shared_state<Rp>
916         {
917           typedef shared_state<Rp> base_type;
918         protected:
919 #ifdef BOOST_THREAD_FUTURE_BLOCKING
920           boost::thread thr_;
joinboost::detail::future_async_shared_state_base921           void join()
922           {
923               if (this_thread::get_id() == thr_.get_id())
924               {
925                   thr_.detach();
926                   return;
927               }
928               if (thr_.joinable()) thr_.join();
929           }
930 #endif
931         public:
future_async_shared_state_baseboost::detail::future_async_shared_state_base932           future_async_shared_state_base()
933           {
934             this->set_async();
935           }
936 
~future_async_shared_state_baseboost::detail::future_async_shared_state_base937           ~future_async_shared_state_base()
938           {
939 #ifdef BOOST_THREAD_FUTURE_BLOCKING
940             join();
941 #elif defined BOOST_THREAD_ASYNC_FUTURE_WAITS
942             unique_lock<boost::mutex> lk(this->mutex);
943             this->waiters.wait(lk, boost::bind(&shared_state_base::is_done, boost::ref(*this)));
944 #endif
945           }
946 
waitboost::detail::future_async_shared_state_base947           virtual void wait(boost::unique_lock<boost::mutex>& lk, bool rethrow)
948           {
949 #ifdef BOOST_THREAD_FUTURE_BLOCKING
950               {
951                 relocker rlk(lk);
952                 join();
953               }
954 #endif
955               this->base_type::wait(lk, rethrow);
956           }
957         };
958 
959         /////////////////////////
960         /// future_async_shared_state
961         /////////////////////////
962         template<typename Rp, typename Fp>
963         struct future_async_shared_state: future_async_shared_state_base<Rp>
964         {
future_async_shared_stateboost::detail::future_async_shared_state965           future_async_shared_state()
966           {
967           }
968 
initboost::detail::future_async_shared_state969           void init(BOOST_THREAD_FWD_REF(Fp) f)
970           {
971 #ifdef BOOST_THREAD_FUTURE_BLOCKING
972             this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f));
973 #else
974             boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f)).detach();
975 #endif
976           }
977 
runboost::detail::future_async_shared_state978           static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
979           {
980             try
981             {
982               that->mark_finished_with_result(f());
983             }
984             catch(...)
985             {
986               that->mark_exceptional_finish();
987             }
988           }
989         };
990 
991         template<typename Fp>
992         struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void>
993         {
initboost::detail::future_async_shared_state994           void init(BOOST_THREAD_FWD_REF(Fp) f)
995           {
996 #ifdef BOOST_THREAD_FUTURE_BLOCKING
997             this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
998 #else
999             boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
1000 #endif
1001           }
1002 
runboost::detail::future_async_shared_state1003           static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
1004           {
1005             try
1006             {
1007               f();
1008               that->mark_finished_with_result();
1009             }
1010             catch(...)
1011             {
1012               that->mark_exceptional_finish();
1013             }
1014           }
1015         };
1016 
1017         template<typename Rp, typename Fp>
1018         struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&>
1019         {
initboost::detail::future_async_shared_state1020           void init(BOOST_THREAD_FWD_REF(Fp) f)
1021           {
1022 #ifdef BOOST_THREAD_FUTURE_BLOCKING
1023             this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
1024 #else
1025             boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
1026 #endif
1027           }
1028 
runboost::detail::future_async_shared_state1029           static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
1030           {
1031             try
1032             {
1033               that->mark_finished_with_result(f());
1034             }
1035             catch(...)
1036             {
1037               that->mark_exceptional_finish();
1038             }
1039           }
1040         };
1041 
1042         //////////////////////////
1043         /// future_deferred_shared_state
1044         //////////////////////////
1045         template<typename Rp, typename Fp>
1046         struct future_deferred_shared_state: shared_state<Rp>
1047         {
1048           Fp func_;
1049 
future_deferred_shared_stateboost::detail::future_deferred_shared_state1050           explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1051           : func_(boost::move(f))
1052           {
1053             this->set_deferred();
1054           }
1055 
executeboost::detail::future_deferred_shared_state1056           virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1057             try
1058             {
1059               Fp local_fuct=boost::move(func_);
1060               relocker relock(lck);
1061               Rp res = local_fuct();
1062               relock.lock();
1063               this->mark_finished_with_result_internal(boost::move(res), lck);
1064             }
1065             catch (...)
1066             {
1067               this->mark_exceptional_finish_internal(current_exception(), lck);
1068             }
1069           }
1070         };
1071         template<typename Rp, typename Fp>
1072         struct future_deferred_shared_state<Rp&,Fp>: shared_state<Rp&>
1073         {
1074           Fp func_;
1075 
future_deferred_shared_stateboost::detail::future_deferred_shared_state1076           explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1077           : func_(boost::move(f))
1078           {
1079             this->set_deferred();
1080           }
1081 
executeboost::detail::future_deferred_shared_state1082           virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1083             try
1084             {
1085               this->mark_finished_with_result_internal(func_(), lck);
1086             }
1087             catch (...)
1088             {
1089               this->mark_exceptional_finish_internal(current_exception(), lck);
1090             }
1091           }
1092         };
1093 
1094         template<typename Fp>
1095         struct future_deferred_shared_state<void,Fp>: shared_state<void>
1096         {
1097           Fp func_;
1098 
future_deferred_shared_stateboost::detail::future_deferred_shared_state1099           explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1100           : func_(boost::move(f))
1101           {
1102             this->set_deferred();
1103           }
1104 
executeboost::detail::future_deferred_shared_state1105           virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1106             try
1107             {
1108               Fp local_fuct=boost::move(func_);
1109               relocker relock(lck);
1110               local_fuct();
1111               relock.lock();
1112               this->mark_finished_with_result_internal(lck);
1113             }
1114             catch (...)
1115             {
1116               this->mark_exceptional_finish_internal(current_exception(), lck);
1117             }
1118           }
1119         };
1120 
1121         class future_waiter
1122         {
1123         public:
1124             typedef std::vector<int>::size_type count_type;
1125         private:
1126             struct registered_waiter
1127             {
1128                 boost::shared_ptr<detail::shared_state_base> future_;
1129                 detail::shared_state_base::notify_when_ready_handle handle;
1130                 count_type index;
1131 
registered_waiterboost::detail::future_waiter::registered_waiter1132                 registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
1133                                   detail::shared_state_base::notify_when_ready_handle handle_,
1134                                   count_type index_):
1135                     future_(a_future),handle(handle_),index(index_)
1136                 {}
1137             };
1138 
1139             struct all_futures_lock
1140             {
1141 #ifdef _MANAGED
1142                    typedef std::ptrdiff_t count_type_portable;
1143 #else
1144                    typedef count_type count_type_portable;
1145 #endif
1146                    count_type_portable count;
1147                    boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
1148 
all_futures_lockboost::detail::future_waiter::all_futures_lock1149                 all_futures_lock(std::vector<registered_waiter>& futures):
1150                     count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
1151                 {
1152                     for(count_type_portable i=0;i<count;++i)
1153                     {
1154                         locks[i]=BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(futures[i].future_->mutex));
1155                     }
1156                 }
1157 
lockboost::detail::future_waiter::all_futures_lock1158                 void lock()
1159                 {
1160                     boost::lock(locks.get(),locks.get()+count);
1161                 }
1162 
unlockboost::detail::future_waiter::all_futures_lock1163                 void unlock()
1164                 {
1165                     for(count_type_portable i=0;i<count;++i)
1166                     {
1167                         locks[i].unlock();
1168                     }
1169                 }
1170             };
1171 
1172             boost::condition_variable_any cv;
1173             std::vector<registered_waiter> futures_;
1174             count_type future_count;
1175 
1176         public:
future_waiter()1177             future_waiter():
1178                 future_count(0)
1179             {}
1180 
1181             template<typename F>
add(F & f)1182             void add(F& f)
1183             {
1184                 if(f.future_)
1185                 {
1186                   registered_waiter waiter(f.future_,f.future_->notify_when_ready(cv),future_count);
1187                   try {
1188                     futures_.push_back(waiter);
1189                   } catch(...) {
1190                     f.future_->unnotify_when_ready(waiter.handle);
1191                     throw;
1192                   }
1193                 }
1194                 ++future_count;
1195             }
1196 
1197 #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1198             template<typename F1, typename... Fs>
add(F1 & f1,Fs &...fs)1199             void add(F1& f1, Fs&... fs)
1200             {
1201               add(f1); add(fs...);
1202             }
1203 #endif
1204 
wait()1205             count_type wait()
1206             {
1207                 all_futures_lock lk(futures_);
1208                 for(;;)
1209                 {
1210                     for(count_type i=0;i<futures_.size();++i)
1211                     {
1212                         if(futures_[i].future_->done)
1213                         {
1214                             return futures_[i].index;
1215                         }
1216                     }
1217                     cv.wait(lk);
1218                 }
1219             }
1220 
~future_waiter()1221             ~future_waiter()
1222             {
1223                 for(count_type i=0;i<futures_.size();++i)
1224                 {
1225                     futures_[i].future_->unnotify_when_ready(futures_[i].handle);
1226                 }
1227             }
1228         };
1229 
1230     }
1231 
1232     template <typename R>
1233     class BOOST_THREAD_FUTURE;
1234 
1235     template <typename R>
1236     class shared_future;
1237 
1238     template<typename T>
1239     struct is_future_type<BOOST_THREAD_FUTURE<T> > : true_type
1240     {
1241     };
1242 
1243     template<typename T>
1244     struct is_future_type<shared_future<T> > : true_type
1245     {
1246     };
1247 
1248 //    template<typename Iterator>
1249 //    typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
1250 //    {
1251 //        if(begin==end)
1252 //            return end;
1253 //
1254 //        detail::future_waiter waiter;
1255 //        for(Iterator current=begin;current!=end;++current)
1256 //        {
1257 //            waiter.add(*current);
1258 //        }
1259 //        return boost::next(begin,waiter.wait());
1260 //    }
1261 
1262 #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1263     template<typename F1,typename F2>
wait_for_any(F1 & f1,F2 & f2)1264     typename boost::enable_if<is_future_type<F1>,typename detail::future_waiter::count_type>::type wait_for_any(F1& f1,F2& f2)
1265     {
1266         detail::future_waiter waiter;
1267         waiter.add(f1);
1268         waiter.add(f2);
1269         return waiter.wait();
1270     }
1271 
1272     template<typename F1,typename F2,typename F3>
wait_for_any(F1 & f1,F2 & f2,F3 & f3)1273     typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3)
1274     {
1275         detail::future_waiter waiter;
1276         waiter.add(f1);
1277         waiter.add(f2);
1278         waiter.add(f3);
1279         return waiter.wait();
1280     }
1281 
1282     template<typename F1,typename F2,typename F3,typename F4>
wait_for_any(F1 & f1,F2 & f2,F3 & f3,F4 & f4)1283     typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
1284     {
1285         detail::future_waiter waiter;
1286         waiter.add(f1);
1287         waiter.add(f2);
1288         waiter.add(f3);
1289         waiter.add(f4);
1290         return waiter.wait();
1291     }
1292 
1293     template<typename F1,typename F2,typename F3,typename F4,typename F5>
wait_for_any(F1 & f1,F2 & f2,F3 & f3,F4 & f4,F5 & f5)1294     typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
1295     {
1296         detail::future_waiter waiter;
1297         waiter.add(f1);
1298         waiter.add(f2);
1299         waiter.add(f3);
1300         waiter.add(f4);
1301         waiter.add(f5);
1302         return waiter.wait();
1303     }
1304 #else
1305     template<typename F1, typename... Fs>
1306     typename boost::enable_if<is_future_type<F1>, typename detail::future_waiter::count_type>::type
wait_for_any(F1 & f1,Fs &...fs)1307     wait_for_any(F1& f1, Fs&... fs)
1308     {
1309       detail::future_waiter waiter;
1310       waiter.add(f1, fs...);
1311       return waiter.wait();
1312     }
1313 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1314 
1315     template <typename R>
1316     class promise;
1317 
1318     template <typename R>
1319     class packaged_task;
1320 
1321     namespace detail
1322     {
1323       /// Common implementation for all the futures independently of the return type
1324       class base_future
1325       {
1326       public:
1327       };
1328       /// Common implementation for future and shared_future.
1329       template <typename R>
1330       class basic_future : public base_future
1331       {
1332       protected:
1333       public:
1334 
1335         typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
1336         typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
1337 
1338         static //BOOST_CONSTEXPR
make_exceptional_future_ptr(exceptional_ptr const & ex)1339         future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
1340           return future_ptr(new detail::shared_state<R>(ex));
1341         }
1342 
1343         future_ptr future_;
1344 
basic_future(future_ptr a_future)1345         basic_future(future_ptr a_future):
1346           future_(a_future)
1347         {
1348         }
1349 
1350       public:
1351         typedef future_state::state state;
1352 
1353         BOOST_THREAD_MOVABLE_ONLY(basic_future)
basic_future()1354         basic_future(): future_() {}
1355 
1356 
1357         //BOOST_CONSTEXPR
basic_future(exceptional_ptr const & ex)1358         basic_future(exceptional_ptr const& ex)
1359           : future_(make_exceptional_future_ptr(ex))
1360         {
1361         }
1362 
~basic_future()1363         ~basic_future() {
1364         }
1365 
basic_future(BOOST_THREAD_RV_REF (basic_future)other)1366         basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
1367         future_(BOOST_THREAD_RV(other).future_)
1368         {
1369             BOOST_THREAD_RV(other).future_.reset();
1370         }
operator =(BOOST_THREAD_RV_REF (basic_future)other)1371         basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
1372         {
1373             future_=BOOST_THREAD_RV(other).future_;
1374             BOOST_THREAD_RV(other).future_.reset();
1375             return *this;
1376         }
swap(basic_future & that)1377         void swap(basic_future& that) BOOST_NOEXCEPT
1378         {
1379           future_.swap(that.future_);
1380         }
1381         // functions to check state, and wait for ready
get_state(boost::unique_lock<boost::mutex> & lk) const1382         state get_state(boost::unique_lock<boost::mutex>& lk) const
1383         {
1384             if(!future_)
1385             {
1386                 return future_state::uninitialized;
1387             }
1388             return future_->get_state(lk);
1389         }
get_state() const1390         state get_state() const
1391         {
1392             if(!future_)
1393             {
1394                 return future_state::uninitialized;
1395             }
1396             return future_->get_state();
1397         }
1398 
is_ready() const1399         bool is_ready() const
1400         {
1401             return get_state()==future_state::ready;
1402         }
1403 
is_ready(boost::unique_lock<boost::mutex> & lk) const1404         bool is_ready(boost::unique_lock<boost::mutex>& lk) const
1405         {
1406             return get_state(lk)==future_state::ready;
1407         }
has_exception() const1408         bool has_exception() const
1409         {
1410             return future_ && future_->has_exception();
1411         }
1412 
has_value() const1413         bool has_value() const
1414         {
1415             return future_ && future_->has_value();
1416         }
1417 
launch_policy(boost::unique_lock<boost::mutex> & lk) const1418         launch launch_policy(boost::unique_lock<boost::mutex>& lk) const
1419         {
1420             if ( future_ ) return future_->launch_policy(lk);
1421             else return launch(launch::none);
1422         }
1423 
launch_policy() const1424         launch launch_policy() const
1425         {
1426           if ( future_ ) {
1427             boost::unique_lock<boost::mutex> lk(this->future_->mutex);
1428             return future_->launch_policy(lk);
1429           }
1430           else return launch(launch::none);
1431         }
1432 
get_exception_ptr()1433         exception_ptr get_exception_ptr()
1434         {
1435             return future_
1436                 ? future_->get_exception_ptr()
1437                 : exception_ptr();
1438         }
1439 
valid() const1440         bool valid() const BOOST_NOEXCEPT
1441         {
1442             return future_.get() != 0 && future_->valid();
1443         }
1444 
wait() const1445         void wait() const
1446         {
1447             if(!future_)
1448             {
1449                 boost::throw_exception(future_uninitialized());
1450             }
1451             future_->wait(false);
1452         }
1453 
1454         typedef detail::shared_state_base::notify_when_ready_handle notify_when_ready_handle;
1455 
mutex()1456         boost::mutex& mutex() {
1457           if(!future_)
1458           {
1459               boost::throw_exception(future_uninitialized());
1460           }
1461           return future_->mutex;
1462         }
1463 
notify_when_ready(boost::condition_variable_any & cv)1464         notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
1465         {
1466           if(!future_)
1467           {
1468               boost::throw_exception(future_uninitialized());
1469           }
1470           return future_->notify_when_ready(cv);
1471         }
1472 
unnotify_when_ready(notify_when_ready_handle h)1473         void unnotify_when_ready(notify_when_ready_handle h)
1474         {
1475           if(!future_)
1476           {
1477               boost::throw_exception(future_uninitialized());
1478           }
1479           return future_->unnotify_when_ready(h);
1480         }
1481 
1482 #if defined BOOST_THREAD_USES_DATETIME
1483         template<typename Duration>
timed_wait(Duration const & rel_time) const1484         bool timed_wait(Duration const& rel_time) const
1485         {
1486             if(!future_)
1487             {
1488                 boost::throw_exception(future_uninitialized());
1489             }
1490             return future_->timed_wait(rel_time);
1491         }
1492 
timed_wait_until(boost::system_time const & abs_time) const1493         bool timed_wait_until(boost::system_time const& abs_time) const
1494         {
1495             if(!future_)
1496             {
1497                 boost::throw_exception(future_uninitialized());
1498             }
1499             return future_->timed_wait_until(abs_time);
1500         }
1501 #endif
1502 #ifdef BOOST_THREAD_USES_CHRONO
1503         template <class Rep, class Period>
1504         future_status
wait_for(const chrono::duration<Rep,Period> & rel_time) const1505         wait_for(const chrono::duration<Rep, Period>& rel_time) const
1506         {
1507           return wait_until(chrono::steady_clock::now() + rel_time);
1508 
1509         }
1510         template <class Clock, class Duration>
1511         future_status
wait_until(const chrono::time_point<Clock,Duration> & abs_time) const1512         wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
1513         {
1514           if(!future_)
1515           {
1516               boost::throw_exception(future_uninitialized());
1517           }
1518           return future_->wait_until(abs_time);
1519         }
1520 #endif
1521 
1522       };
1523 
1524     } // detail
1525     BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END
1526 
1527     namespace detail
1528     {
1529 #if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005
1530         template <class Rp, class Fp>
1531         BOOST_THREAD_FUTURE<Rp>
1532         make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1533 
1534         template <class Rp, class Fp>
1535         BOOST_THREAD_FUTURE<Rp>
1536         make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1537 #endif // #if (!defined _MSC_VER || _MSC_VER >= 1400)
1538 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1539         template<typename F, typename Rp, typename Fp>
1540         struct future_deferred_continuation_shared_state;
1541         template<typename F, typename Rp, typename Fp>
1542         struct future_async_continuation_shared_state;
1543 
1544         template <class F, class Rp, class Fp>
1545         BOOST_THREAD_FUTURE<Rp>
1546         make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1547 
1548         template <class F, class Rp, class Fp>
1549         BOOST_THREAD_FUTURE<Rp>
1550         make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1551 
1552         template <class F, class Rp, class Fp>
1553         BOOST_THREAD_FUTURE<Rp>
1554         make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1555 
1556         template<typename F, typename Rp, typename Fp>
1557         BOOST_THREAD_FUTURE<Rp>
1558         make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1559 
1560         template<typename F, typename Rp, typename Fp>
1561         BOOST_THREAD_FUTURE<Rp>
1562         make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1563 
1564         template<typename F, typename Rp, typename Fp>
1565         BOOST_THREAD_FUTURE<Rp>
1566         make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1567 
1568 
1569   #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1570         template<typename Ex, typename F, typename Rp, typename Fp>
1571         BOOST_THREAD_FUTURE<Rp>
1572         make_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1573 
1574         template<typename Ex, typename F, typename Rp, typename Fp>
1575         BOOST_THREAD_FUTURE<Rp>
1576         make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1577 
1578         template <class Rp, class Fp, class Executor>
1579         BOOST_THREAD_FUTURE<Rp>
1580         make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1581   #endif
1582 #endif
1583 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1584         template<typename F, typename Rp>
1585         struct future_unwrap_shared_state;
1586         template <class F, class Rp>
1587         inline BOOST_THREAD_FUTURE<Rp>
1588         make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1589 #endif
1590     }
1591 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1592       template< typename InputIterator>
1593       typename boost::disable_if<is_future_type<InputIterator>,
1594         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1595       >::type
1596       when_all(InputIterator first, InputIterator last);
1597 
1598       inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1599 
1600     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1601       template< typename T0, typename ...T>
1602       BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1603       when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1604     #endif
1605 
1606       template< typename InputIterator>
1607       typename boost::disable_if<is_future_type<InputIterator>,
1608         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1609       >::type
1610       when_any(InputIterator first, InputIterator last);
1611 
1612       inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1613 
1614     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1615       template< typename T0, typename ...T>
1616       BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1617       when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1618     #endif
1619 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1620 
1621 
1622     template <typename R>
1623     class BOOST_THREAD_FUTURE : public detail::basic_future<R>
1624     {
1625     private:
1626         typedef detail::basic_future<R> base_type;
1627         typedef typename base_type::future_ptr future_ptr;
1628 
1629         friend class shared_future<R>;
1630         friend class promise<R>;
1631 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1632         template <typename, typename, typename>
1633         friend struct detail::future_async_continuation_shared_state;
1634         template <typename, typename, typename>
1635         friend struct detail::future_deferred_continuation_shared_state;
1636 
1637         template <class F, class Rp, class Fp>
1638         friend BOOST_THREAD_FUTURE<Rp>
1639         detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1640 
1641         template <class F, class Rp, class Fp>
1642         friend BOOST_THREAD_FUTURE<Rp>
1643         detail::make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1644 
1645         template <class F, class Rp, class Fp>
1646         friend BOOST_THREAD_FUTURE<Rp>
1647         detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1648 
1649         template<typename F, typename Rp, typename Fp>
1650         friend BOOST_THREAD_FUTURE<Rp>
1651         detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1652 
1653         template<typename F, typename Rp, typename Fp>
1654         friend BOOST_THREAD_FUTURE<Rp>
1655         detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1656 
1657         template<typename F, typename Rp, typename Fp>
1658         friend BOOST_THREAD_FUTURE<Rp>
1659         detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1660 
1661   #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1662         template<typename Ex, typename F, typename Rp, typename Fp>
1663         friend BOOST_THREAD_FUTURE<Rp>
1664         detail::make_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1665 
1666         template<typename Ex, typename F, typename Rp, typename Fp>
1667         friend BOOST_THREAD_FUTURE<Rp>
1668         detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1669 
1670         template <class Rp, class Fp, class Executor>
1671         friend BOOST_THREAD_FUTURE<Rp>
1672         detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1673   #endif
1674 #endif
1675 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1676         template<typename F, typename Rp>
1677         friend struct detail::future_unwrap_shared_state;
1678         template <class F, class Rp>
1679         friend BOOST_THREAD_FUTURE<Rp>
1680         detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1681 #endif
1682 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1683       template< typename InputIterator>
1684       friend typename boost::disable_if<is_future_type<InputIterator>,
1685         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1686       >::type
1687       when_all(InputIterator first, InputIterator last);
1688 
1689       //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1690 
1691     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1692       template< typename T0, typename ...T>
1693       friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1694       when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1695     #endif
1696 
1697       template< typename InputIterator>
1698       friend typename boost::disable_if<is_future_type<InputIterator>,
1699         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1700       >::type
1701       when_any(InputIterator first, InputIterator last);
1702 
1703       //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1704 
1705     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1706       template< typename T0, typename ...T>
1707       friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1708       when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1709     #endif
1710 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1711 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1712         template <class> friend class packaged_task; // todo check if this works in windows
1713 #else
1714         friend class packaged_task<R>;
1715 #endif
1716         friend class detail::future_waiter;
1717 
1718         template <class Rp, class Fp>
1719         friend BOOST_THREAD_FUTURE<Rp>
1720         detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1721 
1722         template <class Rp, class Fp>
1723         friend BOOST_THREAD_FUTURE<Rp>
1724         detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1725 
1726         typedef typename base_type::move_dest_type move_dest_type;
1727 
BOOST_THREAD_FUTURE(future_ptr a_future)1728         BOOST_THREAD_FUTURE(future_ptr a_future):
1729           base_type(a_future)
1730         {
1731         }
1732 
1733     public:
1734         BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1735         typedef future_state::state state;
1736         typedef R value_type; // EXTENSION
1737 
BOOST_THREAD_FUTURE()1738         BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1739         //BOOST_CONSTEXPR
BOOST_THREAD_FUTURE(exceptional_ptr const & ex)1740         BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1741             base_type(ex) {}
1742 
~BOOST_THREAD_FUTURE()1743         ~BOOST_THREAD_FUTURE() {
1744         }
1745 
BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF (BOOST_THREAD_FUTURE)other)1746         BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1747         base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1748         {
1749         }
1750 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1751         inline explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
1752 #endif
1753 
BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF (shared_future<R>)other)1754         explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(shared_future<R>) other) :
1755         base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1756         {}
1757 
operator =(BOOST_THREAD_RV_REF (BOOST_THREAD_FUTURE)other)1758         BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
1759         {
1760             this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1761             return *this;
1762         }
1763 
share()1764         shared_future<R> share()
1765         {
1766           return shared_future<R>(::boost::move(*this));
1767         }
1768 
swap(BOOST_THREAD_FUTURE & other)1769         void swap(BOOST_THREAD_FUTURE& other)
1770         {
1771             static_cast<base_type*>(this)->swap(other);
1772         }
1773 
1774         // todo this function must be private and friendship provided to the internal users.
set_async()1775         void set_async()
1776         {
1777           this->future_->set_async();
1778         }
1779         // todo this function must be private and friendship provided to the internal users.
set_deferred()1780         void set_deferred()
1781         {
1782           this->future_->set_deferred();
1783         }
run_if_is_deferred()1784         bool run_if_is_deferred() {
1785           return this->future_->run_if_is_deferred();
1786         }
run_if_is_deferred_or_ready()1787         bool run_if_is_deferred_or_ready() {
1788           return this->future_->run_if_is_deferred_or_ready();
1789         }
1790         // retrieving the value
get()1791         move_dest_type get()
1792         {
1793             if (this->future_.get() == 0)
1794             {
1795                 boost::throw_exception(future_uninitialized());
1796             }
1797             unique_lock<boost::mutex> lk(this->future_->mutex);
1798             if (! this->future_->valid(lk))
1799             {
1800                 boost::throw_exception(future_uninitialized());
1801             }
1802 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1803             this->future_->invalidate(lk);
1804 #endif
1805             return this->future_->get(lk);
1806         }
1807 
1808         template <typename R2>
1809         typename boost::disable_if< is_void<R2>, move_dest_type>::type
get_or(BOOST_THREAD_RV_REF (R2)v)1810         get_or(BOOST_THREAD_RV_REF(R2) v)
1811         {
1812 
1813             if (this->future_.get() == 0)
1814             {
1815                 boost::throw_exception(future_uninitialized());
1816             }
1817             unique_lock<boost::mutex> lk(this->future_->mutex);
1818             if (! this->future_->valid(lk))
1819             {
1820                 boost::throw_exception(future_uninitialized());
1821             }
1822             this->future_->wait(lk, false);
1823 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1824             this->future_->invalidate(lk);
1825 #endif
1826 
1827             if (this->future_->has_value(lk)) {
1828               return this->future_->get(lk);
1829             }
1830             else {
1831               return boost::move(v);
1832             }
1833         }
1834 
1835         template <typename R2>
1836         typename boost::disable_if< is_void<R2>, move_dest_type>::type
get_or(R2 const & v)1837         get_or(R2 const& v)  // EXTENSION
1838         {
1839             if (this->future_.get() == 0)
1840             {
1841                 boost::throw_exception(future_uninitialized());
1842             }
1843             unique_lock<boost::mutex> lk(this->future_->mutex);
1844             if (! this->future_->valid(lk))
1845             {
1846                 boost::throw_exception(future_uninitialized());
1847             }
1848             this->future_->wait(lk, false);
1849 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1850             this->future_->invalidate(lk);
1851 #endif
1852             if (this->future_->has_value(lk)) {
1853               return this->future_->get(lk);
1854             }
1855             else {
1856               return v;
1857             }
1858         }
1859 
1860 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1861         template<typename F>
1862         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1863         then(BOOST_THREAD_FWD_REF(F) func);  // EXTENSION
1864         template<typename F>
1865         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1866         then(launch policy, BOOST_THREAD_FWD_REF(F) func);  // EXTENSION
1867   #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1868         template<typename Ex, typename F>
1869         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1870         then(Ex& ex, BOOST_THREAD_FWD_REF(F) func);  // EXTENSION
1871   #endif
1872 
1873         template <typename R2>
1874         inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1875         fallback_to(BOOST_THREAD_RV_REF(R2) v);  // EXTENSION
1876         template <typename R2>
1877         inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1878         fallback_to(R2 const& v);  // EXTENSION
1879 
1880 #endif
1881 
1882     };
1883 
1884     BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
1885 
1886         template <typename R2>
1887         class BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> > : public detail::basic_future<BOOST_THREAD_FUTURE<R2> >
1888         {
1889           typedef BOOST_THREAD_FUTURE<R2> R;
1890 
1891         private:
1892             typedef detail::basic_future<R> base_type;
1893             typedef typename base_type::future_ptr future_ptr;
1894 
1895             friend class shared_future<R>;
1896             friend class promise<R>;
1897 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1898             template <typename, typename, typename>
1899             friend struct detail::future_async_continuation_shared_state;
1900             template <typename, typename, typename>
1901             friend struct detail::future_deferred_continuation_shared_state;
1902 
1903             template <class F, class Rp, class Fp>
1904             friend BOOST_THREAD_FUTURE<Rp>
1905             detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1906 
1907             template <class F, class Rp, class Fp>
1908             friend BOOST_THREAD_FUTURE<Rp>
1909             detail::make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1910 
1911             template <class F, class Rp, class Fp>
1912             friend BOOST_THREAD_FUTURE<Rp>
1913             detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1914 
1915             template<typename F, typename Rp, typename Fp>
1916             friend BOOST_THREAD_FUTURE<Rp>
1917             detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1918 
1919             template<typename F, typename Rp, typename Fp>
1920             friend BOOST_THREAD_FUTURE<Rp>
1921             detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1922 
1923             template<typename F, typename Rp, typename Fp>
1924             friend BOOST_THREAD_FUTURE<Rp>
1925             detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1926 
1927       #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1928             template<typename Ex, typename F, typename Rp, typename Fp>
1929             friend BOOST_THREAD_FUTURE<Rp>
1930             detail::make_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1931 
1932             template<typename Ex, typename F, typename Rp, typename Fp>
1933             friend BOOST_THREAD_FUTURE<Rp>
1934             detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1935 
1936             template <class Rp, class Fp, class Executor>
1937             friend BOOST_THREAD_FUTURE<Rp>
1938             detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1939       #endif
1940 
1941 #endif
1942 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1943             template<typename F, typename Rp>
1944             friend struct detail::future_unwrap_shared_state;
1945         template <class F, class Rp>
1946         friend BOOST_THREAD_FUTURE<Rp>
1947         detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1948 #endif
1949 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1950       template< typename InputIterator>
1951       friend typename boost::disable_if<is_future_type<InputIterator>,
1952         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1953       >::type
1954       when_all(InputIterator first, InputIterator last);
1955 
1956       friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1957 
1958     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1959       template< typename T0, typename ...T>
1960       friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1961       when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1962     #endif
1963 
1964       template< typename InputIterator>
1965       friend typename boost::disable_if<is_future_type<InputIterator>,
1966         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1967       >::type
1968       when_any(InputIterator first, InputIterator last);
1969 
1970       friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1971 
1972     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1973       template< typename T0, typename ...T>
1974       friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1975       when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1976     #endif
1977 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1978 
1979     #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1980             template <class> friend class packaged_task; // todo check if this works in windows
1981     #else
1982             friend class packaged_task<R>;
1983     #endif
1984             friend class detail::future_waiter;
1985 
1986             template <class Rp, class Fp>
1987             friend BOOST_THREAD_FUTURE<Rp>
1988             detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1989 
1990             template <class Rp, class Fp>
1991             friend BOOST_THREAD_FUTURE<Rp>
1992             detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1993 
1994             typedef typename base_type::move_dest_type move_dest_type;
1995 
BOOST_THREAD_FUTURE(future_ptr a_future)1996             BOOST_THREAD_FUTURE(future_ptr a_future):
1997               base_type(a_future)
1998             {
1999             }
2000         public:
2001 
2002             BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
2003             typedef future_state::state state;
2004             typedef R value_type; // EXTENSION
2005 
BOOST_THREAD_FUTURE()2006             BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
2007             //BOOST_CONSTEXPR
BOOST_THREAD_FUTURE(exceptional_ptr const & ex)2008             BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
2009                 base_type(ex) {}
2010 
~BOOST_THREAD_FUTURE()2011             ~BOOST_THREAD_FUTURE() {
2012             }
2013 
BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF (BOOST_THREAD_FUTURE)other)2014             BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
2015             base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2016             {
2017             }
2018 
operator =(BOOST_THREAD_RV_REF (BOOST_THREAD_FUTURE)other)2019             BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
2020             {
2021                 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2022                 return *this;
2023             }
2024 
share()2025             shared_future<R> share()
2026             {
2027               return shared_future<R>(::boost::move(*this));
2028             }
2029 
swap(BOOST_THREAD_FUTURE & other)2030             void swap(BOOST_THREAD_FUTURE& other)
2031             {
2032                 static_cast<base_type*>(this)->swap(other);
2033             }
2034 
2035             // todo this function must be private and friendship provided to the internal users.
set_async()2036             void set_async()
2037             {
2038               this->future_->set_async();
2039             }
2040             // todo this function must be private and friendship provided to the internal users.
set_deferred()2041             void set_deferred()
2042             {
2043               this->future_->set_deferred();
2044             }
run_if_is_deferred()2045             bool run_if_is_deferred() {
2046               return this->future_->run_if_is_deferred();
2047             }
run_if_is_deferred_or_ready()2048             bool run_if_is_deferred_or_ready() {
2049               return this->future_->run_if_is_deferred_or_ready();
2050             }
2051             // retrieving the value
get()2052             move_dest_type get()
2053             {
2054                 if (this->future_.get() == 0)
2055                 {
2056                     boost::throw_exception(future_uninitialized());
2057                 }
2058                 unique_lock<boost::mutex> lk(this->future_->mutex);
2059                 if (! this->future_->valid(lk))
2060                 {
2061                     boost::throw_exception(future_uninitialized());
2062                 }
2063     #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
2064                 this->future_->invalidate(lk);
2065     #endif
2066                 return this->future_->get(lk);
2067             }
get_or(BOOST_THREAD_RV_REF (R)v)2068             move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
2069             {
2070                 if (this->future_.get() == 0)
2071                 {
2072                     boost::throw_exception(future_uninitialized());
2073                 }
2074                 unique_lock<boost::mutex> lk(this->future_->mutex);
2075                 if (! this->future_->valid(lk))
2076                 {
2077                     boost::throw_exception(future_uninitialized());
2078                 }
2079                 this->future_->wait(lk, false);
2080     #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
2081                 this->future_->invalidate(lk);
2082     #endif
2083                 if (this->future_->has_value(lk)) return this->future_->get(lk);
2084                 else return boost::move(v);
2085             }
2086 
get_or(R const & v)2087             move_dest_type get_or(R const& v) // EXTENSION
2088             {
2089                 if (this->future_.get() == 0)
2090                 {
2091                     boost::throw_exception(future_uninitialized());
2092                 }
2093                 unique_lock<boost::mutex> lk(this->future_->mutex);
2094                 if (! this->future_->valid(lk))
2095                 {
2096                     boost::throw_exception(future_uninitialized());
2097                 }
2098                 this->future_->wait(lk, false);
2099     #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
2100                 this->future_->invalidate(lk);
2101     #endif
2102                 if (this->future_->has_value(lk)) return this->future_->get(lk);
2103                 else return v;
2104             }
2105 
2106 
2107     #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2108             template<typename F>
2109             inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2110             then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2111             template<typename F>
2112             inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2113             then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2114       #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2115             template<typename Ex, typename F>
2116             inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2117             then(Ex &ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2118       #endif
2119     #endif
2120 
2121     #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
2122             inline
2123             BOOST_THREAD_FUTURE<R2>
2124             unwrap(); // EXTENSION
2125     #endif
2126 
2127   };
2128 
2129     template <typename R>
2130     class shared_future : public detail::basic_future<R>
2131     {
2132         typedef detail::basic_future<R> base_type;
2133         typedef typename base_type::future_ptr future_ptr;
2134 
2135         friend class detail::future_waiter;
2136         friend class promise<R>;
2137 
2138 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2139         template <typename, typename, typename>
2140         friend struct detail::future_async_continuation_shared_state;
2141         template <typename, typename, typename>
2142         friend struct detail::future_deferred_continuation_shared_state;
2143 
2144         template <class F, class Rp, class Fp>
2145         friend BOOST_THREAD_FUTURE<Rp>
2146         detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
2147 
2148         template <class F, class Rp, class Fp>
2149         friend BOOST_THREAD_FUTURE<Rp>
2150         detail::make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
2151 
2152         template <class F, class Rp, class Fp>
2153         friend BOOST_THREAD_FUTURE<Rp>
2154         detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
2155 #endif
2156 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2157         template <class> friend class packaged_task;// todo check if this works in windows
2158 #else
2159         friend class packaged_task<R>;
2160 #endif
shared_future(future_ptr a_future)2161         shared_future(future_ptr a_future):
2162           base_type(a_future)
2163         {}
2164 
2165     public:
2166         BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_future)
2167         typedef R value_type; // EXTENSION
2168 
shared_future(shared_future const & other)2169         shared_future(shared_future const& other):
2170         base_type(other.future_)
2171         {}
2172 
2173         typedef future_state::state state;
2174 
shared_future()2175         BOOST_CONSTEXPR shared_future()
2176         {}
2177         //BOOST_CONSTEXPR
shared_future(exceptional_ptr const & ex)2178         shared_future(exceptional_ptr const& ex):
2179             base_type(ex) {}
~shared_future()2180         ~shared_future()
2181         {}
2182 
operator =(BOOST_THREAD_COPY_ASSIGN_REF (shared_future)other)2183         shared_future& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_future) other)
2184         {
2185             this->future_ = other.future_;
2186             return *this;
2187         }
2188 
shared_future(BOOST_THREAD_RV_REF (shared_future)other)2189         shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
2190         base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2191         {
2192         }
shared_future(BOOST_THREAD_RV_REF (BOOST_THREAD_FUTURE<R>)other)2193         shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT :
2194         base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2195         {
2196         }
2197 
operator =(BOOST_THREAD_RV_REF (shared_future)other)2198         shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
2199         {
2200             base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2201             return *this;
2202         }
operator =(BOOST_THREAD_RV_REF (BOOST_THREAD_FUTURE<R>)other)2203         shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT
2204         {
2205             base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2206             return *this;
2207         }
2208 
swap(shared_future & other)2209         void swap(shared_future& other) BOOST_NOEXCEPT
2210         {
2211             static_cast<base_type*>(this)->swap(other);
2212         }
run_if_is_deferred()2213         bool run_if_is_deferred() {
2214           return this->future_->run_if_is_deferred();
2215         }
run_if_is_deferred_or_ready()2216         bool run_if_is_deferred_or_ready() {
2217           return this->future_->run_if_is_deferred_or_ready();
2218         }
2219         // retrieving the value
get() const2220         typename detail::shared_state<R>::shared_future_get_result_type get() const
2221         {
2222             if(!this->future_)
2223             {
2224                 boost::throw_exception(future_uninitialized());
2225             }
2226             return this->future_->get_sh();
2227         }
2228 
2229         template <typename R2>
2230         typename boost::disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type
get_or(BOOST_THREAD_RV_REF (R2)v) const2231         get_or(BOOST_THREAD_RV_REF(R2) v)  const // EXTENSION
2232         {
2233             if(!this->future_)
2234             {
2235                 boost::throw_exception(future_uninitialized());
2236             }
2237             this->future_->wait();
2238             if (this->future_->has_value()) return this->future_->get_sh();
2239             else return boost::move(v);
2240         }
2241 
2242 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2243         template<typename F>
2244         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2245         then(BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2246         template<typename F>
2247         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2248         then(launch policy, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2249   #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2250         template<typename Ex, typename F>
2251         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2252         then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2253   #endif
2254 #endif
2255 
2256     };
2257 
2258     BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
2259 
2260     template <typename R>
2261     class promise
2262     {
2263         typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
2264 
2265         typedef typename detail::shared_state<R>::source_reference_type source_reference_type;
2266         typedef typename detail::shared_state<R>::rvalue_source_type rvalue_source_type;
2267         typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
2268         typedef typename detail::shared_state<R>::shared_future_get_result_type shared_future_get_result_type;
2269 
2270         future_ptr future_;
2271         bool future_obtained;
2272 
lazy_init()2273         void lazy_init()
2274         {
2275 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2276 #include <boost/thread/detail/atomic_undef_macros.hpp>
2277           if(!atomic_load(&future_))
2278             {
2279                 future_ptr blank;
2280                 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R>));
2281             }
2282 #include <boost/thread/detail/atomic_redef_macros.hpp>
2283 #endif
2284         }
2285 
2286     public:
2287         BOOST_THREAD_MOVABLE_ONLY(promise)
2288 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2289         template <class Allocator>
promise(boost::allocator_arg_t,Allocator a)2290         promise(boost::allocator_arg_t, Allocator a)
2291         {
2292           typedef typename Allocator::template rebind<detail::shared_state<R> >::other A2;
2293           A2 a2(a);
2294           typedef thread_detail::allocator_destructor<A2> D;
2295 
2296           future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R>(), D(a2, 1) );
2297           future_obtained = false;
2298         }
2299 #endif
promise()2300         promise():
2301 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2302             future_(),
2303 #else
2304             future_(new detail::shared_state<R>()),
2305 #endif
2306             future_obtained(false)
2307         {}
2308 
~promise()2309         ~promise()
2310         {
2311             if(future_)
2312             {
2313                 boost::unique_lock<boost::mutex> lock(future_->mutex);
2314 
2315                 if(!future_->done && !future_->is_constructed)
2316                 {
2317                     future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2318                 }
2319             }
2320         }
2321 
2322         // Assignment
promise(BOOST_THREAD_RV_REF (promise)rhs)2323         promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2324             future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2325         {
2326             BOOST_THREAD_RV(rhs).future_.reset();
2327             BOOST_THREAD_RV(rhs).future_obtained=false;
2328         }
operator =(BOOST_THREAD_RV_REF (promise)rhs)2329         promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2330         {
2331             future_=BOOST_THREAD_RV(rhs).future_;
2332             future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2333             BOOST_THREAD_RV(rhs).future_.reset();
2334             BOOST_THREAD_RV(rhs).future_obtained=false;
2335             return *this;
2336         }
2337 
swap(promise & other)2338         void swap(promise& other)
2339         {
2340             future_.swap(other.future_);
2341             std::swap(future_obtained,other.future_obtained);
2342         }
2343 
2344 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
set_executor(executor_ptr_type aex)2345         void set_executor(executor_ptr_type aex)
2346         {
2347           lazy_init();
2348           if (future_.get()==0)
2349           {
2350               boost::throw_exception(promise_moved());
2351           }
2352           boost::lock_guard<boost::mutex> lk(future_->mutex);
2353           future_->set_executor_policy(aex, lk);
2354         }
2355 #endif
2356         // Result retrieval
get_future()2357         BOOST_THREAD_FUTURE<R> get_future()
2358         {
2359             lazy_init();
2360             if (future_.get()==0)
2361             {
2362                 boost::throw_exception(promise_moved());
2363             }
2364             if (future_obtained)
2365             {
2366                 boost::throw_exception(future_already_retrieved());
2367             }
2368             future_obtained=true;
2369             return BOOST_THREAD_FUTURE<R>(future_);
2370         }
2371 
2372 #if defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2373         template <class TR>
2374         typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
set_value(TR const & r)2375             set_value(TR const &  r)
2376         {
2377             lazy_init();
2378             boost::unique_lock<boost::mutex> lock(future_->mutex);
2379             if(future_->done)
2380             {
2381                 boost::throw_exception(promise_already_satisfied());
2382             }
2383             future_->mark_finished_with_result_internal(r, lock);
2384         }
2385 #else
set_value(source_reference_type r)2386         void set_value(source_reference_type r)
2387         {
2388             lazy_init();
2389             boost::unique_lock<boost::mutex> lock(future_->mutex);
2390             if(future_->done)
2391             {
2392                 boost::throw_exception(promise_already_satisfied());
2393             }
2394             future_->mark_finished_with_result_internal(r, lock);
2395         }
2396 #endif
2397 
set_value(rvalue_source_type r)2398         void set_value(rvalue_source_type r)
2399         {
2400             lazy_init();
2401             boost::unique_lock<boost::mutex> lock(future_->mutex);
2402             if(future_->done)
2403             {
2404                 boost::throw_exception(promise_already_satisfied());
2405             }
2406 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2407             future_->mark_finished_with_result_internal(boost::move(r), lock);
2408 #else
2409             future_->mark_finished_with_result_internal(static_cast<rvalue_source_type>(r), lock);
2410 #endif
2411         }
2412 
2413 #if defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2414         template <class TR>
2415         typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
set_value_deferred(TR const & r)2416             set_value_deferred(TR const &  r)
2417         {
2418             lazy_init();
2419             if (future_.get()==0)
2420             {
2421                 boost::throw_exception(promise_moved());
2422             }
2423             future_->set_value_deferred(r);
2424         }
2425 #else
set_value_deferred(source_reference_type r)2426         void set_value_deferred(source_reference_type r)
2427         {
2428             lazy_init();
2429             if (future_.get()==0)
2430             {
2431                 boost::throw_exception(promise_moved());
2432             }
2433             future_->set_value_deferred(r);
2434         }
2435 #endif
2436 
set_value_deferred(rvalue_source_type r)2437         void set_value_deferred(rvalue_source_type r)
2438         {
2439             lazy_init();
2440             if (future_.get()==0)
2441             {
2442                 boost::throw_exception(promise_moved());
2443             }
2444 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2445             future_->set_value_deferred(boost::move(r));
2446 #else
2447             future_->set_value_deferred(static_cast<rvalue_source_type>(r));
2448 #endif
2449         }
2450 
2451 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
2452         template <class ...Args>
emplace(BOOST_THREAD_FWD_REF (Args)...args)2453         void emplace(BOOST_THREAD_FWD_REF(Args) ...args)
2454         {
2455             lazy_init();
2456             boost::unique_lock<boost::mutex> lock(future_->mutex);
2457             if(future_->done)
2458             {
2459                 boost::throw_exception(promise_already_satisfied());
2460             }
2461             future_->mark_finished_with_result_internal(lock, boost::forward<Args>(args)...);
2462         }
2463 
2464 #endif
2465 
set_exception(boost::exception_ptr p)2466         void set_exception(boost::exception_ptr p)
2467         {
2468             lazy_init();
2469             boost::unique_lock<boost::mutex> lock(future_->mutex);
2470             if(future_->done)
2471             {
2472                 boost::throw_exception(promise_already_satisfied());
2473             }
2474             future_->mark_exceptional_finish_internal(p, lock);
2475         }
2476         template <typename E>
set_exception(E ex)2477         void set_exception(E ex)
2478         {
2479           set_exception(boost::copy_exception(ex));
2480         }
set_exception_deferred(boost::exception_ptr p)2481         void set_exception_deferred(boost::exception_ptr p)
2482         {
2483             lazy_init();
2484             if (future_.get()==0)
2485             {
2486                 boost::throw_exception(promise_moved());
2487             }
2488             future_->set_exception_deferred(p);
2489         }
2490         template <typename E>
set_exception_deferred(E ex)2491         void set_exception_deferred(E ex)
2492         {
2493           set_exception_deferred(boost::copy_exception(ex));
2494         }
2495 
2496         // setting the result with deferred notification
2497 #if defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2498         template <class TR>
set_value_at_thread_exit(TR const & r)2499         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)
2500         {
2501           if (future_.get()==0)
2502           {
2503               boost::throw_exception(promise_moved());
2504           }
2505           future_->set_value_at_thread_exit(r);
2506         }
2507 #else
set_value_at_thread_exit(source_reference_type r)2508         void set_value_at_thread_exit(source_reference_type r)
2509         {
2510           if (future_.get()==0)
2511           {
2512               boost::throw_exception(promise_moved());
2513           }
2514           future_->set_value_at_thread_exit(r);
2515         }
2516 #endif
set_value_at_thread_exit(BOOST_THREAD_RV_REF (R)r)2517         void set_value_at_thread_exit(BOOST_THREAD_RV_REF(R) r)
2518         {
2519           if (future_.get()==0)
2520           {
2521               boost::throw_exception(promise_moved());
2522           }
2523           future_->set_value_at_thread_exit(boost::move(r));
2524         }
set_exception_at_thread_exit(exception_ptr e)2525         void set_exception_at_thread_exit(exception_ptr e)
2526         {
2527           if (future_.get()==0)
2528           {
2529               boost::throw_exception(promise_moved());
2530           }
2531           future_->set_exception_at_thread_exit(e);
2532         }
2533         template <typename E>
set_exception_at_thread_exit(E ex)2534         void set_exception_at_thread_exit(E ex)
2535         {
2536           set_exception_at_thread_exit(boost::copy_exception(ex));
2537         }
2538 
2539         template<typename F>
set_wait_callback(F f)2540         void set_wait_callback(F f)
2541         {
2542             lazy_init();
2543             future_->set_wait_callback(f,this);
2544         }
notify_deferred()2545         void notify_deferred()
2546         {
2547             if (future_.get()==0)
2548             {
2549                 boost::throw_exception(promise_moved());
2550             }
2551             future_->notify_deferred();
2552         }
2553 
2554     };
2555 
2556     template <typename R>
2557     class promise<R&>
2558     {
2559         typedef boost::shared_ptr<detail::shared_state<R&> > future_ptr;
2560 
2561         future_ptr future_;
2562         bool future_obtained;
2563 
lazy_init()2564         void lazy_init()
2565         {
2566 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2567 #include <boost/thread/detail/atomic_undef_macros.hpp>
2568             if(!atomic_load(&future_))
2569             {
2570                 future_ptr blank;
2571                 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
2572             }
2573 #include <boost/thread/detail/atomic_redef_macros.hpp>
2574 #endif
2575         }
2576 
2577     public:
2578         BOOST_THREAD_MOVABLE_ONLY(promise)
2579 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2580         template <class Allocator>
promise(boost::allocator_arg_t,Allocator a)2581         promise(boost::allocator_arg_t, Allocator a)
2582         {
2583           typedef typename Allocator::template rebind<detail::shared_state<R&> >::other A2;
2584           A2 a2(a);
2585           typedef thread_detail::allocator_destructor<A2> D;
2586 
2587           future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R&>(), D(a2, 1) );
2588           future_obtained = false;
2589         }
2590 #endif
promise()2591         promise():
2592 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2593             future_(),
2594 #else
2595             future_(new detail::shared_state<R&>()),
2596 #endif
2597             future_obtained(false)
2598         {}
2599 
~promise()2600         ~promise()
2601         {
2602             if(future_)
2603             {
2604                 boost::unique_lock<boost::mutex> lock(future_->mutex);
2605 
2606                 if(!future_->done && !future_->is_constructed)
2607                 {
2608                     future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2609                 }
2610             }
2611         }
2612 
2613         // Assignment
promise(BOOST_THREAD_RV_REF (promise)rhs)2614         promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2615             future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2616         {
2617             BOOST_THREAD_RV(rhs).future_.reset();
2618             BOOST_THREAD_RV(rhs).future_obtained=false;
2619         }
operator =(BOOST_THREAD_RV_REF (promise)rhs)2620         promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2621         {
2622             future_=BOOST_THREAD_RV(rhs).future_;
2623             future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2624             BOOST_THREAD_RV(rhs).future_.reset();
2625             BOOST_THREAD_RV(rhs).future_obtained=false;
2626             return *this;
2627         }
2628 
swap(promise & other)2629         void swap(promise& other)
2630         {
2631             future_.swap(other.future_);
2632             std::swap(future_obtained,other.future_obtained);
2633         }
2634 
2635         // Result retrieval
get_future()2636         BOOST_THREAD_FUTURE<R&> get_future()
2637         {
2638             lazy_init();
2639             if (future_.get()==0)
2640             {
2641                 boost::throw_exception(promise_moved());
2642             }
2643             if (future_obtained)
2644             {
2645                 boost::throw_exception(future_already_retrieved());
2646             }
2647             future_obtained=true;
2648             return BOOST_THREAD_FUTURE<R&>(future_);
2649         }
2650 
set_value(R & r)2651         void set_value(R& r)
2652         {
2653             lazy_init();
2654             boost::unique_lock<boost::mutex> lock(future_->mutex);
2655             if(future_->done)
2656             {
2657                 boost::throw_exception(promise_already_satisfied());
2658             }
2659             future_->mark_finished_with_result_internal(r, lock);
2660         }
set_value_deferred(R & r)2661         void set_value_deferred(R& r)
2662         {
2663             lazy_init();
2664             if (future_.get()==0)
2665             {
2666                 boost::throw_exception(promise_already_satisfied());
2667             }
2668             future_->set_value_deferred(r);
2669         }
set_exception(boost::exception_ptr p)2670         void set_exception(boost::exception_ptr p)
2671         {
2672             lazy_init();
2673             boost::unique_lock<boost::mutex> lock(future_->mutex);
2674             if(future_->done)
2675             {
2676                 boost::throw_exception(promise_already_satisfied());
2677             }
2678             future_->mark_exceptional_finish_internal(p, lock);
2679         }
2680         template <typename E>
set_exception(E ex)2681         void set_exception(E ex)
2682         {
2683           set_exception(boost::copy_exception(ex));
2684         }
set_exception_deferred(boost::exception_ptr p)2685         void set_exception_deferred(boost::exception_ptr p)
2686         {
2687             lazy_init();
2688             if (future_.get()==0)
2689             {
2690                 boost::throw_exception(promise_moved());
2691             }
2692             future_->set_exception_deferred(p);
2693         }
2694         template <typename E>
set_exception_deferred(E ex)2695         void set_exception_deferred(E ex)
2696         {
2697           set_exception_deferred(boost::copy_exception(ex));
2698         }
2699         // setting the result with deferred notification
set_value_at_thread_exit(R & r)2700         void set_value_at_thread_exit(R& r)
2701         {
2702           if (future_.get()==0)
2703           {
2704               boost::throw_exception(promise_moved());
2705           }
2706           future_->set_value_at_thread_exit(r);
2707         }
2708 
set_exception_at_thread_exit(exception_ptr e)2709         void set_exception_at_thread_exit(exception_ptr e)
2710         {
2711           if (future_.get()==0)
2712           {
2713               boost::throw_exception(promise_moved());
2714           }
2715           future_->set_exception_at_thread_exit(e);
2716         }
2717         template <typename E>
set_exception_at_thread_exit(E ex)2718         void set_exception_at_thread_exit(E ex)
2719         {
2720           set_exception_at_thread_exit(boost::copy_exception(ex));
2721         }
2722 
2723         template<typename F>
set_wait_callback(F f)2724         void set_wait_callback(F f)
2725         {
2726             lazy_init();
2727             future_->set_wait_callback(f,this);
2728         }
notify_deferred()2729         void notify_deferred()
2730         {
2731             if (future_.get()==0)
2732             {
2733                 boost::throw_exception(promise_moved());
2734             }
2735             future_->notify_deferred();
2736         }
2737     };
2738 
2739     template <>
2740     class promise<void>
2741     {
2742         typedef boost::shared_ptr<detail::shared_state<void> > future_ptr;
2743 
2744         future_ptr future_;
2745         bool future_obtained;
2746 
lazy_init()2747         void lazy_init()
2748         {
2749 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2750             if(!atomic_load(&future_))
2751             {
2752                 future_ptr blank;
2753                 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<void>));
2754             }
2755 #endif
2756         }
2757     public:
2758         BOOST_THREAD_MOVABLE_ONLY(promise)
2759 
2760 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2761         template <class Allocator>
promise(boost::allocator_arg_t,Allocator a)2762         promise(boost::allocator_arg_t, Allocator a)
2763         {
2764           typedef typename Allocator::template rebind<detail::shared_state<void> >::other A2;
2765           A2 a2(a);
2766           typedef thread_detail::allocator_destructor<A2> D;
2767 
2768           future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<void>(), D(a2, 1) );
2769           future_obtained = false;
2770         }
2771 #endif
promise()2772         promise():
2773 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2774             future_(),
2775 #else
2776             future_(new detail::shared_state<void>),
2777 #endif
2778             future_obtained(false)
2779         {}
2780 
~promise()2781         ~promise()
2782         {
2783             if(future_)
2784             {
2785                 boost::unique_lock<boost::mutex> lock(future_->mutex);
2786 
2787                 if(!future_->done && !future_->is_constructed)
2788                 {
2789                     future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2790                 }
2791             }
2792         }
2793 
2794         // Assignment
promise(BOOST_THREAD_RV_REF (promise)rhs)2795         promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2796             future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2797         {
2798           // we need to release the future as shared_ptr doesn't implements move semantics
2799             BOOST_THREAD_RV(rhs).future_.reset();
2800             BOOST_THREAD_RV(rhs).future_obtained=false;
2801         }
2802 
operator =(BOOST_THREAD_RV_REF (promise)rhs)2803         promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2804         {
2805             future_=BOOST_THREAD_RV(rhs).future_;
2806             future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2807             BOOST_THREAD_RV(rhs).future_.reset();
2808             BOOST_THREAD_RV(rhs).future_obtained=false;
2809             return *this;
2810         }
2811 
swap(promise & other)2812         void swap(promise& other)
2813         {
2814             future_.swap(other.future_);
2815             std::swap(future_obtained,other.future_obtained);
2816         }
2817 
2818         // Result retrieval
get_future()2819         BOOST_THREAD_FUTURE<void> get_future()
2820         {
2821             lazy_init();
2822 
2823             if (future_.get()==0)
2824             {
2825                 boost::throw_exception(promise_moved());
2826             }
2827             if(future_obtained)
2828             {
2829                 boost::throw_exception(future_already_retrieved());
2830             }
2831             future_obtained=true;
2832             //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<void>(future_));
2833             return BOOST_THREAD_FUTURE<void>(future_);
2834         }
2835 
set_value()2836         void set_value()
2837         {
2838             lazy_init();
2839             boost::unique_lock<boost::mutex> lock(future_->mutex);
2840             if(future_->done)
2841             {
2842                 boost::throw_exception(promise_already_satisfied());
2843             }
2844             future_->mark_finished_with_result_internal(lock);
2845         }
set_value_deferred()2846         void set_value_deferred()
2847         {
2848             lazy_init();
2849             if (future_.get()==0)
2850             {
2851                 boost::throw_exception(promise_moved());
2852             }
2853             future_->set_value_deferred();
2854         }
2855 
set_exception(boost::exception_ptr p)2856         void set_exception(boost::exception_ptr p)
2857         {
2858             lazy_init();
2859             boost::unique_lock<boost::mutex> lock(future_->mutex);
2860             if(future_->done)
2861             {
2862                 boost::throw_exception(promise_already_satisfied());
2863             }
2864             future_->mark_exceptional_finish_internal(p,lock);
2865         }
2866         template <typename E>
set_exception(E ex)2867         void set_exception(E ex)
2868         {
2869           set_exception(boost::copy_exception(ex));
2870         }
set_exception_deferred(boost::exception_ptr p)2871         void set_exception_deferred(boost::exception_ptr p)
2872         {
2873             lazy_init();
2874             if (future_.get()==0)
2875             {
2876                 boost::throw_exception(promise_moved());
2877             }
2878             future_->set_exception_deferred(p);
2879         }
2880         template <typename E>
set_exception_deferred(E ex)2881         void set_exception_deferred(E ex)
2882         {
2883           set_exception_deferred(boost::copy_exception(ex));
2884         }
2885         // setting the result with deferred notification
set_value_at_thread_exit()2886         void set_value_at_thread_exit()
2887         {
2888           if (future_.get()==0)
2889           {
2890               boost::throw_exception(promise_moved());
2891           }
2892           future_->set_value_at_thread_exit();
2893         }
2894 
set_exception_at_thread_exit(exception_ptr e)2895         void set_exception_at_thread_exit(exception_ptr e)
2896         {
2897           if (future_.get()==0)
2898           {
2899               boost::throw_exception(promise_moved());
2900           }
2901           future_->set_exception_at_thread_exit(e);
2902         }
2903         template <typename E>
set_exception_at_thread_exit(E ex)2904         void set_exception_at_thread_exit(E ex)
2905         {
2906           set_exception_at_thread_exit(boost::copy_exception(ex));
2907         }
2908 
2909         template<typename F>
set_wait_callback(F f)2910         void set_wait_callback(F f)
2911         {
2912             lazy_init();
2913             future_->set_wait_callback(f,this);
2914         }
notify_deferred()2915         void notify_deferred()
2916         {
2917             if (future_.get()==0)
2918             {
2919                 boost::throw_exception(promise_moved());
2920             }
2921             future_->notify_deferred();
2922         }
2923     };
2924 }
2925 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2926 namespace boost { namespace container {
2927     template <class R, class Alloc>
2928     struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2929     {
2930     };
2931 }}
2932 #if ! defined  BOOST_NO_CXX11_ALLOCATOR
2933 namespace std {
2934     template <class R, class Alloc>
2935     struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2936     {
2937     };
2938 }
2939 #endif
2940 #endif
2941 
2942 namespace boost
2943 {
2944 
2945     BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
2946 
2947     namespace detail
2948     {
2949 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2950       template<typename R>
2951       struct task_base_shared_state;
2952 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2953       template<typename R, typename ...ArgTypes>
2954       struct task_base_shared_state<R(ArgTypes...)>:
2955 #else
2956       template<typename R>
2957       struct task_base_shared_state<R()>:
2958 #endif
2959 #else
2960       template<typename R>
2961       struct task_base_shared_state:
2962 #endif
2963             detail::shared_state<R>
2964         {
2965             bool started;
2966 
task_base_shared_stateboost::detail::task_base_shared_state2967             task_base_shared_state():
2968                 started(false)
2969             {}
2970 
resetboost::detail::task_base_shared_state2971             void reset()
2972             {
2973               // todo The packaged_task::reset must be as if an assignemnt froma new packaged_task with the same function
2974               // the reset function is an optimization that avoids reallocating a new task.
2975               started=false;
2976               this->validate();
2977             }
2978 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2979             virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
runboost::detail::task_base_shared_state2980             void run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2981 #else
2982             virtual void do_run()=0;
2983             void run()
2984 #endif
2985             {
2986                 {
2987                     boost::lock_guard<boost::mutex> lk(this->mutex);
2988                     if(started)
2989                     {
2990                         boost::throw_exception(task_already_started());
2991                     }
2992                     started=true;
2993                 }
2994 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2995                 do_run(boost::move(args)...);
2996 #else
2997                 do_run();
2998 #endif
2999             }
3000 
3001 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3002             virtual void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
applyboost::detail::task_base_shared_state3003             void apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3004 #else
3005             virtual void do_apply()=0;
3006             void apply()
3007 #endif
3008             {
3009                 {
3010                     boost::lock_guard<boost::mutex> lk(this->mutex);
3011                     if(started)
3012                     {
3013                         boost::throw_exception(task_already_started());
3014                     }
3015                     started=true;
3016                 }
3017 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3018                 do_apply(boost::move(args)...);
3019 #else
3020                 do_apply();
3021 #endif
3022             }
3023 
owner_destroyedboost::detail::task_base_shared_state3024             void owner_destroyed()
3025             {
3026                 boost::unique_lock<boost::mutex> lk(this->mutex);
3027                 if(!started)
3028                 {
3029                     started=true;
3030                     this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk);
3031                 }
3032             }
3033         };
3034 
3035 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3036         template<typename F, typename R>
3037         struct task_shared_state;
3038 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3039         template<typename F, typename R, typename ...ArgTypes>
3040         struct task_shared_state<F, R(ArgTypes...)>:
3041           task_base_shared_state<R(ArgTypes...)>
3042 #else
3043         template<typename F, typename R>
3044         struct task_shared_state<F, R()>:
3045           task_base_shared_state<R()>
3046 #endif
3047 #else
3048         template<typename F, typename R>
3049         struct task_shared_state:
3050             task_base_shared_state<R>
3051 #endif
3052         {
3053         private:
3054           task_shared_state(task_shared_state&);
3055         public:
3056             F f;
task_shared_stateboost::detail::task_shared_state3057             task_shared_state(F const& f_):
3058                 f(f_)
3059             {}
task_shared_stateboost::detail::task_shared_state3060             task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3061               f(boost::move(f_))
3062             {}
3063 
callableboost::detail::task_shared_state3064             F callable()
3065             {
3066               return boost::move(f);
3067             }
3068 
3069 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
do_applyboost::detail::task_shared_state3070             void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3071             {
3072                 try
3073                 {
3074                     this->set_value_at_thread_exit(f(boost::move(args)...));
3075                 }
3076 #else
3077             void do_apply()
3078             {
3079                 try
3080                 {
3081                     this->set_value_at_thread_exit(f());
3082                 }
3083 #endif
3084                 catch(...)
3085                 {
3086                     this->set_exception_at_thread_exit(current_exception());
3087                 }
3088             }
3089 
3090 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3091             void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3092             {
3093                 try
3094                 {
3095                     this->mark_finished_with_result(f(boost::move(args)...));
3096                 }
3097 #else
3098             void do_run()
3099             {
3100                 try
3101                 {
3102 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
3103                   R res((f()));
3104                   this->mark_finished_with_result(boost::move(res));
3105 #else
3106                   this->mark_finished_with_result(f());
3107 #endif
3108                   }
3109 #endif
3110                 catch(...)
3111                 {
3112                     this->mark_exceptional_finish();
3113                 }
3114             }
3115         };
3116 
3117 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3118 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3119         template<typename F, typename R, typename ...ArgTypes>
3120         struct task_shared_state<F, R&(ArgTypes...)>:
3121           task_base_shared_state<R&(ArgTypes...)>
3122 #else
3123         template<typename F, typename R>
3124         struct task_shared_state<F, R&()>:
3125           task_base_shared_state<R&()>
3126 #endif
3127 #else
3128         template<typename F, typename R>
3129         struct task_shared_state<F,R&>:
3130             task_base_shared_state<R&>
3131 #endif
3132         {
3133         private:
3134           task_shared_state(task_shared_state&);
3135         public:
3136             F f;
3137             task_shared_state(F const& f_):
3138                 f(f_)
3139             {}
3140             task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3141                 f(boost::move(f_))
3142             {}
3143 
3144             F callable()
3145             {
3146               return f;
3147             }
3148 
3149 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3150             void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3151             {
3152                 try
3153                 {
3154                     this->set_value_at_thread_exit(f(boost::move(args)...));
3155                 }
3156 #else
3157             void do_apply()
3158             {
3159                 try
3160                 {
3161                     this->set_value_at_thread_exit(f());
3162                 }
3163 #endif
3164                 catch(...)
3165                 {
3166                     this->set_exception_at_thread_exit(current_exception());
3167                 }
3168             }
3169 
3170 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3171             void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3172             {
3173                 try
3174                 {
3175                     this->mark_finished_with_result(f(boost::move(args)...));
3176                 }
3177 #else
3178             void do_run()
3179             {
3180                 try
3181                 {
3182                   R& res((f()));
3183                   this->mark_finished_with_result(res);
3184                 }
3185 #endif
3186                 catch(...)
3187                 {
3188                     this->mark_exceptional_finish();
3189                 }
3190             }
3191         };
3192 
3193 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
3194 
3195 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3196 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3197         template<typename R, typename ...ArgTypes>
3198         struct task_shared_state<R (*)(ArgTypes...), R(ArgTypes...)>:
3199           task_base_shared_state<R(ArgTypes...)>
3200 #else
3201         template<typename R>
3202         struct task_shared_state<R (*)(), R()>:
3203           task_base_shared_state<R()>
3204 #endif
3205 #else
3206         template<typename R>
3207         struct task_shared_state<R (*)(), R> :
3208            task_base_shared_state<R>
3209 #endif
3210             {
3211             private:
3212               task_shared_state(task_shared_state&);
3213 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3214               typedef R (*CallableType)(ArgTypes ... );
3215 #else
3216               typedef R (*CallableType)();
3217 #endif
3218             public:
3219                 CallableType f;
3220                 task_shared_state(CallableType f_):
3221                     f(f_)
3222                 {}
3223 
3224                 CallableType callable()
3225                 {
3226                   return f;
3227                 }
3228 
3229 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3230                 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3231                 {
3232                     try
3233                     {
3234                         this->set_value_at_thread_exit(f(boost::move(args)...));
3235                     }
3236 #else
3237                 void do_apply()
3238                 {
3239                     try
3240                     {
3241                         R r((f()));
3242                         this->set_value_at_thread_exit(boost::move(r));
3243                     }
3244 #endif
3245                     catch(...)
3246                     {
3247                         this->set_exception_at_thread_exit(current_exception());
3248                     }
3249                 }
3250 
3251 
3252 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3253                 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3254                 {
3255                     try
3256                     {
3257                         this->mark_finished_with_result(f(boost::move(args)...));
3258                     }
3259 #else
3260                 void do_run()
3261                 {
3262                     try
3263                     {
3264                         R res((f()));
3265                         this->mark_finished_with_result(boost::move(res));
3266                     }
3267 #endif
3268                     catch(...)
3269                     {
3270                         this->mark_exceptional_finish();
3271                     }
3272                 }
3273             };
3274 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3275 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3276         template<typename R, typename ...ArgTypes>
3277         struct task_shared_state<R& (*)(ArgTypes...), R&(ArgTypes...)>:
3278           task_base_shared_state<R&(ArgTypes...)>
3279 #else
3280         template<typename R>
3281         struct task_shared_state<R& (*)(), R&()>:
3282           task_base_shared_state<R&()>
3283 #endif
3284 #else
3285         template<typename R>
3286         struct task_shared_state<R& (*)(), R&> :
3287            task_base_shared_state<R&>
3288 #endif
3289             {
3290             private:
3291               task_shared_state(task_shared_state&);
3292             public:
3293 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3294                 typedef R& (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes) ... );
3295 #else
3296                 typedef R& (*CallableType)();
3297 #endif
3298                 CallableType f;
3299                 task_shared_state(CallableType f_):
3300                     f(f_)
3301                 {}
3302 
3303                 CallableType callable()
3304                 {
3305                   return boost::move(f);
3306                 }
3307 
3308 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3309                 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3310                 {
3311                     try
3312                     {
3313                         this->set_value_at_thread_exit(f(boost::move(args)...));
3314                     }
3315 #else
3316                 void do_apply()
3317                 {
3318                     try
3319                     {
3320                       this->set_value_at_thread_exit(f());
3321                     }
3322 #endif
3323                     catch(...)
3324                     {
3325                         this->set_exception_at_thread_exit(current_exception());
3326                     }
3327                 }
3328 
3329 
3330 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3331                 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3332                 {
3333                     try
3334                     {
3335                         this->mark_finished_with_result(f(boost::move(args)...));
3336                     }
3337 #else
3338                 void do_run()
3339                 {
3340                     try
3341                     {
3342                         this->mark_finished_with_result(f());
3343                     }
3344 #endif
3345                     catch(...)
3346                     {
3347                         this->mark_exceptional_finish();
3348                     }
3349                 }
3350             };
3351 #endif
3352 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3353 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3354         template<typename F, typename ...ArgTypes>
3355         struct task_shared_state<F, void(ArgTypes...)>:
3356           task_base_shared_state<void(ArgTypes...)>
3357 #else
3358         template<typename F>
3359         struct task_shared_state<F, void()>:
3360           task_base_shared_state<void()>
3361 #endif
3362 #else
3363         template<typename F>
3364         struct task_shared_state<F,void>:
3365           task_base_shared_state<void>
3366 #endif
3367         {
3368         private:
3369           task_shared_state(task_shared_state&);
3370         public:
3371             typedef F CallableType;
3372             F f;
3373             task_shared_state(F const& f_):
3374                 f(f_)
3375             {}
3376             task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3377                 f(boost::move(f_))
3378             {}
3379             F callable()
3380             {
3381               return boost::move(f);
3382             }
3383 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3384             void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3385             {
3386               try
3387               {
3388                 f(boost::move(args)...);
3389 #else
3390             void do_apply()
3391             {
3392                 try
3393                 {
3394                     f();
3395 #endif
3396                   this->set_value_at_thread_exit();
3397                 }
3398                 catch(...)
3399                 {
3400                     this->set_exception_at_thread_exit(current_exception());
3401                 }
3402             }
3403 
3404 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3405             void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3406             {
3407                 try
3408                 {
3409                     f(boost::move(args)...);
3410 #else
3411             void do_run()
3412             {
3413                 try
3414                 {
3415                     f();
3416 #endif
3417                     this->mark_finished_with_result();
3418                 }
3419                 catch(...)
3420                 {
3421                     this->mark_exceptional_finish();
3422                 }
3423             }
3424         };
3425 
3426 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3427 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3428         template<typename ...ArgTypes>
3429         struct task_shared_state<void (*)(ArgTypes...), void(ArgTypes...)>:
3430         task_base_shared_state<void(ArgTypes...)>
3431 #else
3432         template<>
3433         struct task_shared_state<void (*)(), void()>:
3434         task_base_shared_state<void()>
3435 #endif
3436 #else
3437         template<>
3438         struct task_shared_state<void (*)(),void>:
3439           task_base_shared_state<void>
3440 #endif
3441         {
3442         private:
3443           task_shared_state(task_shared_state&);
3444 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3445             typedef void (*CallableType)(ArgTypes...);
3446 #else
3447             typedef void (*CallableType)();
3448 #endif
3449         public:
3450             CallableType f;
3451             task_shared_state(CallableType f_):
3452                 f(f_)
3453             {}
3454             CallableType callable()
3455             {
3456               return f;
3457             }
3458 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3459             void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3460             {
3461                 try
3462                 {
3463                     f(boost::move(args)...);
3464 #else
3465             void do_apply()
3466             {
3467                 try
3468                 {
3469                     f();
3470 #endif
3471                     this->set_value_at_thread_exit();
3472                 }
3473                 catch(...)
3474                 {
3475                     this->set_exception_at_thread_exit(current_exception());
3476                 }
3477             }
3478 
3479 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3480             void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3481             {
3482                 try
3483                 {
3484                     f(boost::move(args)...);
3485 #else
3486             void do_run()
3487             {
3488                 try
3489                 {
3490                   f();
3491 #endif
3492                   this->mark_finished_with_result();
3493                 }
3494                 catch(...)
3495                 {
3496                     this->mark_exceptional_finish();
3497                 }
3498             }
3499         };
3500     }
3501 
3502 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3503   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3504     template<typename R, typename ...ArgTypes>
3505     class packaged_task<R(ArgTypes...)>
3506     {
3507       typedef boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task_ptr;
3508       boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task;
3509   #else
3510     template<typename R>
3511     class packaged_task<R()>
3512     {
3513       typedef boost::shared_ptr<detail::task_base_shared_state<R()> > task_ptr;
3514       boost::shared_ptr<detail::task_base_shared_state<R()> > task;
3515   #endif
3516 #else
3517     template<typename R>
3518     class packaged_task
3519     {
3520       typedef boost::shared_ptr<detail::task_base_shared_state<R> > task_ptr;
3521       boost::shared_ptr<detail::task_base_shared_state<R> > task;
3522 #endif
3523         bool future_obtained;
3524         struct dummy;
3525 
3526     public:
3527         typedef R result_type;
3528         BOOST_THREAD_MOVABLE_ONLY(packaged_task)
3529 
3530         packaged_task():
3531             future_obtained(false)
3532         {}
3533 
3534         // construction and destruction
3535 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
3536 
3537 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3538   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3539         explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args)
3540         {
3541             typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3542             typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3543             task= task_ptr(new task_shared_state_type(f, boost::move(args)...));
3544             future_obtained=false;
3545         }
3546   #else
3547         explicit packaged_task(R(*f)())
3548         {
3549             typedef R(*FR)();
3550             typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3551             task= task_ptr(new task_shared_state_type(f));
3552             future_obtained=false;
3553         }
3554   #endif
3555 #else
3556         explicit packaged_task(R(*f)())
3557         {
3558               typedef R(*FR)();
3559             typedef detail::task_shared_state<FR,R> task_shared_state_type;
3560             task= task_ptr(new task_shared_state_type(f));
3561             future_obtained=false;
3562         }
3563 #endif
3564 #endif
3565 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
3566         template <class F>
3567         explicit packaged_task(BOOST_THREAD_FWD_REF(F) f
3568             , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3569             )
3570         {
3571           typedef typename decay<F>::type FR;
3572 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3573   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3574             typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3575   #else
3576             typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3577   #endif
3578 #else
3579             typedef detail::task_shared_state<FR,R> task_shared_state_type;
3580 #endif
3581             task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
3582             future_obtained = false;
3583 
3584         }
3585 
3586 #else
3587         template <class F>
3588         explicit packaged_task(F const& f
3589             , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3590             )
3591         {
3592 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3593   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3594             typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3595   #else
3596             typedef detail::task_shared_state<F,R()> task_shared_state_type;
3597   #endif
3598 #else
3599             typedef detail::task_shared_state<F,R> task_shared_state_type;
3600 #endif
3601             task = task_ptr(new task_shared_state_type(f));
3602             future_obtained=false;
3603         }
3604         template <class F>
3605         explicit packaged_task(BOOST_THREAD_RV_REF(F) f)
3606         {
3607 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3608 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3609             typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3610             task = task_ptr(new task_shared_state_type(boost::move(f)));
3611 #else
3612             typedef detail::task_shared_state<F,R()> task_shared_state_type;
3613             task = task_ptr(new task_shared_state_type(boost::move(f)));
3614 #endif
3615 #else
3616             typedef detail::task_shared_state<F,R> task_shared_state_type;
3617             task = task_ptr(new task_shared_state_type(boost::move(f)));
3618 #endif
3619             future_obtained=false;
3620 
3621         }
3622 #endif
3623 
3624 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3625 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
3626         template <class Allocator>
3627         packaged_task(boost::allocator_arg_t, Allocator a, R(*f)())
3628         {
3629           typedef R(*FR)();
3630 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3631   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3632           typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3633   #else
3634           typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3635   #endif
3636 #else
3637           typedef detail::task_shared_state<FR,R> task_shared_state_type;
3638 #endif
3639           typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3640           A2 a2(a);
3641           typedef thread_detail::allocator_destructor<A2> D;
3642 
3643           task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3644           future_obtained = false;
3645         }
3646 #endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
3647 
3648 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3649         template <class F, class Allocator>
3650         packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
3651         {
3652           typedef typename decay<F>::type FR;
3653 
3654 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3655   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3656           typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3657   #else
3658           typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3659   #endif
3660 #else
3661           typedef detail::task_shared_state<FR,R> task_shared_state_type;
3662 #endif
3663           typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3664           A2 a2(a);
3665           typedef thread_detail::allocator_destructor<A2> D;
3666 
3667           task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
3668           future_obtained = false;
3669         }
3670 #else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3671         template <class F, class Allocator>
3672         packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
3673         {
3674 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3675   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3676           typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3677   #else
3678           typedef detail::task_shared_state<F,R()> task_shared_state_type;
3679   #endif
3680 #else
3681           typedef detail::task_shared_state<F,R> task_shared_state_type;
3682 #endif
3683           typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3684           A2 a2(a);
3685           typedef thread_detail::allocator_destructor<A2> D;
3686 
3687           task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3688           future_obtained = false;
3689         }
3690         template <class F, class Allocator>
3691         packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f)
3692         {
3693 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3694   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3695           typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3696   #else
3697           typedef detail::task_shared_state<F,R()> task_shared_state_type;
3698   #endif
3699 #else
3700           typedef detail::task_shared_state<F,R> task_shared_state_type;
3701 #endif
3702           typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3703           A2 a2(a);
3704           typedef thread_detail::allocator_destructor<A2> D;
3705 
3706           task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) );
3707           future_obtained = false;
3708         }
3709 
3710 #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
3711 #endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3712 
3713         ~packaged_task() {
3714             if(task) {
3715                 task->owner_destroyed();
3716             }
3717         }
3718 
3719         // assignment
3720         packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
3721         : future_obtained(BOOST_THREAD_RV(other).future_obtained) {
3722             task.swap(BOOST_THREAD_RV(other).task);
3723             BOOST_THREAD_RV(other).future_obtained=false;
3724         }
3725         packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT {
3726 
3727 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
3728             packaged_task temp(boost::move(other));
3729 #else
3730             packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
3731 #endif
3732             swap(temp);
3733             return *this;
3734         }
3735 
3736 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3737         void set_executor(executor_ptr_type aex)
3738         {
3739           if (!valid())
3740               boost::throw_exception(task_moved());
3741           boost::lock_guard<boost::mutex> lk(task->mutex);
3742           task->set_executor_policy(aex, lk);
3743         }
3744 #endif
3745         void reset() {
3746             if (!valid())
3747               boost::throw_exception(future_error(system::make_error_code(future_errc::no_state)));
3748 
3749             // As if *this = packaged_task(task->callable());
3750 
3751             task->reset();
3752             future_obtained=false;
3753         }
3754 
3755         void swap(packaged_task& other) BOOST_NOEXCEPT {
3756             task.swap(other.task);
3757             std::swap(future_obtained,other.future_obtained);
3758         }
3759         bool valid() const BOOST_NOEXCEPT {
3760           return task.get()!=0;
3761         }
3762 
3763         // result retrieval
3764         BOOST_THREAD_FUTURE<R> get_future() {
3765             if(!task) {
3766                 boost::throw_exception(task_moved());
3767             } else if(!future_obtained) {
3768                 future_obtained=true;
3769                 return BOOST_THREAD_FUTURE<R>(task);
3770             } else {
3771                 boost::throw_exception(future_already_retrieved());
3772             }
3773         }
3774 
3775         // execution
3776 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3777         void operator()(ArgTypes... args) {
3778             if(!task) {
3779                 boost::throw_exception(task_moved());
3780             }
3781             task->run(boost::move(args)...);
3782         }
3783         void make_ready_at_thread_exit(ArgTypes... args) {
3784           if(!task) {
3785               boost::throw_exception(task_moved());
3786           }
3787           if (task->has_value()) {
3788                 boost::throw_exception(promise_already_satisfied());
3789           }
3790           task->apply(boost::move(args)...);
3791         }
3792 #else
3793         void operator()() {
3794             if(!task) {
3795                 boost::throw_exception(task_moved());
3796             }
3797             task->run();
3798         }
3799         void make_ready_at_thread_exit() {
3800           if(!task) {
3801               boost::throw_exception(task_moved());
3802           }
3803           if (task->has_value()) boost::throw_exception(promise_already_satisfied());
3804           task->apply();
3805         }
3806 #endif
3807         template<typename F>
3808         void set_wait_callback(F f) {
3809             task->set_wait_callback(f,this);
3810         }
3811     };
3812 }
3813 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3814 namespace boost { namespace container {
3815     template <class R, class Alloc>
3816     struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3817     {};
3818 }}
3819 #if ! defined  BOOST_NO_CXX11_ALLOCATOR
3820 namespace std {
3821     template <class R, class Alloc>
3822     struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3823     {};
3824 }
3825 #endif
3826 #endif
3827 
3828 namespace boost
3829 {
3830   BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
3831 
3832 namespace detail
3833 {
3834   ////////////////////////////////
3835   // make_future_deferred_shared_state
3836   ////////////////////////////////
3837   template <class Rp, class Fp>
3838   BOOST_THREAD_FUTURE<Rp>
3839   make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3840     shared_ptr<future_deferred_shared_state<Rp, Fp> >
3841         h(new future_deferred_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
3842     return BOOST_THREAD_FUTURE<Rp>(h);
3843   }
3844 
3845   ////////////////////////////////
3846   // make_future_async_shared_state
3847   ////////////////////////////////
3848   template <class Rp, class Fp>
3849   BOOST_THREAD_FUTURE<Rp>
3850   make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3851     shared_ptr<future_async_shared_state<Rp, Fp> >
3852         h(new future_async_shared_state<Rp, Fp>());
3853     h->init(boost::forward<Fp>(f));
3854     return BOOST_THREAD_FUTURE<Rp>(h);
3855   }
3856 }
3857 
3858     ////////////////////////////////
3859     // template <class F, class... ArgTypes>
3860     // future<R> async(launch policy, F&&, ArgTypes&&...);
3861     ////////////////////////////////
3862 
3863 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
3864 
3865 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3866   template <class R, class... ArgTypes>
3867   BOOST_THREAD_FUTURE<R>
3868   async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3869     typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3870     typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3871     typedef typename BF::result_type Rp;
3872 
3873     if (underlying_cast<int>(policy) & int(launch::async)) {
3874       return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3875               BF(
3876                   f
3877                   , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3878               )
3879           ));
3880     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3881       return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3882               BF(
3883                   f
3884                   , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3885               )
3886           ));
3887     } else {
3888       std::terminate();
3889       //BOOST_THREAD_FUTURE<R> ret;
3890       //return ::boost::move(ret);
3891     }
3892   }
3893 
3894 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3895 
3896   template <class R>
3897   BOOST_THREAD_FUTURE<R>
3898   async(launch policy, R(*f)()) {
3899   #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3900     typedef packaged_task<R()> packaged_task_type;
3901   #else
3902     typedef packaged_task<R> packaged_task_type;
3903   #endif
3904 
3905     if (underlying_cast<int>(policy) & int(launch::async)) {
3906       packaged_task_type pt( f );
3907       BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
3908       ret.set_async();
3909       boost::thread( boost::move(pt) ).detach();
3910       return ::boost::move(ret);
3911     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3912       std::terminate();
3913       //BOOST_THREAD_FUTURE<R> ret;
3914       //return ::boost::move(ret);
3915     } else {
3916       std::terminate();
3917       //BOOST_THREAD_FUTURE<R> ret;
3918       //return ::boost::move(ret);
3919     }
3920   }
3921 #endif
3922 #endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
3923 
3924 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3925 
3926   template <class F, class ...ArgTypes>
3927   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3928       typename decay<ArgTypes>::type...
3929   )>::type>
3930   async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3931     typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3932     typedef typename BF::result_type Rp;
3933 
3934     if (underlying_cast<int>(policy) & int(launch::async)) {
3935       return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3936               BF(
3937                   thread_detail::decay_copy(boost::forward<F>(f))
3938                 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3939               )
3940           ));
3941     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3942       return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3943               BF(
3944                   thread_detail::decay_copy(boost::forward<F>(f))
3945                 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3946               )
3947           ));
3948     } else {
3949       std::terminate();
3950       //BOOST_THREAD_FUTURE<R> ret;
3951       //return ::boost::move(ret);
3952     }
3953   }
3954 
3955 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3956 
3957   template <class F>
3958   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3959   async(launch policy, BOOST_THREAD_FWD_REF(F) f) {
3960     typedef typename boost::result_of<typename decay<F>::type()>::type R;
3961 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3962     typedef packaged_task<R()> packaged_task_type;
3963 #else // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3964     typedef packaged_task<R> packaged_task_type;
3965 #endif // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3966 
3967     if (underlying_cast<int>(policy) & int(launch::async)) {
3968       packaged_task_type pt( boost::forward<F>(f) );
3969       BOOST_THREAD_FUTURE<R> ret = pt.get_future();
3970       ret.set_async();
3971       boost::thread( boost::move(pt) ).detach();
3972       return ::boost::move(ret);
3973     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3974       std::terminate();
3975       //BOOST_THREAD_FUTURE<R> ret;
3976       //return ::boost::move(ret);
3977       //          return boost::detail::make_future_deferred_shared_state<Rp>(
3978       //              BF(
3979       //                  thread_detail::decay_copy(boost::forward<F>(f))
3980       //              )
3981       //          );
3982     } else {
3983       std::terminate();
3984       //BOOST_THREAD_FUTURE<R> ret;
3985       //return ::boost::move(ret);
3986     }
3987   }
3988 #endif // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3989 
3990 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3991 namespace detail {
3992 
3993     /////////////////////////
3994     /// shared_state_nullary_task
3995     /////////////////////////
3996     template<typename Rp, typename Fp>
3997     struct shared_state_nullary_task
3998     {
3999 
4000       typedef shared_ptr<shared_state_base > storage_type;
4001       storage_type that;
4002       Fp f_;
4003     public:
4004 
4005       shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
4006       : that(st), f_(boost::move(f))
4007       {};
4008 
4009 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4010       BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
4011       shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
4012       : that(x.that), f_(x.f_)
4013       {}
4014       shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
4015       {
4016         if (this != &x) {
4017           that=x.that;
4018           f_=x.f_;
4019         }
4020         return *this;
4021       }
4022       // move
4023       shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
4024       : that(x.that), f_(boost::move(x.f_))
4025       {
4026         x.that.reset();
4027       }
4028       shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
4029       {
4030         if (this != &x) {
4031           that=x.that;
4032           f_=boost::move(x.f_);
4033           x.that.reset();
4034         }
4035         return *this;
4036       }
4037 #endif
4038       void operator()() {
4039         shared_ptr<shared_state<Rp> > that_ = static_pointer_cast<shared_state<Rp> >(that);
4040         try {
4041           that_->mark_finished_with_result(f_());
4042         } catch(...) {
4043           that_->mark_exceptional_finish();
4044         }
4045       }
4046       ~shared_state_nullary_task()
4047       {
4048       }
4049     };
4050 
4051     template<typename Fp>
4052     struct shared_state_nullary_task<void, Fp>
4053     {
4054       typedef shared_ptr<shared_state_base > storage_type;
4055       storage_type that;
4056       Fp f_;
4057     public:
4058       shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
4059       : that(st), f_(boost::move(f))
4060       {};
4061 
4062 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4063       BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
4064       shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
4065       : that(x.that), f_(x.f_)
4066       {}
4067       shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
4068       {
4069         if (this != &x) {
4070           that=x.that;
4071           f_=x.f_;
4072         }
4073         return *this;
4074       }
4075       // move
4076       shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
4077       : that(x.that), f_(boost::move(x.f_))
4078       {
4079         x.that.reset();
4080       }
4081       shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
4082         if (this != &x) {
4083           that=x.that;
4084           f_=boost::move(x.f_);
4085           x.that.reset();
4086         }
4087         return *this;
4088       }
4089 #endif
4090       void operator()() {
4091         shared_ptr<shared_state<void> > that_ = static_pointer_cast<shared_state<void> >(that);
4092         try {
4093           f_();
4094           that_->mark_finished_with_result();
4095         } catch(...) {
4096           that_->mark_exceptional_finish();
4097         }
4098       }
4099     };
4100 
4101 }
4102     BOOST_THREAD_DCL_MOVABLE_BEG2(R,F) detail::shared_state_nullary_task<R,F> BOOST_THREAD_DCL_MOVABLE_END
4103 namespace detail {
4104 
4105     /////////////////////////
4106     /// future_executor_shared_state_base
4107     /////////////////////////
4108     template<typename Rp>
4109     struct future_executor_shared_state: shared_state<Rp>
4110     {
4111       typedef shared_state<Rp> base_type;
4112     protected:
4113     public:
4114       future_executor_shared_state() {
4115       }
4116 
4117       template <class Fp, class Executor>
4118       void init(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f)
4119       {
4120         typedef typename decay<Fp>::type Cont;
4121         this->set_executor_policy(executor_ptr_type(new executor_ref<Executor>(ex)));
4122         shared_state_nullary_task<Rp,Cont> t(this->shared_from_this(), boost::forward<Fp>(f));
4123         ex.submit(boost::move(t));
4124       }
4125 
4126       ~future_executor_shared_state() {}
4127     };
4128 
4129     ////////////////////////////////
4130     // make_future_executor_shared_state
4131     ////////////////////////////////
4132     template <class Rp, class Fp, class Executor>
4133     BOOST_THREAD_FUTURE<Rp>
4134     make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
4135       shared_ptr<future_executor_shared_state<Rp> >
4136           h(new future_executor_shared_state<Rp>());
4137       h->init(ex, boost::forward<Fp>(f));
4138       return BOOST_THREAD_FUTURE<Rp>(h);
4139     }
4140 
4141 } // detail
4142 
4143     ////////////////////////////////
4144     // template <class Executor, class F, class... ArgTypes>
4145     // future<R> async(Executor& ex, F&&, ArgTypes&&...);
4146     ////////////////////////////////
4147 
4148 //#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4149 #if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
4150 
4151 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4152 
4153   template <class Executor, class R, class... ArgTypes>
4154   BOOST_THREAD_FUTURE<R>
4155   async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4156     typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
4157     typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
4158     typedef typename BF::result_type Rp;
4159 
4160     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4161         BF(
4162             f
4163             , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
4164         )
4165     ));
4166   }
4167 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4168 
4169   template <class Executor, class F, class ...ArgTypes>
4170   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4171       typename decay<ArgTypes>::type...
4172   )>::type>
4173   async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4174     typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
4175     typedef typename BF::result_type Rp;
4176 
4177     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4178         BF(
4179             thread_detail::decay_copy(boost::forward<F>(f))
4180             , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
4181         )
4182     ));
4183   }
4184 
4185 #else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4186 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4187 
4188   template <class Executor, class R>
4189   BOOST_THREAD_FUTURE<R>
4190   async(Executor& ex, R(*f)()) {
4191     typedef R(*F)();
4192     typedef detail::invoker<F> BF;
4193     typedef typename BF::result_type Rp;
4194 
4195     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4196         BF(
4197             f
4198         )
4199     ));
4200   }
4201 
4202   template <class Executor, class R, class A1>
4203   BOOST_THREAD_FUTURE<R>
4204   async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1) {
4205     typedef R(*F)(BOOST_THREAD_FWD_REF(A1));
4206     typedef detail::invoker<F, typename decay<A1>::type> BF;
4207     typedef typename BF::result_type Rp;
4208 
4209     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4210         BF(
4211             f
4212             , thread_detail::decay_copy(boost::forward<A1>(a1))
4213         )
4214     ));
4215   }
4216 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4217 
4218   template <class Executor, class F>
4219   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
4220   async(Executor& ex, BOOST_THREAD_FWD_REF(F) f)  {
4221     typedef detail::invoker<typename decay<F>::type> BF;
4222     typedef typename BF::result_type Rp;
4223 
4224     return boost::detail::make_future_executor_shared_state<Rp>(ex,
4225         BF(
4226             thread_detail::decay_copy(boost::forward<F>(f))
4227         )
4228     );
4229   }
4230 
4231   template <class Executor, class F, class A1>
4232   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4233       typename decay<A1>::type
4234   )>::type>
4235   async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) {
4236     typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type> BF;
4237     typedef typename BF::result_type Rp;
4238 
4239     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4240         BF(
4241             thread_detail::decay_copy(boost::forward<F>(f))
4242           , thread_detail::decay_copy(boost::forward<A1>(a1))
4243         )
4244     ));
4245   }
4246 
4247   template <class Executor, class F, class A1, class A2>
4248   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4249       typename decay<A1>::type, typename decay<A2>::type
4250   )>::type>
4251   async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) {
4252     typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type, typename decay<A2>::type> BF;
4253     typedef typename BF::result_type Rp;
4254 
4255     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4256         BF(
4257             thread_detail::decay_copy(boost::forward<F>(f))
4258           , thread_detail::decay_copy(boost::forward<A1>(a1))
4259           , thread_detail::decay_copy(boost::forward<A2>(a2))
4260         )
4261     ));
4262   }
4263 
4264 #endif //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4265 #endif
4266 
4267   ////////////////////////////////
4268   // template <class F, class... ArgTypes>
4269   // future<R> async(F&&, ArgTypes&&...);
4270   ////////////////////////////////
4271 
4272 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4273   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
4274   template <class R, class... ArgTypes>
4275   BOOST_THREAD_FUTURE<R>
4276   async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4277     return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
4278   }
4279   #else
4280   template <class R>
4281   BOOST_THREAD_FUTURE<R>
4282   async(R(*f)()) {
4283     return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
4284   }
4285   #endif
4286 #endif
4287 
4288 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
4289   template <class F, class ...ArgTypes>
4290   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4291       typename decay<ArgTypes>::type...
4292   )>::type>
4293   async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4294       return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
4295   }
4296 #else
4297   template <class F>
4298   BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
4299   async(BOOST_THREAD_FWD_REF(F) f) {
4300       return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
4301   }
4302 #endif
4303 
4304   ////////////////////////////////
4305   // make_future deprecated
4306   ////////////////////////////////
4307   template <typename T>
4308   BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value) {
4309     typedef typename decay<T>::type future_value_type;
4310     promise<future_value_type> p;
4311     p.set_value(boost::forward<future_value_type>(value));
4312     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4313   }
4314 
4315 #if defined BOOST_THREAD_USES_MOVE
4316   inline BOOST_THREAD_FUTURE<void> make_future() {
4317     promise<void> p;
4318     p.set_value();
4319     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4320   }
4321 #endif
4322 
4323   ////////////////////////////////
4324   // make_ready_future
4325   ////////////////////////////////
4326   namespace detail {
4327     template <class T>
4328     struct deduced_type_impl
4329     {
4330         typedef T type;
4331     };
4332 
4333     template <class T>
4334     struct deduced_type_impl<reference_wrapper<T> const>
4335     {
4336         typedef T& type;
4337     };
4338     template <class T>
4339     struct deduced_type_impl<reference_wrapper<T> >
4340     {
4341         typedef T& type;
4342     };
4343 #if __cplusplus > 201103L
4344     template <class T>
4345     struct deduced_type_impl<std::reference_wrapper<T> >
4346     {
4347         typedef T& type;
4348     };
4349 #endif
4350     template <class T>
4351     struct deduced_type
4352     {
4353         typedef typename detail::deduced_type_impl<typename decay<T>::type>::type type;
4354     };
4355 
4356   }
4357 
4358 
4359 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4360   template <int = 0, int..., class T>
4361 #else
4362   template <class T>
4363 #endif
4364   BOOST_THREAD_FUTURE<typename detail::deduced_type<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
4365     typedef typename detail::deduced_type<T>::type future_value_type;
4366     promise<future_value_type> p;
4367     p.set_value(boost::forward<T>(value));
4368     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4369   }
4370 
4371   // explicit overloads
4372   template <class T>
4373   BOOST_THREAD_FUTURE<T> make_ready_future(typename remove_reference<T>::type & x)
4374   {
4375     promise<T> p;
4376     p.set_value(x);
4377     return p.get_future();
4378   }
4379 
4380   template <class T>
4381   BOOST_THREAD_FUTURE<T> make_ready_future(BOOST_THREAD_FWD_REF(typename remove_reference<T>::type) x)
4382   {
4383     promise<T> p;
4384     p.set_value(forward<typename remove_reference<T>::type>(x));
4385     return p.get_future();
4386   }
4387 
4388   // variadic overload
4389 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4390   template <class T, class ...Args>
4391   BOOST_THREAD_FUTURE<T> make_ready_future(Args&&... args)
4392   {
4393     promise<T> p;
4394     p.emplace(forward<Args>(args)...);
4395     return p.get_future();
4396 
4397   }
4398 #endif
4399 
4400   template <typename T, typename T1>
4401   BOOST_THREAD_FUTURE<T> make_ready_no_decay_future(T1 value) {
4402     typedef T future_value_type;
4403     promise<future_value_type> p;
4404     p.set_value(value);
4405     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4406   }
4407 
4408 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
4409   inline BOOST_THREAD_FUTURE<void> make_ready_future() {
4410     promise<void> p;
4411     p.set_value();
4412     return p.get_future();
4413   }
4414 #endif
4415 
4416 
4417   template <typename T>
4418   BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
4419     promise<T> p;
4420     p.set_exception(ex);
4421     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4422   }
4423 
4424   template <typename T, typename E>
4425   BOOST_THREAD_FUTURE<T> make_exceptional_future(E ex) {
4426     promise<T> p;
4427     p.set_exception(boost::copy_exception(ex));
4428     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4429   }
4430 
4431   template <typename T>
4432   BOOST_THREAD_FUTURE<T> make_exceptional_future() {
4433     promise<T> p;
4434     p.set_exception(boost::current_exception());
4435     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4436   }
4437   template <typename T>
4438   BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex)  {
4439     return make_exceptional_future<T>(ex);
4440   }
4441 
4442 #if 0
4443   template<typename CLOSURE>
4444   make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE<decltype(closure())> {
4445       typedef decltype(closure()) T;
4446       promise<T> p;
4447       try {
4448         p.set_value(closure());
4449       } catch(...) {
4450         p.set_exception(std::current_exception());
4451       }
4452       return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4453   }
4454 #endif
4455 
4456   ////////////////////////////////
4457   // make_shared_future deprecated
4458   ////////////////////////////////
4459   template <typename T>
4460   shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value) {
4461     typedef typename decay<T>::type future_type;
4462     promise<future_type> p;
4463     p.set_value(boost::forward<T>(value));
4464     return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4465   }
4466 
4467   inline shared_future<void> make_shared_future()  {
4468     promise<void> p;
4469     return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4470   }
4471 
4472   ////////////////////////////////
4473   // detail::future_async_continuation_shared_state
4474   ////////////////////////////////
4475 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
4476 
4477 namespace detail
4478 {
4479   //////////////////////
4480   // detail::continuation_shared_state
4481   //////////////////////
4482   template<typename F, typename Rp, typename Fp, class ShSt=shared_state<Rp> >
4483   struct continuation_shared_state: ShSt
4484   {
4485     F parent;
4486     Fp continuation;
4487 
4488   public:
4489     continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4490     : parent(boost::move(f)),
4491       continuation(boost::move(c))
4492     {
4493     }
4494 
4495     void init(boost::unique_lock<boost::mutex> &lock)
4496     {
4497       parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
4498     }
4499 
4500     void call() {
4501       try {
4502         this->mark_finished_with_result(this->continuation(boost::move(this->parent)));
4503       } catch(...) {
4504         this->mark_exceptional_finish();
4505       }
4506       // make sure parent is really cleared to prevent memory "leaks"
4507       this->parent = F();
4508     }
4509 
4510     void call(boost::unique_lock<boost::mutex>& lck) {
4511       try {
4512         relocker relock(lck);
4513 
4514         // neither continuation nor parent are protected by the lock - call() must only
4515         // be called once, and no one else must modify it.
4516         Rp res = this->continuation(boost::move(this->parent));
4517 
4518         // make sure parent is really cleared to prevent memory "leaks"
4519         this->parent = F();
4520 
4521         relock.lock();
4522 
4523         this->mark_finished_with_result_internal(boost::move(res), lck);
4524       } catch (...) {
4525         this->mark_exceptional_finish_internal(current_exception(), lck);
4526 
4527         // make sure parent is really cleared to prevent memory "leaks"
4528         relocker relock(lck);
4529         this->parent = F();
4530       }
4531     }
4532 
4533     static void run(shared_ptr<boost::detail::shared_state_base> that_)
4534     {
4535       continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
4536       that->call();
4537     }
4538 
4539     ~continuation_shared_state() {}
4540   };
4541 
4542   template<typename F, typename Fp, class ShSt>
4543   struct continuation_shared_state<F, void, Fp, ShSt>: ShSt
4544   {
4545     F parent;
4546     Fp continuation;
4547 
4548   public:
4549     continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4550     : parent(boost::move(f)),
4551       continuation(boost::move(c))
4552     {
4553     }
4554 
4555     void init(boost::unique_lock<boost::mutex> &lock)
4556     {
4557       parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
4558     }
4559 
4560     void call()
4561     {
4562       try {
4563         this->continuation(boost::move(this->parent));
4564         this->mark_finished_with_result();
4565       } catch(...) {
4566         this->mark_exceptional_finish();
4567       }
4568       // make sure parent is really cleared to prevent memory "leaks"
4569       this->parent = F();
4570     }
4571 
4572     void call(boost::unique_lock<boost::mutex>& lck) {
4573       try {
4574         {
4575           relocker relock(lck);
4576           // neither continuation nor parent are protected by the lock - call() must only
4577           // be called once, and no one else must modify it.
4578           this->continuation(boost::move(this->parent));
4579 
4580           // make sure parent is really cleared to prevent memory "leaks"
4581           this->parent = F();
4582         }
4583         this->mark_finished_with_result_internal(lck);
4584       } catch (...) {
4585         this->mark_exceptional_finish_internal(current_exception(), lck);
4586 
4587         // make sure parent is really cleared to prevent memory "leaks"
4588         relocker relock(lck);
4589         this->parent = F();
4590       }
4591     }
4592 
4593     static void run(shared_ptr<boost::detail::shared_state_base> that_)
4594     {
4595       continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
4596       that->call();
4597     }
4598 
4599     ~continuation_shared_state() {}
4600   };
4601   /////////////////////////
4602   /// future_async_continuation_shared_state
4603   /////////////////////////
4604 
4605   template<typename F, typename Rp, typename Fp>
4606   struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
4607   {
4608     typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
4609   public:
4610     future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4611     : base_type(boost::move(f), boost::forward<Fp>(c))
4612     {    }
4613 
4614     void launch_continuation() {
4615 #if defined BOOST_THREAD_FUTURE_BLOCKING
4616       boost::lock_guard<boost::mutex> lk(this->mutex);
4617       this->thr_ = boost::thread(&future_async_continuation_shared_state::run, static_shared_from_this(this));
4618 #else
4619       boost::thread(&base_type::run, static_shared_from_this(this)).detach();
4620 #endif
4621     }
4622   };
4623 
4624   /////////////////////////
4625   /// future_sync_continuation_shared_state
4626   /////////////////////////
4627 
4628   template<typename F, typename Rp, typename Fp>
4629   struct future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
4630   {
4631     typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
4632   public:
4633     future_sync_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4634     : base_type(boost::move(f), boost::forward<Fp>(c))
4635     {    }
4636 
4637     void launch_continuation() {
4638       this->call();
4639     }
4640   };
4641 
4642 
4643   /////////////////////////
4644   /// future_executor_continuation_shared_state
4645   /////////////////////////
4646 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4647 
4648   template <typename FutureExecutorContinuationSharedState>
4649   struct run_it {
4650     shared_ptr<FutureExecutorContinuationSharedState> that_;
4651 
4652 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4653       BOOST_THREAD_COPYABLE_AND_MOVABLE(run_it)
4654       run_it(run_it const& x) //BOOST_NOEXCEPT
4655       : that_(x.that_)
4656       {}
4657       run_it& operator=(BOOST_THREAD_COPY_ASSIGN_REF(run_it) x) //BOOST_NOEXCEPT
4658       {
4659         if (this != &x) {
4660           that_=x.that_;
4661         }
4662         return *this;
4663       }
4664       // move
4665       run_it(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT
4666       : that_(x.that_)
4667       {
4668         x.that_.reset();
4669       }
4670       run_it& operator=(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT {
4671         if (this != &x) {
4672           that_=x.that;
4673           x.that_.reset();
4674         }
4675         return *this;
4676       }
4677 #endif
4678     run_it(shared_ptr<FutureExecutorContinuationSharedState> that) : that_ (that) {}
4679 
4680     void operator()()
4681     {
4682       that_->run(that_);
4683     }
4684   };
4685 
4686 }
4687   BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::run_it<F> BOOST_THREAD_DCL_MOVABLE_END
4688 
4689 namespace detail {
4690 
4691   template<typename F, typename Rp, typename Fp>
4692   struct future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4693   {
4694     typedef continuation_shared_state<F,Rp,Fp> base_type;
4695 
4696   public:
4697     future_executor_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4698     : base_type(boost::move(f), boost::forward<Fp>(c))
4699     {
4700     }
4701 
4702     template <class Ex>
4703     void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
4704     {
4705       this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
4706       this->base_type::init(lk);
4707     }
4708 
4709     void launch_continuation() {
4710       run_it<base_type> fct(static_shared_from_this(this));
4711       this->get_executor()->submit(boost::move(fct));
4712     }
4713 
4714     ~future_executor_continuation_shared_state() {}
4715   };
4716 #endif
4717 
4718   /////////////////////////
4719   /// shared_future_async_continuation_shared_state
4720   /////////////////////////
4721 
4722   template<typename F, typename Rp, typename Fp>
4723   struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
4724   {
4725     typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
4726 
4727   public:
4728     shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4729     : base_type(boost::move(f), boost::forward<Fp>(c))
4730     {
4731     }
4732 
4733     void launch_continuation() {
4734 #if defined BOOST_THREAD_FUTURE_BLOCKING
4735       boost::lock_guard<boost::mutex> lk(this->mutex);
4736       this->thr_ = boost::thread(&base_type::run, static_shared_from_this(this));
4737 #else
4738       boost::thread(&base_type::run, static_shared_from_this(this)).detach();
4739 #endif
4740     }
4741   };
4742 
4743   /////////////////////////
4744   /// shared_future_async_continuation_shared_state
4745   /////////////////////////
4746 
4747   template<typename F, typename Rp, typename Fp>
4748   struct shared_future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
4749   {
4750     typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
4751 
4752   public:
4753     shared_future_sync_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4754     : base_type(boost::move(f), boost::forward<Fp>(c))
4755     {
4756     }
4757 
4758     void launch_continuation() {
4759       this->call();
4760     }
4761   };
4762 
4763 
4764   /////////////////////////
4765   /// shared_future_executor_continuation_shared_state
4766   /////////////////////////
4767 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4768 
4769   template<typename F, typename Rp, typename Fp>
4770   struct shared_future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4771   {
4772     typedef continuation_shared_state<F,Rp,Fp> base_type;
4773 
4774   public:
4775 
4776     shared_future_executor_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4777     : base_type(boost::move(f), boost::forward<Fp>(c))
4778     {
4779     }
4780 
4781     template <class Ex>
4782     void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
4783     {
4784       this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
4785       this->base_type::init(lk);
4786     }
4787 
4788     void launch_continuation() {
4789       run_it<base_type> fct(static_shared_from_this(this));
4790       this->get_executor()->submit(boost::move(fct));
4791     }
4792 
4793     ~shared_future_executor_continuation_shared_state() {}
4794   };
4795 
4796 #endif
4797   //////////////////////////
4798   /// future_deferred_continuation_shared_state
4799   //////////////////////////
4800   template<typename F, typename Rp, typename Fp>
4801   struct future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4802   {
4803     typedef continuation_shared_state<F,Rp,Fp> base_type;
4804   public:
4805     future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4806     : base_type(boost::move(f), boost::forward<Fp>(c))
4807     {
4808       this->set_deferred();
4809     }
4810 
4811     virtual void execute(boost::unique_lock<boost::mutex>& lk) {
4812       this->parent.wait();
4813       this->call(lk);
4814     }
4815 
4816     virtual void launch_continuation() {    }
4817   };
4818 
4819   //////////////////////////
4820   /// shared_future_deferred_continuation_shared_state
4821   //////////////////////////
4822   template<typename F, typename Rp, typename Fp>
4823   struct shared_future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4824   {
4825     typedef continuation_shared_state<F,Rp,Fp> base_type;
4826 
4827   public:
4828     shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4829     : base_type(boost::move(f), boost::forward<Fp>(c))
4830     {
4831       this->set_deferred();
4832     }
4833 
4834     virtual void execute(boost::unique_lock<boost::mutex>& lk) {
4835       this->parent.wait();
4836       this->call(lk);
4837     }
4838 
4839     virtual void launch_continuation() {    }
4840   };
4841 
4842   ////////////////////////////////
4843   // make_future_deferred_continuation_shared_state
4844   ////////////////////////////////
4845   template<typename F, typename Rp, typename Fp>
4846   BOOST_THREAD_FUTURE<Rp>
4847   make_future_deferred_continuation_shared_state(
4848       boost::unique_lock<boost::mutex> &lock,
4849       BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c) {
4850     typedef typename decay<Fp>::type Cont;
4851     shared_ptr<future_deferred_continuation_shared_state<F, Rp, Cont> >
4852         h(new future_deferred_continuation_shared_state<F, Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4853     h->init(lock);
4854     return BOOST_THREAD_FUTURE<Rp>(h);
4855   }
4856 
4857   ////////////////////////////////
4858   // make_future_async_continuation_shared_state
4859   ////////////////////////////////
4860   template<typename F, typename Rp, typename Fp>
4861   BOOST_THREAD_FUTURE<Rp>
4862   make_future_async_continuation_shared_state(
4863       boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4864       BOOST_THREAD_FWD_REF(Fp) c) {
4865     typedef typename decay<Fp>::type Cont;
4866     shared_ptr<future_async_continuation_shared_state<F,Rp, Cont> >
4867         h(new future_async_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4868     h->init(lock);
4869 
4870     return BOOST_THREAD_FUTURE<Rp>(h);
4871   }
4872   ////////////////////////////////
4873   // make_future_sync_continuation_shared_state
4874   ////////////////////////////////
4875   template<typename F, typename Rp, typename Fp>
4876   BOOST_THREAD_FUTURE<Rp>
4877   make_future_sync_continuation_shared_state(
4878       boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4879       BOOST_THREAD_FWD_REF(Fp) c) {
4880     typedef typename decay<Fp>::type Cont;
4881     shared_ptr<future_sync_continuation_shared_state<F,Rp, Cont> >
4882         h(new future_sync_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4883     h->init(lock);
4884 
4885     return BOOST_THREAD_FUTURE<Rp>(h);
4886   }
4887 
4888   ////////////////////////////////
4889   // make_future_executor_continuation_shared_state
4890   ////////////////////////////////
4891 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4892 
4893   template<typename Ex, typename F, typename Rp, typename Fp>
4894   BOOST_THREAD_FUTURE<Rp>
4895   make_future_executor_continuation_shared_state(Ex& ex,
4896       boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4897       BOOST_THREAD_FWD_REF(Fp) c) {
4898     typedef typename decay<Fp>::type Cont;
4899     shared_ptr<future_executor_continuation_shared_state<F,Rp, Cont> >
4900         h(new future_executor_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4901     h->init(lock, ex);
4902 
4903     return BOOST_THREAD_FUTURE<Rp>(h);
4904   }
4905 #endif
4906 
4907   ////////////////////////////////
4908   // make_shared_future_deferred_continuation_shared_state
4909   ////////////////////////////////
4910   template<typename F, typename Rp, typename Fp>
4911   BOOST_THREAD_FUTURE<Rp>
4912   make_shared_future_deferred_continuation_shared_state(
4913       boost::unique_lock<boost::mutex> &lock,
4914       F f, BOOST_THREAD_FWD_REF(Fp) c) {
4915     typedef typename decay<Fp>::type Cont;
4916     shared_ptr<shared_future_deferred_continuation_shared_state<F, Rp, Cont> >
4917         h(new shared_future_deferred_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
4918     h->init(lock);
4919 
4920     return BOOST_THREAD_FUTURE<Rp>(h);
4921   }
4922   ////////////////////////////////
4923   // make_shared_future_async_continuation_shared_state
4924   ////////////////////////////////
4925   template<typename F, typename Rp, typename Fp>
4926   BOOST_THREAD_FUTURE<Rp>
4927   make_shared_future_async_continuation_shared_state(
4928       boost::unique_lock<boost::mutex> &lock, F f,
4929       BOOST_THREAD_FWD_REF(Fp) c) {
4930     typedef typename decay<Fp>::type Cont;
4931     shared_ptr<shared_future_async_continuation_shared_state<F,Rp, Cont> >
4932         h(new shared_future_async_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
4933     h->init(lock);
4934 
4935     return BOOST_THREAD_FUTURE<Rp>(h);
4936   }
4937   ////////////////////////////////
4938   // make_shared_future_sync_continuation_shared_state
4939   ////////////////////////////////
4940   template<typename F, typename Rp, typename Fp>
4941   BOOST_THREAD_FUTURE<Rp>
4942   make_shared_future_sync_continuation_shared_state(
4943       boost::unique_lock<boost::mutex> &lock, F f,
4944       BOOST_THREAD_FWD_REF(Fp) c) {
4945     typedef typename decay<Fp>::type Cont;
4946     shared_ptr<shared_future_sync_continuation_shared_state<F,Rp, Cont> >
4947         h(new shared_future_sync_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
4948     h->init(lock);
4949 
4950     return BOOST_THREAD_FUTURE<Rp>(h);
4951   }
4952   ////////////////////////////////
4953   // make_shared_future_executor_continuation_shared_state
4954   ////////////////////////////////
4955 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4956   template<typename Ex, typename F, typename Rp, typename Fp>
4957   BOOST_THREAD_FUTURE<Rp>
4958   make_shared_future_executor_continuation_shared_state(Ex& ex,
4959       boost::unique_lock<boost::mutex> &lock, F f,
4960       BOOST_THREAD_FWD_REF(Fp) c) {
4961     typedef typename decay<Fp>::type Cont;
4962     shared_ptr<shared_future_executor_continuation_shared_state<F, Rp, Cont> >
4963         h(new shared_future_executor_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
4964     h->init(lock, ex);
4965 
4966     return BOOST_THREAD_FUTURE<Rp>(h);
4967   }
4968 #endif
4969 }
4970 
4971   ////////////////////////////////
4972   // template<typename F>
4973   // auto future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4974   ////////////////////////////////
4975   template <typename R>
4976   template <typename F>
4977   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4978   BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
4979     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4980     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
4981 
4982     // keep state alive as we move ourself but hold the lock
4983     shared_ptr<detail::shared_state_base> sentinel(this->future_);
4984     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
4985 
4986     if (underlying_cast<int>(policy) & int(launch::async)) {
4987       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4988                   lock, boost::move(*this), boost::forward<F>(func)
4989               )));
4990     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
4991       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4992                   lock, boost::move(*this), boost::forward<F>(func)
4993               )));
4994     } else if (underlying_cast<int>(policy) & int(launch::sync)) {
4995       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4996                   lock, boost::move(*this), boost::forward<F>(func)
4997               )));
4998 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4999     } else if (underlying_cast<int>(policy) & int(launch::executor)) {
5000       assert(this->future_->get_executor());
5001       typedef executor Ex;
5002       Ex& ex = *(this->future_->get_executor());
5003       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5004                     lock, boost::move(*this), boost::forward<F>(func)
5005                 )));
5006 #endif
5007     } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
5008 
5009         launch policy_ = this->launch_policy(lock);
5010         if (underlying_cast<int>(policy_) & int(launch::async)) {
5011           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5012                       lock, boost::move(*this), boost::forward<F>(func)
5013                   )));
5014         } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
5015           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5016                       lock, boost::move(*this), boost::forward<F>(func)
5017                   )));
5018         } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
5019           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5020                       lock, boost::move(*this), boost::forward<F>(func)
5021                   )));
5022 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5023         } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
5024           assert(this->future_->get_executor());
5025           typedef executor Ex;
5026           Ex& ex = *(this->future_->get_executor());
5027           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5028                         lock, boost::move(*this), boost::forward<F>(func)
5029                     )));
5030 #endif
5031         } else {
5032           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5033                       lock, boost::move(*this), boost::forward<F>(func)
5034                   )));
5035         }
5036     } else {
5037       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5038                   lock, boost::move(*this), boost::forward<F>(func)
5039               )));
5040     }
5041   }
5042 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5043   ////////////////////////////////
5044   // template<typename Ex, typename F>
5045   // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5046   ////////////////////////////////
5047   template <typename R>
5048   template <typename Ex, typename F>
5049   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
5050   BOOST_THREAD_FUTURE<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
5051     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5052     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5053 
5054     // keep state alive as we move ourself but hold the lock
5055     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5056     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5057 
5058     return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5059                   lock, boost::move(*this), boost::forward<F>(func)
5060               )));
5061   }
5062 #endif
5063   ////////////////////////////////
5064   // template<typename F>
5065   // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5066   ////////////////////////////////
5067   template <typename R>
5068   template <typename F>
5069   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
5070   BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func)  {
5071 
5072 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5073     return this->then(this->launch_policy(), boost::forward<F>(func));
5074 #else
5075     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5076     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5077 
5078     // keep state alive as we move ourself but hold the lock
5079     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5080     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5081 
5082     launch policy = this->launch_policy(lock);
5083     if (underlying_cast<int>(policy) & int(launch::deferred)) {
5084       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5085                   lock, boost::move(*this), boost::forward<F>(func)
5086               )));
5087     } else {
5088       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5089                   lock, boost::move(*this), boost::forward<F>(func)
5090               )));
5091     }
5092 #endif
5093 
5094   }
5095 
5096   ////////////////////////////////
5097   // template<typename F>
5098   // auto future<future<R2> >::then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5099   ////////////////////////////////
5100   template <typename R2>
5101   template <typename F>
5102   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
5103   BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
5104     typedef BOOST_THREAD_FUTURE<R2> R;
5105     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5106     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5107 
5108     // keep state alive as we move ourself but hold the lock
5109     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5110     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5111 
5112     if (underlying_cast<int>(policy) & int(launch::async)) {
5113       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5114                   lock, boost::move(*this), boost::forward<F>(func)
5115               )));
5116     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
5117       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5118                   lock, boost::move(*this), boost::forward<F>(func)
5119               )));
5120     } else if (underlying_cast<int>(policy) & int(launch::sync)) {
5121       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5122                   lock, boost::move(*this), boost::forward<F>(func)
5123               )));
5124 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5125     } else if (underlying_cast<int>(policy) & int(launch::executor)) {
5126       assert(this->future_->get_executor());
5127       typedef executor Ex;
5128       Ex& ex = *(this->future_->get_executor());
5129       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5130                     lock, boost::move(*this), boost::forward<F>(func)
5131                 )));
5132 #endif
5133     } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
5134         launch policy_ = this->launch_policy(lock);
5135 
5136         if (underlying_cast<int>(policy_) & int(launch::async)) {
5137           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5138                       lock, boost::move(*this), boost::forward<F>(func)
5139                   )));
5140         } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
5141           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5142                       lock, boost::move(*this), boost::forward<F>(func)
5143                   )));
5144         } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
5145           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5146                       lock, boost::move(*this), boost::forward<F>(func)
5147                   )));
5148 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5149         } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
5150           assert(this->future_->get_executor());
5151           typedef executor Ex;
5152           Ex& ex = *(this->future_->get_executor());
5153           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5154                         lock, boost::move(*this), boost::forward<F>(func)
5155                     )));
5156 #endif
5157         } else {
5158           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5159                       lock, boost::move(*this), boost::forward<F>(func)
5160                   )));
5161         }
5162     } else {
5163       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5164                   lock, boost::move(*this), boost::forward<F>(func)
5165               )));
5166     }
5167   }
5168 
5169 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5170   ////////////////////////////////
5171   // template<typename Ex, typename F>
5172   // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5173   ////////////////////////////////
5174   template <typename R2>
5175   template <typename Ex, typename F>
5176   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
5177   BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
5178     typedef BOOST_THREAD_FUTURE<R2> R;
5179     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5180     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5181 
5182     // keep state alive as we move ourself but hold the lock
5183     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5184     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5185 
5186     return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5187                   lock, boost::move(*this), boost::forward<F>(func)
5188               )));
5189   }
5190 #endif
5191 
5192   ////////////////////////////////
5193   // template<typename F>
5194   // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5195   ////////////////////////////////
5196   template <typename R2>
5197   template <typename F>
5198   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
5199   BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(BOOST_THREAD_FWD_REF(F) func)  {
5200 
5201 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5202     return this->then(this->launch_policy(), boost::forward<F>(func));
5203 #else
5204     typedef BOOST_THREAD_FUTURE<R2> R;
5205     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5206     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5207 
5208     // keep state alive as we move ourself but hold the lock
5209     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5210     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5211 
5212     launch policy = this->launch_policy(lock);
5213 
5214     if  (underlying_cast<int>(policy) & int(launch::deferred)) {
5215       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5216                   lock, boost::move(*this), boost::forward<F>(func)
5217               )));
5218     } else {
5219       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5220                   lock, boost::move(*this), boost::forward<F>(func)
5221               )));
5222     }
5223 #endif
5224   }
5225 
5226   ////////////////////////////////
5227   // template<typename F>
5228   // auto shared_future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5229   ////////////////////////////////
5230   template <typename R>
5231   template <typename F>
5232   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5233   shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func)  const
5234   {
5235     typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5236     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5237 
5238     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5239     if (underlying_cast<int>(policy) & int(launch::async)) {
5240       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5241                   lock, *this, boost::forward<F>(func)
5242               )));
5243     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
5244       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5245                   lock, *this, boost::forward<F>(func)
5246               )));
5247     } else if (underlying_cast<int>(policy) & int(launch::sync)) {
5248       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5249                   lock, *this, boost::forward<F>(func)
5250               )));
5251 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5252     } else if (underlying_cast<int>(policy) & int(launch::executor)) {
5253       typedef executor Ex;
5254       Ex& ex = *(this->future_->get_executor());
5255       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5256                     lock, *this, boost::forward<F>(func)
5257                 )));
5258 #endif
5259     } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
5260 
5261         launch policy_ = this->launch_policy(lock);
5262         if (underlying_cast<int>(policy_) & int(launch::async)) {
5263           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5264                       lock, *this, boost::forward<F>(func)
5265                   )));
5266         } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
5267           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5268                       lock, *this, boost::forward<F>(func)
5269                   )));
5270         } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
5271           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5272                       lock, *this, boost::forward<F>(func)
5273                   )));
5274 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5275         } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
5276           typedef executor Ex;
5277           Ex& ex = *(this->future_->get_executor());
5278           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5279                         lock, *this, boost::forward<F>(func)
5280                     )));
5281 #endif
5282         } else {
5283           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5284                       lock, *this, boost::forward<F>(func)
5285                   )));
5286         }
5287 
5288     } else {
5289       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5290                   lock, *this, boost::forward<F>(func)
5291               )));
5292     }
5293   }
5294 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5295   ////////////////////////////////
5296   // template<typename Ex, typename F>
5297   // auto shared_future<R>::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5298   ////////////////////////////////
5299   template <typename R>
5300   template <typename Ex, typename F>
5301   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5302   shared_future<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func)  const
5303   {
5304     typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5305     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5306 
5307     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5308     return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5309                   lock, *this, boost::forward<F>(func)
5310               )));
5311   }
5312 #endif
5313 
5314   ////////////////////////////////
5315   // template<typename F>
5316   // auto shared_future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5317   ////////////////////////////////
5318   template <typename R>
5319   template <typename F>
5320   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5321   shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func)  const {
5322 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5323     return this->then(this->launch_policy(), boost::forward<F>(func));
5324 #else
5325     typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5326     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5327 
5328     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5329     launch policy = this->launch_policy(lock);
5330     if (underlying_cast<int>(policy) & int(launch::deferred)) {
5331       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5332                   lock, *this, boost::forward<F>(func)
5333               )));
5334     } else {
5335       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5336                   lock, *this, boost::forward<F>(func)
5337               )));
5338     }
5339 #endif
5340   }
5341 
5342 namespace detail
5343 {
5344   template <typename T>
5345   struct mfallbacker_to
5346   {
5347     T value_;
5348     typedef T result_type;
5349     mfallbacker_to(BOOST_THREAD_RV_REF(T) v)
5350     : value_(boost::move(v))
5351     {}
5352 
5353     T operator()(BOOST_THREAD_FUTURE<T> fut) {
5354       return fut.get_or(boost::move(value_));
5355     }
5356   };
5357   template <typename T>
5358   struct cfallbacker_to
5359   {
5360     T value_;
5361     typedef T result_type;
5362     cfallbacker_to(T const& v)
5363     : value_(v)
5364     {}
5365 
5366     T operator()(BOOST_THREAD_FUTURE<T> fut) const {
5367       return fut.get_or(value_);
5368 
5369     }
5370   };
5371 }
5372   ////////////////////////////////
5373   // future<R> future<R>::fallback_to(R&& v);
5374   ////////////////////////////////
5375 
5376   template <typename R>
5377   template <typename R2>
5378   inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
5379   BOOST_THREAD_FUTURE<R>::fallback_to(BOOST_THREAD_RV_REF(R2) v) {
5380     return then(detail::mfallbacker_to<R>(boost::move(v)));
5381   }
5382 
5383   template <typename R>
5384   template <typename R2>
5385   inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
5386   BOOST_THREAD_FUTURE<R>::fallback_to(R2 const& v) {
5387     return then(detail::cfallbacker_to<R>(v));
5388   }
5389 
5390 #endif
5391 
5392 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
5393 namespace detail
5394 {
5395   /////////////////////////
5396   /// future_unwrap_shared_state
5397   /////////////////////////
5398 
5399   template<typename F, typename Rp>
5400   struct future_unwrap_shared_state: shared_state<Rp>
5401   {
5402     F wrapped;
5403     typename F::value_type unwrapped;
5404   public:
5405     explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
5406     : wrapped(boost::move(f)) {
5407     }
5408 
5409     void launch_continuation()
5410     {
5411       boost::unique_lock<boost::mutex> lk(this->mutex);
5412       // assert(wrapped.is_ready());
5413       if (! unwrapped.valid() )
5414       {
5415         if (wrapped.has_exception()) {
5416           this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
5417         } else {
5418           unwrapped = wrapped.get();
5419           if (unwrapped.valid())
5420           {
5421             lk.unlock();
5422             boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
5423             unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
5424           } else {
5425             this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
5426           }
5427         }
5428       } else {
5429         // assert(unwrapped.is_ready());
5430         if (unwrapped.has_exception()) {
5431           this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
5432         } else {
5433           this->mark_finished_with_result_internal(unwrapped.get(), lk);
5434         }
5435       }
5436     }
5437   };
5438 
5439   template<typename F>
5440   struct future_unwrap_shared_state<F,void>: shared_state<void>
5441   {
5442     F wrapped;
5443     typename F::value_type unwrapped;
5444   public:
5445     explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
5446     : wrapped(boost::move(f)) {
5447     }
5448 
5449     void launch_continuation()
5450     {
5451       boost::unique_lock<boost::mutex> lk(this->mutex);
5452       // assert(wrapped.is_ready());
5453       if (! unwrapped.valid() )
5454       {
5455         if (wrapped.has_exception()) {
5456           this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
5457         } else {
5458           unwrapped = wrapped.get();
5459           if (unwrapped.valid())
5460           {
5461             lk.unlock();
5462             boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
5463             unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
5464           } else {
5465             this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
5466           }
5467         }
5468       } else {
5469         // assert(unwrapped.is_ready());
5470         if (unwrapped.has_exception()) {
5471           this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
5472         } else {
5473           this->mark_finished_with_result_internal(lk);
5474         }
5475       }
5476     }
5477   };
5478 
5479   template <class F, class Rp>
5480   BOOST_THREAD_FUTURE<Rp>
5481   make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f) {
5482     shared_ptr<future_unwrap_shared_state<F, Rp> >
5483         h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
5484     h->wrapped.future_->set_continuation_ptr(h, lock);
5485 
5486     return BOOST_THREAD_FUTURE<Rp>(h);
5487   }
5488 }
5489 
5490   template <typename R>
5491   inline BOOST_THREAD_FUTURE<R>::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other)
5492   : base_type(other.unwrap()) {}
5493 
5494   template <typename R2>
5495   BOOST_THREAD_FUTURE<R2>
5496   BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
5497   {
5498     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5499 
5500     // keep state alive as we move ourself but hold the lock
5501     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5502     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5503 
5504     return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
5505   }
5506 #endif
5507 
5508 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
5509 namespace detail
5510 {
5511   struct input_iterator_tag {};
5512   struct vector_tag {};
5513   struct values_tag {};
5514   template <typename T>
5515   struct alias_t { typedef T type; };
5516 
5517   BOOST_CONSTEXPR_OR_CONST input_iterator_tag input_iterator_tag_value = {};
5518   BOOST_CONSTEXPR_OR_CONST vector_tag vector_tag_value = {};
5519   BOOST_CONSTEXPR_OR_CONST values_tag values_tag_value = {};
5520   ////////////////////////////////
5521   // detail::future_async_when_all_shared_state
5522   ////////////////////////////////
5523   template<typename F>
5524   struct future_when_all_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
5525   {
5526     typedef csbl::vector<F> vector_type;
5527     typedef typename F::value_type value_type;
5528     vector_type vec_;
5529 
5530     static void run(shared_ptr<boost::detail::shared_state_base> that_) {
5531       future_when_all_vector_shared_state* that = static_cast<future_when_all_vector_shared_state*>(that_.get());
5532       try {
5533         boost::wait_for_all(that->vec_.begin(), that->vec_.end());
5534         that->mark_finished_with_result(boost::move(that->vec_));
5535       } catch(...) {
5536         that->mark_exceptional_finish();
5537       }
5538     }
5539     bool run_deferred() {
5540 
5541       bool res = false;
5542       for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
5543         if (! it->run_if_is_deferred())
5544         {
5545           res = true;
5546         }
5547       }
5548       return res;
5549     }
5550     void init() {
5551       if (! run_deferred())
5552       {
5553         future_when_all_vector_shared_state::run(this->shared_from_this());
5554         return;
5555       }
5556 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5557       this->thr_ = boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this());
5558 #else
5559       boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this()).detach();
5560 #endif
5561     }
5562 
5563   public:
5564     template< typename InputIterator>
5565     future_when_all_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
5566     : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
5567     {
5568     }
5569 
5570     future_when_all_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
5571     : vec_(boost::move(v))
5572     {
5573     }
5574 
5575 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5576     template< typename T0, typename ...T>
5577     future_when_all_vector_shared_state(values_tag, BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5578       vec_.push_back(boost::forward<T0>(f));
5579       typename alias_t<char[]>::type{
5580           ( //first part of magic unpacker
5581           vec_.push_back(boost::forward<T>(futures)),'0'
5582           )..., '0'
5583       }; //second part of magic unpacker
5584     }
5585 #endif
5586 
5587     ~future_when_all_vector_shared_state() {}
5588   };
5589 
5590   ////////////////////////////////
5591   // detail::future_async_when_any_shared_state
5592   ////////////////////////////////
5593   template<typename F>
5594   struct future_when_any_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
5595   {
5596     typedef csbl::vector<F> vector_type;
5597     typedef typename F::value_type value_type;
5598     vector_type vec_;
5599 
5600     static void run(shared_ptr<boost::detail::shared_state_base> that_)
5601     {
5602       future_when_any_vector_shared_state* that = static_cast<future_when_any_vector_shared_state*>(that_.get());
5603       try {
5604         boost::wait_for_any(that->vec_.begin(), that->vec_.end());
5605         that->mark_finished_with_result(boost::move(that->vec_));
5606       } catch(...) {
5607         that->mark_exceptional_finish();
5608       }
5609     }
5610     bool run_deferred() {
5611 
5612       for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
5613         if (it->run_if_is_deferred_or_ready())
5614         {
5615           return true;
5616         }
5617       }
5618       return false;
5619     }
5620     void init() {
5621       if (run_deferred())
5622       {
5623         future_when_any_vector_shared_state::run(this->shared_from_this());
5624         return;
5625       }
5626 
5627 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5628       this->thr_ = boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this());
5629 #else
5630       boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this()).detach();
5631 #endif
5632     }
5633 
5634   public:
5635     template< typename InputIterator>
5636     future_when_any_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
5637     : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
5638     {
5639     }
5640 
5641     future_when_any_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
5642     : vec_(boost::move(v))
5643     {
5644     }
5645 
5646 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5647     template< typename T0, typename ...T>
5648     future_when_any_vector_shared_state(values_tag,
5649         BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures
5650     ) {
5651       vec_.push_back(boost::forward<T0>(f));
5652       typename alias_t<char[]>::type{
5653           ( //first part of magic unpacker
5654           vec_.push_back(boost::forward<T>(futures))
5655           ,'0'
5656           )...,
5657           '0'
5658       }; //second part of magic unpacker
5659     }
5660 #endif
5661 
5662     ~future_when_any_vector_shared_state() {}
5663   };
5664 
5665 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5666   struct wait_for_all_fctr {
5667     template <class ...T>
5668     void operator()(T&&... v) {
5669       boost::wait_for_all(boost::forward<T>(v)...);
5670     }
5671   };
5672 
5673   struct wait_for_any_fctr {
5674     template <class ...T>
5675     void operator()(T&&... v) {
5676       boost::wait_for_any(boost::forward<T>(v)...);
5677     }
5678   };
5679 
5680 
5681   template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5682   struct accumulate_run_if_is_deferred {
5683     bool operator ()(Tuple& t)
5684     {
5685       return (! csbl::get<i-1>(t).run_if_is_deferred()) || accumulate_run_if_is_deferred<Tuple,i-1>()(t);
5686     }
5687   };
5688   template <class Tuple>
5689   struct accumulate_run_if_is_deferred<Tuple, 0> {
5690     bool operator ()(Tuple& )
5691     {
5692       return false;
5693     }
5694   };
5695 
5696 
5697   template< typename Tuple, typename T0, typename ...T>
5698   struct future_when_all_tuple_shared_state: future_async_shared_state_base<Tuple>
5699   {
5700     Tuple tup_;
5701     typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5702 
5703     static void run(shared_ptr<boost::detail::shared_state_base> that_) {
5704       future_when_all_tuple_shared_state* that = static_cast<future_when_all_tuple_shared_state*>(that_.get());
5705       try {
5706         // TODO make use of apply(that->tup_, boost::detail::wait_for_all_fctor());
5707         that->wait_for_all(Index());
5708 
5709         that->mark_finished_with_result(boost::move(that->tup_));
5710       } catch(...) {
5711         that->mark_exceptional_finish();
5712       }
5713     }
5714 
5715     template <size_t ...Indices>
5716     void wait_for_all(tuple_indices<Indices...>) {
5717 #if defined BOOST_THREAD_PROVIDES_INVOKE
5718       return invoke<void>(wait_for_all_fctr(), csbl::get<Indices>(tup_)...);
5719 #else
5720       return wait_for_all_fctr()(csbl::get<Indices>(tup_)...);
5721 #endif
5722     }
5723 
5724     bool run_deferred() {
5725 
5726       return accumulate_run_if_is_deferred<Tuple>()(tup_);
5727     }
5728     void init() {
5729       if (! run_deferred())
5730       {
5731         future_when_all_tuple_shared_state::run(this->shared_from_this());
5732         return;
5733       }
5734 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5735       this->thr_ = boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this());
5736 #else
5737       boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this()).detach();
5738 #endif
5739 
5740     }
5741   public:
5742     template< typename F, typename ...Fs>
5743     future_when_all_tuple_shared_state(values_tag, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures) :
5744       tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5745     {
5746     }
5747 
5748     ~future_when_all_tuple_shared_state() {}
5749 
5750   };
5751 
5752 
5753   template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5754   struct apply_any_run_if_is_deferred_or_ready {
5755     bool operator ()(Tuple& t)
5756     {
5757       if (csbl::get<i-1>(t).run_if_is_deferred_or_ready()) return true;
5758       return apply_any_run_if_is_deferred_or_ready<Tuple,i-1>()(t);
5759     }
5760   };
5761   template <class Tuple>
5762   struct apply_any_run_if_is_deferred_or_ready<Tuple, 0> {
5763     bool operator ()(Tuple& )
5764     {
5765       return false;
5766     }
5767   };
5768 
5769   template< typename Tuple, typename T0, typename ...T >
5770   struct future_when_any_tuple_shared_state: future_async_shared_state_base<Tuple>
5771   {
5772     Tuple tup_;
5773     typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5774 
5775     static void run(shared_ptr<boost::detail::shared_state_base> that_)
5776     {
5777       future_when_any_tuple_shared_state* that = static_cast<future_when_any_tuple_shared_state*>(that_.get());
5778       try {
5779         // TODO make use of apply(that->tup_, wait_for_any_fctr);
5780         that->wait_for_any(Index());
5781 
5782         that->mark_finished_with_result(boost::move(that->tup_));
5783       } catch(...) {
5784         that->mark_exceptional_finish();
5785       }
5786     }
5787     template <size_t ...Indices>
5788     void wait_for_any(tuple_indices<Indices...>) {
5789 #if defined BOOST_THREAD_PROVIDES_INVOKE
5790       return invoke<void>(wait_for_any_fctr(), csbl::get<Indices>(tup_)...);
5791 #else
5792       return wait_for_any_fctr()(csbl::get<Indices>(tup_)...);
5793 #endif
5794     }
5795     bool run_deferred() {
5796       return apply_any_run_if_is_deferred_or_ready<Tuple>()(tup_);
5797     }
5798     void init() {
5799       if (run_deferred())
5800       {
5801         future_when_any_tuple_shared_state::run(this->shared_from_this());
5802         return;
5803       }
5804 
5805 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5806       this->thr_ = boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this());
5807 #else
5808       boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this()).detach();
5809 #endif
5810     }
5811 
5812   public:
5813     template< typename F, typename ...Fs>
5814     future_when_any_tuple_shared_state(values_tag,
5815         BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures
5816     ) :
5817       tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5818     {
5819     }
5820 
5821     ~future_when_any_tuple_shared_state() {}
5822   };
5823 #endif
5824 
5825 }
5826 
5827   template< typename InputIterator>
5828   typename boost::disable_if<is_future_type<InputIterator>,
5829     BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
5830   >::type
5831   when_all(InputIterator first, InputIterator last) {
5832     typedef  typename InputIterator::value_type value_type;
5833     typedef  csbl::vector<value_type> container_type;
5834     typedef  detail::future_when_all_vector_shared_state<value_type> factory_type;
5835 
5836     if (first==last) return make_ready_future(container_type());
5837     shared_ptr<factory_type >
5838         h(new factory_type(detail::input_iterator_tag_value, first,last));
5839     h->init();
5840     return BOOST_THREAD_FUTURE<container_type>(h);
5841   }
5842 
5843   inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all() {
5844     return make_ready_future(csbl::tuple<>());
5845   }
5846 
5847 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5848   template< typename T0, typename ...T>
5849   BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5850   when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5851     typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5852     typedef detail::future_when_all_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5853 
5854     shared_ptr<factory_type>
5855         h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5856     h->init();
5857     return BOOST_THREAD_FUTURE<container_type>(h);
5858   }
5859 #endif
5860 
5861   template< typename InputIterator>
5862   typename boost::disable_if<is_future_type<InputIterator>,
5863     BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
5864   >::type
5865   when_any(InputIterator first, InputIterator last) {
5866     typedef  typename InputIterator::value_type value_type;
5867     typedef  csbl::vector<value_type> container_type;
5868     typedef  detail::future_when_any_vector_shared_state<value_type> factory_type;
5869 
5870     if (first==last) return make_ready_future(container_type());
5871     shared_ptr<factory_type >
5872         h(new factory_type(detail::input_iterator_tag_value, first,last));
5873     h->init();
5874     return BOOST_THREAD_FUTURE<container_type>(h);
5875   }
5876 
5877   inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any() {
5878     return make_ready_future(csbl::tuple<>());
5879   }
5880 
5881 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5882   template< typename T0, typename ...T>
5883   BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5884   when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5885     typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5886     typedef detail::future_when_any_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5887 
5888     shared_ptr<factory_type>
5889         h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5890     h->init();
5891     return BOOST_THREAD_FUTURE<container_type>(h);
5892   }
5893 #endif
5894 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
5895 }
5896 
5897 #endif // BOOST_NO_EXCEPTIONS
5898 #endif // header
5899