LCOV - code coverage report
Current view: top level - usr/include/boost/thread - future.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 52 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14