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