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