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