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