Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:09:30

0001 //  (C) Copyright 2008-10 Anthony Williams
0002 //  (C) Copyright 2011-2015 Vicente J. Botet Escriba
0003 //
0004 //  Distributed under the Boost Software License, Version 1.0. (See
0005 //  accompanying file LICENSE_1_0.txt or copy at
0006 //  http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_THREAD_FUTURE_HPP
0009 #define BOOST_THREAD_FUTURE_HPP
0010 
0011 #include <boost/thread/detail/config.hpp>
0012 
0013 // boost::thread::future requires exception handling
0014 // due to boost::exception::exception_ptr dependency
0015 
0016 //#define BOOST_THREAD_CONTINUATION_SYNC
0017 
0018 #ifdef BOOST_NO_EXCEPTIONS
0019 namespace boost
0020 {
0021 namespace detail {
0022 struct shared_state_base {
0023     void notify_deferred() {}
0024 };
0025 }
0026 }
0027 #else
0028 
0029 #include <boost/thread/condition_variable.hpp>
0030 #include <boost/thread/detail/move.hpp>
0031 #include <boost/thread/detail/invoker.hpp>
0032 #include <boost/thread/detail/invoke.hpp>
0033 #include <boost/thread/detail/is_convertible.hpp>
0034 #include <boost/thread/exceptional_ptr.hpp>
0035 #include <boost/thread/futures/future_error.hpp>
0036 #include <boost/thread/futures/future_error_code.hpp>
0037 #include <boost/thread/futures/future_status.hpp>
0038 #include <boost/thread/futures/is_future_type.hpp>
0039 #include <boost/thread/futures/launch.hpp>
0040 #include <boost/thread/futures/wait_for_all.hpp>
0041 #include <boost/thread/futures/wait_for_any.hpp>
0042 #include <boost/thread/lock_algorithms.hpp>
0043 #include <boost/thread/lock_types.hpp>
0044 #include <boost/thread/mutex.hpp>
0045 #include <boost/thread/thread_only.hpp>
0046 #include <boost/thread/thread_time.hpp>
0047 #include <boost/thread/executor.hpp>
0048 #include <boost/thread/executors/generic_executor_ref.hpp>
0049 
0050 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0051 #include <boost/optional.hpp>
0052 #else
0053 #include <boost/thread/csbl/memory/unique_ptr.hpp>
0054 #endif
0055 
0056 #include <boost/assert.hpp>
0057 #include <boost/bind/bind.hpp>
0058 #ifdef BOOST_THREAD_USES_CHRONO
0059 #include <boost/chrono/system_clocks.hpp>
0060 #endif
0061 #include <boost/core/enable_if.hpp>
0062 #include <boost/core/ref.hpp>
0063 #include <boost/enable_shared_from_this.hpp>
0064 #include <boost/exception_ptr.hpp>
0065 #include <boost/function.hpp>
0066 #include <boost/scoped_array.hpp>
0067 #include <boost/shared_ptr.hpp>
0068 #include <boost/smart_ptr/make_shared.hpp>
0069 #include <boost/throw_exception.hpp>
0070 #include <boost/type_traits/conditional.hpp>
0071 #include <boost/type_traits/decay.hpp>
0072 #include <boost/type_traits/is_copy_constructible.hpp>
0073 #include <boost/type_traits/is_fundamental.hpp>
0074 #include <boost/type_traits/is_void.hpp>
0075 #include <boost/utility/result_of.hpp>
0076 
0077 
0078 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
0079 #include <boost/thread/detail/memory.hpp>
0080 #include <boost/container/scoped_allocator.hpp>
0081 #if ! defined  BOOST_NO_CXX11_ALLOCATOR
0082 #include <memory>
0083 #endif
0084 #endif
0085 
0086 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
0087 #include <boost/thread/csbl/tuple.hpp>
0088 #include <boost/thread/csbl/vector.hpp>
0089 #endif
0090 
0091 #include <algorithm>
0092 #include <list>
0093 #include <vector>
0094 #include <utility>
0095 
0096 #if defined BOOST_THREAD_PROVIDES_FUTURE
0097 #define BOOST_THREAD_FUTURE future
0098 #else
0099 #define BOOST_THREAD_FUTURE unique_future
0100 #endif
0101 
0102 namespace boost
0103 {
0104   template <class T>
0105   shared_ptr<T> static_shared_from_this(T* that)
0106   {
0107     return static_pointer_cast<T>(that->shared_from_this());
0108   }
0109   template <class T>
0110   shared_ptr<T const> static_shared_from_this(T const* that)
0111   {
0112     return static_pointer_cast<T const>(that->shared_from_this());
0113   }
0114 
0115 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
0116 #else
0117     namespace executors {
0118         class executor;
0119     }
0120     using executors::executor;
0121 #endif
0122     typedef shared_ptr<executor> executor_ptr_type;
0123 
0124     namespace detail
0125     {
0126 
0127         struct relocker
0128         {
0129             boost::unique_lock<boost::mutex>& lock_;
0130 
0131             relocker(boost::unique_lock<boost::mutex>& lk):
0132                 lock_(lk)
0133             {
0134                 lock_.unlock();
0135             }
0136             ~relocker()
0137             {
0138               if (! lock_.owns_lock()) {
0139                 lock_.lock();
0140               }
0141             }
0142             void lock() {
0143               if (! lock_.owns_lock()) {
0144                 lock_.lock();
0145               }
0146             }
0147         private:
0148             relocker& operator=(relocker const&);
0149         };
0150 
0151         struct shared_state_base : enable_shared_from_this<shared_state_base>
0152         {
0153             typedef std::list<boost::condition_variable_any*> waiter_list;
0154             typedef waiter_list::iterator notify_when_ready_handle;
0155             // This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
0156             typedef shared_ptr<shared_state_base> continuation_ptr_type;
0157             typedef std::vector<continuation_ptr_type> continuations_type;
0158 
0159             boost::exception_ptr exception;
0160             bool done;
0161             bool is_valid_;
0162             bool is_deferred_;
0163             bool is_constructed;
0164             launch policy_;
0165             mutable boost::mutex mutex;
0166             boost::condition_variable waiters;
0167             waiter_list external_waiters;
0168             boost::function<void()> callback;
0169             // This declaration should be only included conditionally, but is included to maintain the same layout.
0170             continuations_type continuations;
0171             executor_ptr_type ex_;
0172 
0173             // This declaration should be only included conditionally, but is included to maintain the same layout.
0174             virtual void launch_continuation()
0175             {
0176             }
0177 
0178             shared_state_base():
0179                 done(false),
0180                 is_valid_(true),
0181                 is_deferred_(false),
0182                 is_constructed(false),
0183                 policy_(launch::none),
0184                 continuations(),
0185                 ex_()
0186             {}
0187 
0188             shared_state_base(exceptional_ptr const& ex):
0189                 exception(ex.ptr_),
0190                 done(true),
0191                 is_valid_(true),
0192                 is_deferred_(false),
0193                 is_constructed(false),
0194                 policy_(launch::none),
0195                 continuations(),
0196                 ex_()
0197             {}
0198 
0199 
0200             virtual ~shared_state_base()
0201             {
0202             }
0203 
0204             bool is_done()
0205             {
0206                 return done;
0207             }
0208 
0209             executor_ptr_type get_executor()
0210             {
0211               return ex_;
0212             }
0213 
0214             void set_executor_policy(executor_ptr_type aex)
0215             {
0216               set_executor();
0217               ex_ = aex;
0218             }
0219             void set_executor_policy(executor_ptr_type aex, boost::lock_guard<boost::mutex>&)
0220             {
0221               set_executor();
0222               ex_ = aex;
0223             }
0224             void set_executor_policy(executor_ptr_type aex, boost::unique_lock<boost::mutex>&)
0225             {
0226               set_executor();
0227               ex_ = aex;
0228             }
0229 
0230             bool valid(boost::unique_lock<boost::mutex>&) { return is_valid_; }
0231             bool valid() {
0232               boost::unique_lock<boost::mutex> lk(this->mutex);
0233               return valid(lk);
0234             }
0235             void invalidate(boost::unique_lock<boost::mutex>&) { is_valid_ = false; }
0236             void invalidate() {
0237               boost::unique_lock<boost::mutex> lk(this->mutex);
0238               invalidate(lk);
0239             }
0240             void validate(boost::unique_lock<boost::mutex>&) { is_valid_ = true; }
0241             void validate() {
0242               boost::unique_lock<boost::mutex> lk(this->mutex);
0243               validate(lk);
0244             }
0245 
0246             void set_deferred()
0247             {
0248               is_deferred_ = true;
0249               policy_ = launch::deferred;
0250             }
0251             void set_async()
0252             {
0253               is_deferred_ = false;
0254               policy_ = launch::async;
0255             }
0256 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
0257             void set_executor()
0258             {
0259               is_deferred_ = false;
0260               policy_ = launch::executor;
0261             }
0262 #else
0263             void set_executor()
0264             {
0265             }
0266 #endif
0267             notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
0268             {
0269                 boost::unique_lock<boost::mutex> lock(this->mutex);
0270                 do_callback(lock);
0271                 return external_waiters.insert(external_waiters.end(),&cv);
0272             }
0273 
0274             void unnotify_when_ready(notify_when_ready_handle it)
0275             {
0276                 boost::lock_guard<boost::mutex> lock(this->mutex);
0277                 external_waiters.erase(it);
0278             }
0279 
0280 #if 0
0281             // this inline definition results in ODR. See https://github.com/boostorg/thread/issues/193
0282             // to avoid it, we define the function on the derived templates using the macro BOOST_THREAD_DO_CONTINUATION
0283 #define BOOST_THREAD_DO_CONTINUATION
0284 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
0285             void do_continuation(boost::unique_lock<boost::mutex>& lock)
0286             {
0287                 if (! continuations.empty()) {
0288                   continuations_type the_continuations = continuations;
0289                   continuations.clear();
0290                   relocker rlk(lock);
0291                   for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) {
0292                     (*it)->launch_continuation();
0293                   }
0294                 }
0295             }
0296 #else
0297             void do_continuation(boost::unique_lock<boost::mutex>&)
0298             {
0299             }
0300 #endif
0301 
0302 #else
0303 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
0304 #define BOOST_THREAD_DO_CONTINUATION \
0305             void do_continuation(boost::unique_lock<boost::mutex>& lock) \
0306             { \
0307                 if (! this->continuations.empty()) { \
0308                   continuations_type the_continuations = this->continuations; \
0309                   this->continuations.clear(); \
0310                   relocker rlk(lock); \
0311                   for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) { \
0312                     (*it)->launch_continuation(); \
0313                   } \
0314                 } \
0315             }
0316 #else
0317 #define BOOST_THREAD_DO_CONTINUATION \
0318             void do_continuation(boost::unique_lock<boost::mutex>&) \
0319             { \
0320             }
0321 #endif
0322 
0323             virtual void do_continuation(boost::unique_lock<boost::mutex>&) = 0;
0324 #endif
0325 
0326 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
0327             virtual void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
0328             {
0329               continuations.push_back(continuation);
0330               if (done) {
0331                 do_continuation(lock);
0332               }
0333             }
0334 #endif
0335             void mark_finished_internal(boost::unique_lock<boost::mutex>& lock)
0336             {
0337                 done=true;
0338                 waiters.notify_all();
0339                 for(waiter_list::const_iterator it=external_waiters.begin(),
0340                         end=external_waiters.end();it!=end;++it)
0341                 {
0342                     (*it)->notify_all();
0343                 }
0344                 do_continuation(lock);
0345             }
0346             void notify_deferred()
0347             {
0348               boost::unique_lock<boost::mutex> lock(this->mutex);
0349               mark_finished_internal(lock);
0350             }
0351 
0352             void do_callback(boost::unique_lock<boost::mutex>& lock)
0353             {
0354                 if(callback && !done)
0355                 {
0356                     boost::function<void()> local_callback=callback;
0357                     relocker relock(lock);
0358                     local_callback();
0359                 }
0360             }
0361 
0362             virtual bool run_if_is_deferred()
0363             {
0364               boost::unique_lock<boost::mutex> lk(this->mutex);
0365               if (is_deferred_)
0366               {
0367                 is_deferred_=false;
0368                 execute(lk);
0369                 return true;
0370               }
0371               else
0372                 return false;
0373             }
0374             virtual bool run_if_is_deferred_or_ready()
0375             {
0376               boost::unique_lock<boost::mutex> lk(this->mutex);
0377               if (is_deferred_)
0378               {
0379                 is_deferred_=false;
0380                 execute(lk);
0381 
0382                 return true;
0383               }
0384               else
0385                 return done;
0386             }
0387             void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true)
0388             {
0389               do_callback(lk);
0390               if (is_deferred_)
0391               {
0392                 is_deferred_=false;
0393                 execute(lk);
0394               }
0395               waiters.wait(lk, boost::bind(&shared_state_base::is_done, boost::ref(*this)));
0396               if(rethrow && exception)
0397               {
0398                   boost::rethrow_exception(exception);
0399               }
0400             }
0401 
0402             virtual void wait(boost::unique_lock<boost::mutex>& lock, bool rethrow=true)
0403             {
0404                 wait_internal(lock, rethrow);
0405             }
0406 
0407             void wait(bool rethrow=true)
0408             {
0409                 boost::unique_lock<boost::mutex> lock(this->mutex);
0410                 wait(lock, rethrow);
0411             }
0412 
0413 #if defined BOOST_THREAD_USES_DATETIME
0414             template<typename Duration>
0415             bool timed_wait(Duration const& rel_time)
0416             {
0417                 boost::unique_lock<boost::mutex> lock(this->mutex);
0418                 if (is_deferred_)
0419                     return false;
0420 
0421                 do_callback(lock);
0422                 return waiters.timed_wait(lock, rel_time, boost::bind(&shared_state_base::is_done, boost::ref(*this)));
0423             }
0424 
0425             bool timed_wait_until(boost::system_time const& target_time)
0426             {
0427                 boost::unique_lock<boost::mutex> lock(this->mutex);
0428                 if (is_deferred_)
0429                     return false;
0430 
0431                 do_callback(lock);
0432                 return waiters.timed_wait(lock, target_time, boost::bind(&shared_state_base::is_done, boost::ref(*this)));
0433             }
0434 #endif
0435 #ifdef BOOST_THREAD_USES_CHRONO
0436 
0437             template <class Clock, class Duration>
0438             future_status
0439             wait_until(const chrono::time_point<Clock, Duration>& abs_time)
0440             {
0441               boost::unique_lock<boost::mutex> lock(this->mutex);
0442               if (is_deferred_)
0443                   return future_status::deferred;
0444               do_callback(lock);
0445               if(!waiters.wait_until(lock, abs_time, boost::bind(&shared_state_base::is_done, boost::ref(*this))))
0446               {
0447                   return future_status::timeout;
0448               }
0449               return future_status::ready;
0450             }
0451 #endif
0452             void mark_exceptional_finish_internal(boost::exception_ptr const& e, boost::unique_lock<boost::mutex>& lock)
0453             {
0454                 exception=e;
0455                 mark_finished_internal(lock);
0456             }
0457 
0458             void mark_exceptional_finish()
0459             {
0460                 boost::unique_lock<boost::mutex> lock(this->mutex);
0461                 mark_exceptional_finish_internal(boost::current_exception(), lock);
0462             }
0463 
0464             void set_exception_deferred(exception_ptr e)
0465             {
0466               unique_lock<boost::mutex> lk(this->mutex);
0467               if (has_value(lk))
0468               {
0469                   throw_exception(promise_already_satisfied());
0470               }
0471               exception=e;
0472               this->is_constructed = true;
0473             }
0474             void set_exception_at_thread_exit(exception_ptr e)
0475             {
0476               set_exception_deferred(e);
0477 //              unique_lock<boost::mutex> lk(this->mutex);
0478 //              if (has_value(lk))
0479 //              {
0480 //                  throw_exception(promise_already_satisfied());
0481 //              }
0482 //              exception=e;
0483 //              this->is_constructed = true;
0484               detail::make_ready_at_thread_exit(shared_from_this());
0485             }
0486 
0487             bool has_value() const
0488             {
0489                 boost::lock_guard<boost::mutex> lock(this->mutex);
0490                 return done && ! exception;
0491             }
0492 
0493             bool has_value(unique_lock<boost::mutex>& )  const
0494             {
0495                 return done && ! exception;
0496             }
0497 
0498             bool has_exception()  const
0499             {
0500                 boost::lock_guard<boost::mutex> lock(this->mutex);
0501                 return done && exception;
0502             }
0503 
0504             launch launch_policy(boost::unique_lock<boost::mutex>&) const
0505             {
0506                 return policy_;
0507             }
0508 
0509             future_state::state get_state(boost::unique_lock<boost::mutex>&) const
0510             {
0511                 if(!done)
0512                 {
0513                     return future_state::waiting;
0514                 }
0515                 else
0516                 {
0517                     return future_state::ready;
0518                 }
0519             }
0520             future_state::state get_state() const
0521             {
0522                 boost::lock_guard<boost::mutex> guard(this->mutex);
0523                 if(!done)
0524                 {
0525                     return future_state::waiting;
0526                 }
0527                 else
0528                 {
0529                     return future_state::ready;
0530                 }
0531             }
0532 
0533             exception_ptr get_exception_ptr()
0534             {
0535                 boost::unique_lock<boost::mutex> lock(this->mutex);
0536                 wait_internal(lock, false);
0537                 return exception;
0538             }
0539 
0540             template<typename F,typename U>
0541             void set_wait_callback(F f,U* u)
0542             {
0543                 boost::lock_guard<boost::mutex> lock(this->mutex);
0544                 callback=boost::bind(f,boost::ref(*u));
0545             }
0546 
0547             virtual void execute(boost::unique_lock<boost::mutex>&) {}
0548 
0549         private:
0550             shared_state_base(shared_state_base const&);
0551             shared_state_base& operator=(shared_state_base const&);
0552         };
0553 
0554         // Used to create stand-alone futures
0555         template<typename T>
0556         struct shared_state:
0557             detail::shared_state_base
0558         {
0559 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0560               typedef boost::optional<T> storage_type;
0561 #else
0562               typedef boost::csbl::unique_ptr<T> storage_type;
0563 #endif
0564 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0565             typedef T const& source_reference_type;
0566             typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
0567             typedef T move_dest_type;
0568 #elif defined BOOST_THREAD_USES_MOVE
0569             typedef typename conditional<boost::is_fundamental<T>::value,T,T const&>::type source_reference_type;
0570             typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
0571             typedef T move_dest_type;
0572 #else
0573             typedef T& source_reference_type;
0574             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;
0575             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;
0576 #endif
0577 
0578             typedef const T& shared_future_get_result_type;
0579 
0580             storage_type result;
0581 
0582             shared_state():
0583                 result()
0584             {}
0585             shared_state(exceptional_ptr const& ex):
0586               detail::shared_state_base(ex), result()
0587             {}
0588 
0589             // locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
0590             BOOST_THREAD_DO_CONTINUATION
0591 
0592             void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
0593             {
0594 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0595                 result = result_;
0596 #else
0597                 result.reset(new T(result_));
0598 #endif
0599                 this->mark_finished_internal(lock);
0600             }
0601 
0602             void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
0603             {
0604 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0605                 result = boost::move(result_);
0606 #elif ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
0607                 result.reset(new T(boost::move(result_)));
0608 #else
0609                 result.reset(new T(static_cast<rvalue_source_type>(result_)));
0610 #endif
0611                 this->mark_finished_internal(lock);
0612             }
0613 
0614 
0615 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0616             template <class ...Args>
0617             void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock, BOOST_THREAD_FWD_REF(Args)... args)
0618             {
0619 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0620                 result.emplace(boost::forward<Args>(args)...);
0621 #else
0622                 result.reset(new T(boost::forward<Args>(args)...));
0623 #endif
0624                 this->mark_finished_internal(lock);
0625             }
0626 #endif
0627 
0628             void mark_finished_with_result(source_reference_type result_)
0629             {
0630                 boost::unique_lock<boost::mutex> lock(this->mutex);
0631                 this->mark_finished_with_result_internal(result_, lock);
0632             }
0633 
0634             void mark_finished_with_result(rvalue_source_type result_)
0635             {
0636                 boost::unique_lock<boost::mutex> lock(this->mutex);
0637 
0638 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
0639                 mark_finished_with_result_internal(boost::move(result_), lock);
0640 #else
0641                 mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
0642 #endif
0643             }
0644 
0645             storage_type& get_storage(boost::unique_lock<boost::mutex>& lk)
0646             {
0647                 wait_internal(lk);
0648                 return result;
0649             }
0650             virtual move_dest_type get(boost::unique_lock<boost::mutex>& lk)
0651             {
0652                 return boost::move(*get_storage(lk));
0653             }
0654             move_dest_type get()
0655             {
0656                 boost::unique_lock<boost::mutex> lk(this->mutex);
0657                 return this->get(lk);
0658             }
0659 
0660             virtual shared_future_get_result_type get_sh(boost::unique_lock<boost::mutex>& lk)
0661             {
0662                 return *get_storage(lk);
0663             }
0664             shared_future_get_result_type get_sh()
0665             {
0666                 boost::unique_lock<boost::mutex> lk(this->mutex);
0667                 return this->get_sh(lk);
0668             }
0669             void set_value_deferred(source_reference_type result_)
0670             {
0671               unique_lock<boost::mutex> lk(this->mutex);
0672               if (this->has_value(lk))
0673               {
0674                   throw_exception(promise_already_satisfied());
0675               }
0676 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0677               result = result_;
0678 #else
0679               result.reset(new T(result_));
0680 #endif
0681 
0682               this->is_constructed = true;
0683             }
0684             void set_value_deferred(rvalue_source_type result_)
0685             {
0686               unique_lock<boost::mutex> lk(this->mutex);
0687               if (this->has_value(lk))
0688               {
0689                   throw_exception(promise_already_satisfied());
0690               }
0691 
0692 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
0693 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0694                 result = boost::move(result_);
0695 #else
0696                 result.reset(new T(boost::move(result_)));
0697 #endif
0698 #else
0699 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0700                 result = boost::move(result_);
0701 #else
0702                 result.reset(new T(static_cast<rvalue_source_type>(result_)));
0703 #endif
0704 #endif
0705               this->is_constructed = true;
0706             }
0707 
0708             void set_value_at_thread_exit(source_reference_type result_)
0709             {
0710                 set_value_deferred(result_);
0711 //              unique_lock<boost::mutex> lk(this->mutex);
0712 //              if (this->has_value(lk))
0713 //              {
0714 //                  throw_exception(promise_already_satisfied());
0715 //              }
0716 //#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0717 //              result = result_;
0718 //#else
0719 //              result.reset(new T(result_));
0720 //#endif
0721 //
0722 //              this->is_constructed = true;
0723               detail::make_ready_at_thread_exit(shared_from_this());
0724             }
0725             void set_value_at_thread_exit(rvalue_source_type result_)
0726             {
0727                 set_value_deferred(boost::move(result_));
0728 //              unique_lock<boost::mutex> lk(this->mutex);
0729 //              if (this->has_value(lk))
0730 //                  throw_exception(promise_already_satisfied());
0731 //
0732 //#if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
0733 //#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0734 //                result = boost::move(result_);
0735 //#else
0736 //                result.reset(new T(boost::move(result_)));
0737 //#endif
0738 //#else
0739 //#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
0740 //                result = boost::move(result_);
0741 //#else
0742 //                result.reset(new T(static_cast<rvalue_source_type>(result_)));
0743 //#endif
0744 //#endif
0745 //              this->is_constructed = true;
0746               detail::make_ready_at_thread_exit(shared_from_this());
0747             }
0748 
0749         private:
0750             shared_state(shared_state const&);
0751             shared_state& operator=(shared_state const&);
0752         };
0753 
0754         template<typename T>
0755         struct shared_state<T&>:
0756             detail::shared_state_base
0757         {
0758             typedef T* storage_type;
0759             typedef T& source_reference_type;
0760             typedef T& move_dest_type;
0761             typedef T& shared_future_get_result_type;
0762 
0763             T* result;
0764 
0765             shared_state():
0766                 result(0)
0767             {}
0768 
0769             shared_state(exceptional_ptr const& ex):
0770               detail::shared_state_base(ex), result(0)
0771             {}
0772 
0773             // locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
0774             BOOST_THREAD_DO_CONTINUATION
0775 
0776             void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
0777             {
0778                 result= &result_;
0779                 mark_finished_internal(lock);
0780             }
0781 
0782             void mark_finished_with_result(source_reference_type result_)
0783             {
0784                 boost::unique_lock<boost::mutex> lock(this->mutex);
0785                 mark_finished_with_result_internal(result_, lock);
0786             }
0787 
0788             virtual T& get(boost::unique_lock<boost::mutex>& lock)
0789             {
0790                 wait_internal(lock);
0791                 return *result;
0792             }
0793             T& get()
0794             {
0795                 boost::unique_lock<boost::mutex> lk(this->mutex);
0796                 return get(lk);
0797             }
0798 
0799             virtual T& get_sh(boost::unique_lock<boost::mutex>& lock)
0800             {
0801                 wait_internal(lock);
0802                 return *result;
0803             }
0804             T& get_sh()
0805             {
0806                 boost::unique_lock<boost::mutex> lock(this->mutex);
0807                 return get_sh(lock);
0808             }
0809 
0810             void set_value_deferred(T& result_)
0811             {
0812               unique_lock<boost::mutex> lk(this->mutex);
0813               if (this->has_value(lk))
0814               {
0815                   throw_exception(promise_already_satisfied());
0816               }
0817               result= &result_;
0818               this->is_constructed = true;
0819             }
0820 
0821             void set_value_at_thread_exit(T& result_)
0822             {
0823               set_value_deferred(result_);
0824 //              unique_lock<boost::mutex> lk(this->mutex);
0825 //              if (this->has_value(lk))
0826 //                  throw_exception(promise_already_satisfied());
0827 //              result= &result_;
0828 //              this->is_constructed = true;
0829               detail::make_ready_at_thread_exit(shared_from_this());
0830             }
0831 
0832         private:
0833             shared_state(shared_state const&);
0834             shared_state& operator=(shared_state const&);
0835         };
0836 
0837         template<>
0838         struct shared_state<void>:
0839             detail::shared_state_base
0840         {
0841             typedef void shared_future_get_result_type;
0842             typedef void move_dest_type;
0843 
0844             shared_state()
0845             {}
0846 
0847             shared_state(exceptional_ptr const& ex):
0848               detail::shared_state_base(ex)
0849             {}
0850 
0851             // locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
0852             BOOST_THREAD_DO_CONTINUATION
0853 
0854             void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
0855             {
0856                 mark_finished_internal(lock);
0857             }
0858 
0859             void mark_finished_with_result()
0860             {
0861                 boost::unique_lock<boost::mutex> lock(this->mutex);
0862                 mark_finished_with_result_internal(lock);
0863             }
0864 
0865             virtual void get(boost::unique_lock<boost::mutex>& lock)
0866             {
0867                 this->wait_internal(lock);
0868             }
0869             void get()
0870             {
0871                 boost::unique_lock<boost::mutex> lock(this->mutex);
0872                 this->get(lock);
0873             }
0874 
0875             virtual void get_sh(boost::unique_lock<boost::mutex>& lock)
0876             {
0877                 this->wait_internal(lock);
0878             }
0879             void get_sh()
0880             {
0881                 boost::unique_lock<boost::mutex> lock(this->mutex);
0882                 this->get_sh(lock);
0883             }
0884 
0885             void set_value_deferred()
0886             {
0887               unique_lock<boost::mutex> lk(this->mutex);
0888               if (this->has_value(lk))
0889               {
0890                   throw_exception(promise_already_satisfied());
0891               }
0892               this->is_constructed = true;
0893             }
0894             void set_value_at_thread_exit()
0895             {
0896               set_value_deferred();
0897 //              unique_lock<boost::mutex> lk(this->mutex);
0898 //              if (this->has_value(lk))
0899 //              {
0900 //                  throw_exception(promise_already_satisfied());
0901 //              }
0902 //              this->is_constructed = true;
0903               detail::make_ready_at_thread_exit(shared_from_this());
0904             }
0905         private:
0906             shared_state(shared_state const&);
0907             shared_state& operator=(shared_state const&);
0908         };
0909 
0910         /////////////////////////
0911         /// future_async_shared_state_base
0912         /////////////////////////
0913         template<typename Rp>
0914         struct future_async_shared_state_base: shared_state<Rp>
0915         {
0916           typedef shared_state<Rp> base_type;
0917         protected:
0918 #ifdef BOOST_THREAD_FUTURE_BLOCKING
0919           boost::thread thr_;
0920           void join()
0921           {
0922               if (this_thread::get_id() == thr_.get_id())
0923               {
0924                   thr_.detach();
0925                   return;
0926               }
0927               if (thr_.joinable()) thr_.join();
0928           }
0929 #endif
0930         public:
0931           future_async_shared_state_base()
0932           {
0933             this->set_async();
0934           }
0935 
0936           ~future_async_shared_state_base()
0937           {
0938 #ifdef BOOST_THREAD_FUTURE_BLOCKING
0939             join();
0940 #elif defined BOOST_THREAD_ASYNC_FUTURE_WAITS
0941             unique_lock<boost::mutex> lk(this->mutex);
0942             this->waiters.wait(lk, boost::bind(&shared_state_base::is_done, boost::ref(*this)));
0943 #endif
0944           }
0945 
0946           virtual void wait(boost::unique_lock<boost::mutex>& lk, bool rethrow)
0947           {
0948 #ifdef BOOST_THREAD_FUTURE_BLOCKING
0949               {
0950                 relocker rlk(lk);
0951                 join();
0952               }
0953 #endif
0954               this->base_type::wait(lk, rethrow);
0955           }
0956         };
0957 
0958         /////////////////////////
0959         /// future_async_shared_state
0960         /////////////////////////
0961         template<typename Rp, typename Fp>
0962         struct future_async_shared_state: future_async_shared_state_base<Rp>
0963         {
0964           future_async_shared_state()
0965           {
0966           }
0967 
0968           void init(BOOST_THREAD_FWD_REF(Fp) f)
0969           {
0970 #ifdef BOOST_THREAD_FUTURE_BLOCKING
0971             this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f));
0972 #else
0973             boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f)).detach();
0974 #endif
0975           }
0976 
0977           static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
0978           {
0979             try
0980             {
0981               that->mark_finished_with_result(f());
0982             }
0983             catch(...)
0984             {
0985               that->mark_exceptional_finish();
0986             }
0987           }
0988         };
0989 
0990         template<typename Fp>
0991         struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void>
0992         {
0993           void init(BOOST_THREAD_FWD_REF(Fp) f)
0994           {
0995 #ifdef BOOST_THREAD_FUTURE_BLOCKING
0996             this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
0997 #else
0998             boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
0999 #endif
1000           }
1001 
1002           static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
1003           {
1004             try
1005             {
1006               f();
1007               that->mark_finished_with_result();
1008             }
1009             catch(...)
1010             {
1011               that->mark_exceptional_finish();
1012             }
1013           }
1014         };
1015 
1016         template<typename Rp, typename Fp>
1017         struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&>
1018         {
1019           void init(BOOST_THREAD_FWD_REF(Fp) f)
1020           {
1021 #ifdef BOOST_THREAD_FUTURE_BLOCKING
1022             this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
1023 #else
1024             boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
1025 #endif
1026           }
1027 
1028           static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
1029           {
1030             try
1031             {
1032               that->mark_finished_with_result(f());
1033             }
1034             catch(...)
1035             {
1036               that->mark_exceptional_finish();
1037             }
1038           }
1039         };
1040 
1041         //////////////////////////
1042         /// future_deferred_shared_state
1043         //////////////////////////
1044         template<typename Rp, typename Fp>
1045         struct future_deferred_shared_state: shared_state<Rp>
1046         {
1047           Fp func_;
1048 
1049           explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1050           : func_(boost::move(f))
1051           {
1052             this->set_deferred();
1053           }
1054 
1055           virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1056             try
1057             {
1058               Fp local_fuct=boost::move(func_);
1059               relocker relock(lck);
1060               Rp res = local_fuct();
1061               relock.lock();
1062               this->mark_finished_with_result_internal(boost::move(res), lck);
1063             }
1064             catch (...)
1065             {
1066               this->mark_exceptional_finish_internal(current_exception(), lck);
1067             }
1068           }
1069         };
1070         template<typename Rp, typename Fp>
1071         struct future_deferred_shared_state<Rp&,Fp>: shared_state<Rp&>
1072         {
1073           Fp func_;
1074 
1075           explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1076           : func_(boost::move(f))
1077           {
1078             this->set_deferred();
1079           }
1080 
1081           virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1082             try
1083             {
1084               this->mark_finished_with_result_internal(func_(), lck);
1085             }
1086             catch (...)
1087             {
1088               this->mark_exceptional_finish_internal(current_exception(), lck);
1089             }
1090           }
1091         };
1092 
1093         template<typename Fp>
1094         struct future_deferred_shared_state<void,Fp>: shared_state<void>
1095         {
1096           Fp func_;
1097 
1098           explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1099           : func_(boost::move(f))
1100           {
1101             this->set_deferred();
1102           }
1103 
1104           virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1105             try
1106             {
1107               Fp local_fuct=boost::move(func_);
1108               relocker relock(lck);
1109               local_fuct();
1110               relock.lock();
1111               this->mark_finished_with_result_internal(lck);
1112             }
1113             catch (...)
1114             {
1115               this->mark_exceptional_finish_internal(current_exception(), lck);
1116             }
1117           }
1118         };
1119 
1120         class future_waiter
1121         {
1122         public:
1123             typedef std::vector<int>::size_type count_type;
1124         private:
1125             struct registered_waiter
1126             {
1127                 boost::shared_ptr<detail::shared_state_base> future_;
1128                 detail::shared_state_base::notify_when_ready_handle handle;
1129                 count_type index;
1130 
1131                 registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
1132                                   detail::shared_state_base::notify_when_ready_handle handle_,
1133                                   count_type index_):
1134                     future_(a_future),handle(handle_),index(index_)
1135                 {}
1136             };
1137 
1138             struct all_futures_lock
1139             {
1140 #ifdef _MANAGED
1141                    typedef std::ptrdiff_t count_type_portable;
1142 #else
1143                    typedef count_type count_type_portable;
1144 #endif
1145                    count_type_portable count;
1146                    boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
1147 
1148                 all_futures_lock(std::vector<registered_waiter>& futures):
1149                     count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
1150                 {
1151                     for(count_type_portable i=0;i<count;++i)
1152                     {
1153                         locks[i]=BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(futures[i].future_->mutex));
1154                     }
1155                 }
1156 
1157                 void lock()
1158                 {
1159                     boost::lock(locks.get(),locks.get()+count);
1160                 }
1161 
1162                 void unlock()
1163                 {
1164                     for(count_type_portable i=0;i<count;++i)
1165                     {
1166                         locks[i].unlock();
1167                     }
1168                 }
1169             };
1170 
1171             boost::condition_variable_any cv;
1172             std::vector<registered_waiter> futures_;
1173             count_type future_count;
1174 
1175         public:
1176             future_waiter():
1177                 future_count(0)
1178             {}
1179 
1180             template<typename F>
1181             void add(F& f)
1182             {
1183                 if(f.future_)
1184                 {
1185                   registered_waiter waiter(f.future_,f.future_->notify_when_ready(cv),future_count);
1186                   try {
1187                     futures_.push_back(waiter);
1188                   } catch(...) {
1189                     f.future_->unnotify_when_ready(waiter.handle);
1190                     throw;
1191                   }
1192                 }
1193                 ++future_count;
1194             }
1195 
1196 #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1197             template<typename F1, typename... Fs>
1198             void add(F1& f1, Fs&... fs)
1199             {
1200               add(f1); add(fs...);
1201             }
1202 #endif
1203 
1204             count_type wait()
1205             {
1206                 all_futures_lock lk(futures_);
1207                 for(;;)
1208                 {
1209                     for(count_type i=0;i<futures_.size();++i)
1210                     {
1211                         if(futures_[i].future_->done)
1212                         {
1213                             return futures_[i].index;
1214                         }
1215                     }
1216                     cv.wait(lk);
1217                 }
1218             }
1219 
1220             ~future_waiter()
1221             {
1222                 for(count_type i=0;i<futures_.size();++i)
1223                 {
1224                     futures_[i].future_->unnotify_when_ready(futures_[i].handle);
1225                 }
1226             }
1227         };
1228 
1229     }
1230 
1231     template <typename R>
1232     class BOOST_THREAD_FUTURE;
1233 
1234     template <typename R>
1235     class shared_future;
1236 
1237     template<typename T>
1238     struct is_future_type<BOOST_THREAD_FUTURE<T> > : true_type
1239     {
1240     };
1241 
1242     template<typename T>
1243     struct is_future_type<shared_future<T> > : true_type
1244     {
1245     };
1246 
1247 //    template<typename Iterator>
1248 //    typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
1249 //    {
1250 //        if(begin==end)
1251 //            return end;
1252 //
1253 //        detail::future_waiter waiter;
1254 //        for(Iterator current=begin;current!=end;++current)
1255 //        {
1256 //            waiter.add(*current);
1257 //        }
1258 //        return boost::next(begin,waiter.wait());
1259 //    }
1260 
1261 #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1262     template<typename F1,typename F2>
1263     typename boost::enable_if<is_future_type<F1>,typename detail::future_waiter::count_type>::type wait_for_any(F1& f1,F2& f2)
1264     {
1265         detail::future_waiter waiter;
1266         waiter.add(f1);
1267         waiter.add(f2);
1268         return waiter.wait();
1269     }
1270 
1271     template<typename F1,typename F2,typename F3>
1272     typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3)
1273     {
1274         detail::future_waiter waiter;
1275         waiter.add(f1);
1276         waiter.add(f2);
1277         waiter.add(f3);
1278         return waiter.wait();
1279     }
1280 
1281     template<typename F1,typename F2,typename F3,typename F4>
1282     typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
1283     {
1284         detail::future_waiter waiter;
1285         waiter.add(f1);
1286         waiter.add(f2);
1287         waiter.add(f3);
1288         waiter.add(f4);
1289         return waiter.wait();
1290     }
1291 
1292     template<typename F1,typename F2,typename F3,typename F4,typename F5>
1293     typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
1294     {
1295         detail::future_waiter waiter;
1296         waiter.add(f1);
1297         waiter.add(f2);
1298         waiter.add(f3);
1299         waiter.add(f4);
1300         waiter.add(f5);
1301         return waiter.wait();
1302     }
1303 #else
1304     template<typename F1, typename... Fs>
1305     typename boost::enable_if<is_future_type<F1>, typename detail::future_waiter::count_type>::type
1306     wait_for_any(F1& f1, Fs&... fs)
1307     {
1308       detail::future_waiter waiter;
1309       waiter.add(f1, fs...);
1310       return waiter.wait();
1311     }
1312 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1313 
1314     template <typename R>
1315     class promise;
1316 
1317     template <typename R>
1318     class packaged_task;
1319 
1320     namespace detail
1321     {
1322       /// Common implementation for all the futures independently of the return type
1323       class base_future
1324       {
1325       public:
1326       };
1327       /// Common implementation for future and shared_future.
1328       template <typename R>
1329       class basic_future : public base_future
1330       {
1331       protected:
1332       public:
1333 
1334         typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
1335         typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
1336 
1337         static //BOOST_CONSTEXPR
1338         future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
1339           return future_ptr(new detail::shared_state<R>(ex));
1340         }
1341 
1342         future_ptr future_;
1343 
1344         basic_future(future_ptr a_future):
1345           future_(a_future)
1346         {
1347         }
1348 
1349       public:
1350         typedef future_state::state state;
1351 
1352         BOOST_THREAD_MOVABLE_ONLY(basic_future)
1353         basic_future(): future_() {}
1354 
1355 
1356         //BOOST_CONSTEXPR
1357         basic_future(exceptional_ptr const& ex)
1358           : future_(make_exceptional_future_ptr(ex))
1359         {
1360         }
1361 
1362         ~basic_future() {
1363         }
1364 
1365         basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
1366         future_(BOOST_THREAD_RV(other).future_)
1367         {
1368             BOOST_THREAD_RV(other).future_.reset();
1369         }
1370         basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
1371         {
1372             future_=BOOST_THREAD_RV(other).future_;
1373             BOOST_THREAD_RV(other).future_.reset();
1374             return *this;
1375         }
1376         void swap(basic_future& that) BOOST_NOEXCEPT
1377         {
1378           future_.swap(that.future_);
1379         }
1380         // functions to check state, and wait for ready
1381         state get_state(boost::unique_lock<boost::mutex>& lk) const
1382         {
1383             if(!future_)
1384             {
1385                 return future_state::uninitialized;
1386             }
1387             return future_->get_state(lk);
1388         }
1389         state get_state() const
1390         {
1391             if(!future_)
1392             {
1393                 return future_state::uninitialized;
1394             }
1395             return future_->get_state();
1396         }
1397 
1398         bool is_ready() const
1399         {
1400             return get_state()==future_state::ready;
1401         }
1402 
1403         bool is_ready(boost::unique_lock<boost::mutex>& lk) const
1404         {
1405             return get_state(lk)==future_state::ready;
1406         }
1407         bool has_exception() const
1408         {
1409             return future_ && future_->has_exception();
1410         }
1411 
1412         bool has_value() const
1413         {
1414             return future_ && future_->has_value();
1415         }
1416 
1417         launch launch_policy(boost::unique_lock<boost::mutex>& lk) const
1418         {
1419             if ( future_ ) return future_->launch_policy(lk);
1420             else return launch(launch::none);
1421         }
1422 
1423         launch launch_policy() const
1424         {
1425           if ( future_ ) {
1426             boost::unique_lock<boost::mutex> lk(this->future_->mutex);
1427             return future_->launch_policy(lk);
1428           }
1429           else return launch(launch::none);
1430         }
1431 
1432         exception_ptr get_exception_ptr()
1433         {
1434             return future_
1435                 ? future_->get_exception_ptr()
1436                 : exception_ptr();
1437         }
1438 
1439         bool valid() const BOOST_NOEXCEPT
1440         {
1441             return future_.get() != 0 && future_->valid();
1442         }
1443 
1444         void wait() const
1445         {
1446             if(!future_)
1447             {
1448                 boost::throw_exception(future_uninitialized());
1449             }
1450             future_->wait(false);
1451         }
1452 
1453         typedef detail::shared_state_base::notify_when_ready_handle notify_when_ready_handle;
1454 
1455         boost::mutex& mutex() {
1456           if(!future_)
1457           {
1458               boost::throw_exception(future_uninitialized());
1459           }
1460           return future_->mutex;
1461         }
1462 
1463         notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
1464         {
1465           if(!future_)
1466           {
1467               boost::throw_exception(future_uninitialized());
1468           }
1469           return future_->notify_when_ready(cv);
1470         }
1471 
1472         void unnotify_when_ready(notify_when_ready_handle h)
1473         {
1474           if(!future_)
1475           {
1476               boost::throw_exception(future_uninitialized());
1477           }
1478           return future_->unnotify_when_ready(h);
1479         }
1480 
1481 #if defined BOOST_THREAD_USES_DATETIME
1482         template<typename Duration>
1483         bool timed_wait(Duration const& rel_time) const
1484         {
1485             if(!future_)
1486             {
1487                 boost::throw_exception(future_uninitialized());
1488             }
1489             return future_->timed_wait(rel_time);
1490         }
1491 
1492         bool timed_wait_until(boost::system_time const& abs_time) const
1493         {
1494             if(!future_)
1495             {
1496                 boost::throw_exception(future_uninitialized());
1497             }
1498             return future_->timed_wait_until(abs_time);
1499         }
1500 #endif
1501 #ifdef BOOST_THREAD_USES_CHRONO
1502         template <class Rep, class Period>
1503         future_status
1504         wait_for(const chrono::duration<Rep, Period>& rel_time) const
1505         {
1506           return wait_until(chrono::steady_clock::now() + rel_time);
1507 
1508         }
1509         template <class Clock, class Duration>
1510         future_status
1511         wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
1512         {
1513           if(!future_)
1514           {
1515               boost::throw_exception(future_uninitialized());
1516           }
1517           return future_->wait_until(abs_time);
1518         }
1519 #endif
1520 
1521       };
1522 
1523     } // detail
1524     BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END
1525 
1526     namespace detail
1527     {
1528 #if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005
1529         template <class Rp, class Fp>
1530         BOOST_THREAD_FUTURE<Rp>
1531         make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1532 
1533         template <class Rp, class Fp>
1534         BOOST_THREAD_FUTURE<Rp>
1535         make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1536 #endif // #if (!defined _MSC_VER || _MSC_VER >= 1400)
1537 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1538         template<typename F, typename Rp, typename Fp>
1539         struct future_deferred_continuation_shared_state;
1540         template<typename F, typename Rp, typename Fp>
1541         struct future_async_continuation_shared_state;
1542 
1543         template <class F, class Rp, class Fp>
1544         BOOST_THREAD_FUTURE<Rp>
1545         make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1546 
1547         template <class F, class Rp, class Fp>
1548         BOOST_THREAD_FUTURE<Rp>
1549         make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1550 
1551         template <class F, class Rp, class Fp>
1552         BOOST_THREAD_FUTURE<Rp>
1553         make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1554 
1555         template<typename F, typename Rp, typename Fp>
1556         BOOST_THREAD_FUTURE<Rp>
1557         make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1558 
1559         template<typename F, typename Rp, typename Fp>
1560         BOOST_THREAD_FUTURE<Rp>
1561         make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1562 
1563         template<typename F, typename Rp, typename Fp>
1564         BOOST_THREAD_FUTURE<Rp>
1565         make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1566 
1567 
1568   #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1569         template<typename Ex, typename F, typename Rp, typename Fp>
1570         BOOST_THREAD_FUTURE<Rp>
1571         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);
1572 
1573         template<typename Ex, typename F, typename Rp, typename Fp>
1574         BOOST_THREAD_FUTURE<Rp>
1575         make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1576 
1577         template <class Rp, class Fp, class Executor>
1578         BOOST_THREAD_FUTURE<Rp>
1579         make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1580   #endif
1581 #endif
1582 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1583         template<typename F, typename Rp>
1584         struct future_unwrap_shared_state;
1585         template <class F, class Rp>
1586         inline BOOST_THREAD_FUTURE<Rp>
1587         make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1588 #endif
1589     }
1590 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1591       template< typename InputIterator>
1592       typename boost::disable_if<is_future_type<InputIterator>,
1593         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1594       >::type
1595       when_all(InputIterator first, InputIterator last);
1596 
1597       inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1598 
1599     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1600       template< typename T0, typename ...T>
1601       BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1602       when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1603     #endif
1604 
1605       template< typename InputIterator>
1606       typename boost::disable_if<is_future_type<InputIterator>,
1607         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1608       >::type
1609       when_any(InputIterator first, InputIterator last);
1610 
1611       inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1612 
1613     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1614       template< typename T0, typename ...T>
1615       BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1616       when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1617     #endif
1618 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1619 
1620 
1621     template <typename R>
1622     class BOOST_THREAD_FUTURE : public detail::basic_future<R>
1623     {
1624     private:
1625         typedef detail::basic_future<R> base_type;
1626         typedef typename base_type::future_ptr future_ptr;
1627 
1628         friend class shared_future<R>;
1629         friend class promise<R>;
1630 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1631         template <typename, typename, typename>
1632         friend struct detail::future_async_continuation_shared_state;
1633         template <typename, typename, typename>
1634         friend struct detail::future_deferred_continuation_shared_state;
1635 
1636         template <class F, class Rp, class Fp>
1637         friend BOOST_THREAD_FUTURE<Rp>
1638         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);
1639 
1640         template <class F, class Rp, class Fp>
1641         friend BOOST_THREAD_FUTURE<Rp>
1642         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);
1643 
1644         template <class F, class Rp, class Fp>
1645         friend BOOST_THREAD_FUTURE<Rp>
1646         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);
1647 
1648         template<typename F, typename Rp, typename Fp>
1649         friend BOOST_THREAD_FUTURE<Rp>
1650         detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1651 
1652         template<typename F, typename Rp, typename Fp>
1653         friend BOOST_THREAD_FUTURE<Rp>
1654         detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1655 
1656         template<typename F, typename Rp, typename Fp>
1657         friend BOOST_THREAD_FUTURE<Rp>
1658         detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1659 
1660   #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1661         template<typename Ex, typename F, typename Rp, typename Fp>
1662         friend BOOST_THREAD_FUTURE<Rp>
1663         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);
1664 
1665         template<typename Ex, typename F, typename Rp, typename Fp>
1666         friend BOOST_THREAD_FUTURE<Rp>
1667         detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1668 
1669         template <class Rp, class Fp, class Executor>
1670         friend BOOST_THREAD_FUTURE<Rp>
1671         detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1672   #endif
1673 #endif
1674 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1675         template<typename F, typename Rp>
1676         friend struct detail::future_unwrap_shared_state;
1677         template <class F, class Rp>
1678         friend BOOST_THREAD_FUTURE<Rp>
1679         detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1680 #endif
1681 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1682       template< typename InputIterator>
1683       friend typename boost::disable_if<is_future_type<InputIterator>,
1684         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1685       >::type
1686       when_all(InputIterator first, InputIterator last);
1687 
1688       //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1689 
1690     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1691       template< typename T0, typename ...T>
1692       friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1693       when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1694     #endif
1695 
1696       template< typename InputIterator>
1697       friend typename boost::disable_if<is_future_type<InputIterator>,
1698         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1699       >::type
1700       when_any(InputIterator first, InputIterator last);
1701 
1702       //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1703 
1704     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1705       template< typename T0, typename ...T>
1706       friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1707       when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1708     #endif
1709 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1710 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1711         template <class> friend class packaged_task; // todo check if this works in windows
1712 #else
1713         friend class packaged_task<R>;
1714 #endif
1715         friend class detail::future_waiter;
1716 
1717         template <class Rp, class Fp>
1718         friend BOOST_THREAD_FUTURE<Rp>
1719         detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1720 
1721         template <class Rp, class Fp>
1722         friend BOOST_THREAD_FUTURE<Rp>
1723         detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1724 
1725         typedef typename base_type::move_dest_type move_dest_type;
1726 
1727         BOOST_THREAD_FUTURE(future_ptr a_future):
1728           base_type(a_future)
1729         {
1730         }
1731 
1732     public:
1733         BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1734         typedef future_state::state state;
1735         typedef R value_type; // EXTENSION
1736 
1737         BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1738         //BOOST_CONSTEXPR
1739         BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1740             base_type(ex) {}
1741 
1742         ~BOOST_THREAD_FUTURE() {
1743         }
1744 
1745         BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1746         base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1747         {
1748         }
1749 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1750         inline explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
1751 #endif
1752 
1753         explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(shared_future<R>) other) :
1754         base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1755         {}
1756 
1757         BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
1758         {
1759             this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1760             return *this;
1761         }
1762 
1763         shared_future<R> share()
1764         {
1765           return shared_future<R>(::boost::move(*this));
1766         }
1767 
1768         void swap(BOOST_THREAD_FUTURE& other)
1769         {
1770             static_cast<base_type*>(this)->swap(other);
1771         }
1772 
1773         // todo this function must be private and friendship provided to the internal users.
1774         void set_async()
1775         {
1776           this->future_->set_async();
1777         }
1778         // todo this function must be private and friendship provided to the internal users.
1779         void set_deferred()
1780         {
1781           this->future_->set_deferred();
1782         }
1783         bool run_if_is_deferred() {
1784           return this->future_->run_if_is_deferred();
1785         }
1786         bool run_if_is_deferred_or_ready() {
1787           return this->future_->run_if_is_deferred_or_ready();
1788         }
1789         // retrieving the value
1790         move_dest_type get()
1791         {
1792             if (this->future_.get() == 0)
1793             {
1794                 boost::throw_exception(future_uninitialized());
1795             }
1796             unique_lock<boost::mutex> lk(this->future_->mutex);
1797             if (! this->future_->valid(lk))
1798             {
1799                 boost::throw_exception(future_uninitialized());
1800             }
1801 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1802             this->future_->invalidate(lk);
1803 #endif
1804             return this->future_->get(lk);
1805         }
1806 
1807         template <typename R2>
1808         typename boost::disable_if< is_void<R2>, move_dest_type>::type
1809         get_or(BOOST_THREAD_RV_REF(R2) v)
1810         {
1811 
1812             if (this->future_.get() == 0)
1813             {
1814                 boost::throw_exception(future_uninitialized());
1815             }
1816             unique_lock<boost::mutex> lk(this->future_->mutex);
1817             if (! this->future_->valid(lk))
1818             {
1819                 boost::throw_exception(future_uninitialized());
1820             }
1821             this->future_->wait(lk, false);
1822 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1823             this->future_->invalidate(lk);
1824 #endif
1825 
1826             if (this->future_->has_value(lk)) {
1827               return this->future_->get(lk);
1828             }
1829             else {
1830               return boost::move(v);
1831             }
1832         }
1833 
1834         template <typename R2>
1835         typename boost::disable_if< is_void<R2>, move_dest_type>::type
1836         get_or(R2 const& v)  // EXTENSION
1837         {
1838             if (this->future_.get() == 0)
1839             {
1840                 boost::throw_exception(future_uninitialized());
1841             }
1842             unique_lock<boost::mutex> lk(this->future_->mutex);
1843             if (! this->future_->valid(lk))
1844             {
1845                 boost::throw_exception(future_uninitialized());
1846             }
1847             this->future_->wait(lk, false);
1848 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1849             this->future_->invalidate(lk);
1850 #endif
1851             if (this->future_->has_value(lk)) {
1852               return this->future_->get(lk);
1853             }
1854             else {
1855               return v;
1856             }
1857         }
1858 
1859 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1860         template<typename F>
1861         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1862         then(BOOST_THREAD_FWD_REF(F) func);  // EXTENSION
1863         template<typename F>
1864         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1865         then(launch policy, BOOST_THREAD_FWD_REF(F) func);  // EXTENSION
1866   #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1867         template<typename Ex, typename F>
1868         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1869         then(Ex& ex, BOOST_THREAD_FWD_REF(F) func);  // EXTENSION
1870   #endif
1871 
1872         template <typename R2>
1873         inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1874         fallback_to(BOOST_THREAD_RV_REF(R2) v);  // EXTENSION
1875         template <typename R2>
1876         inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1877         fallback_to(R2 const& v);  // EXTENSION
1878 
1879 #endif
1880 
1881     };
1882 
1883     BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
1884 
1885         template <typename R2>
1886         class BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> > : public detail::basic_future<BOOST_THREAD_FUTURE<R2> >
1887         {
1888           typedef BOOST_THREAD_FUTURE<R2> R;
1889 
1890         private:
1891             typedef detail::basic_future<R> base_type;
1892             typedef typename base_type::future_ptr future_ptr;
1893 
1894             friend class shared_future<R>;
1895             friend class promise<R>;
1896 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1897             template <typename, typename, typename>
1898             friend struct detail::future_async_continuation_shared_state;
1899             template <typename, typename, typename>
1900             friend struct detail::future_deferred_continuation_shared_state;
1901 
1902             template <class F, class Rp, class Fp>
1903             friend BOOST_THREAD_FUTURE<Rp>
1904             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);
1905 
1906             template <class F, class Rp, class Fp>
1907             friend BOOST_THREAD_FUTURE<Rp>
1908             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);
1909 
1910             template <class F, class Rp, class Fp>
1911             friend BOOST_THREAD_FUTURE<Rp>
1912             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);
1913 
1914             template<typename F, typename Rp, typename Fp>
1915             friend BOOST_THREAD_FUTURE<Rp>
1916             detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1917 
1918             template<typename F, typename Rp, typename Fp>
1919             friend BOOST_THREAD_FUTURE<Rp>
1920             detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1921 
1922             template<typename F, typename Rp, typename Fp>
1923             friend BOOST_THREAD_FUTURE<Rp>
1924             detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1925 
1926       #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1927             template<typename Ex, typename F, typename Rp, typename Fp>
1928             friend BOOST_THREAD_FUTURE<Rp>
1929             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);
1930 
1931             template<typename Ex, typename F, typename Rp, typename Fp>
1932             friend BOOST_THREAD_FUTURE<Rp>
1933             detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1934 
1935             template <class Rp, class Fp, class Executor>
1936             friend BOOST_THREAD_FUTURE<Rp>
1937             detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1938       #endif
1939 
1940 #endif
1941 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1942             template<typename F, typename Rp>
1943             friend struct detail::future_unwrap_shared_state;
1944         template <class F, class Rp>
1945         friend BOOST_THREAD_FUTURE<Rp>
1946         detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1947 #endif
1948 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1949       template< typename InputIterator>
1950       friend typename boost::disable_if<is_future_type<InputIterator>,
1951         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1952       >::type
1953       when_all(InputIterator first, InputIterator last);
1954 
1955       friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1956 
1957     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1958       template< typename T0, typename ...T>
1959       friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1960       when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1961     #endif
1962 
1963       template< typename InputIterator>
1964       friend typename boost::disable_if<is_future_type<InputIterator>,
1965         BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
1966       >::type
1967       when_any(InputIterator first, InputIterator last);
1968 
1969       friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1970 
1971     #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1972       template< typename T0, typename ...T>
1973       friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1974       when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1975     #endif
1976 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1977 
1978     #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1979             template <class> friend class packaged_task; // todo check if this works in windows
1980     #else
1981             friend class packaged_task<R>;
1982     #endif
1983             friend class detail::future_waiter;
1984 
1985             template <class Rp, class Fp>
1986             friend BOOST_THREAD_FUTURE<Rp>
1987             detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1988 
1989             template <class Rp, class Fp>
1990             friend BOOST_THREAD_FUTURE<Rp>
1991             detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1992 
1993             typedef typename base_type::move_dest_type move_dest_type;
1994 
1995             BOOST_THREAD_FUTURE(future_ptr a_future):
1996               base_type(a_future)
1997             {
1998             }
1999         public:
2000 
2001             BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
2002             typedef future_state::state state;
2003             typedef R value_type; // EXTENSION
2004 
2005             BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
2006             //BOOST_CONSTEXPR
2007             BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
2008                 base_type(ex) {}
2009 
2010             ~BOOST_THREAD_FUTURE() {
2011             }
2012 
2013             BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
2014             base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2015             {
2016             }
2017 
2018             BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
2019             {
2020                 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2021                 return *this;
2022             }
2023 
2024             shared_future<R> share()
2025             {
2026               return shared_future<R>(::boost::move(*this));
2027             }
2028 
2029             void swap(BOOST_THREAD_FUTURE& other)
2030             {
2031                 static_cast<base_type*>(this)->swap(other);
2032             }
2033 
2034             // todo this function must be private and friendship provided to the internal users.
2035             void set_async()
2036             {
2037               this->future_->set_async();
2038             }
2039             // todo this function must be private and friendship provided to the internal users.
2040             void set_deferred()
2041             {
2042               this->future_->set_deferred();
2043             }
2044             bool run_if_is_deferred() {
2045               return this->future_->run_if_is_deferred();
2046             }
2047             bool run_if_is_deferred_or_ready() {
2048               return this->future_->run_if_is_deferred_or_ready();
2049             }
2050             // retrieving the value
2051             move_dest_type get()
2052             {
2053                 if (this->future_.get() == 0)
2054                 {
2055                     boost::throw_exception(future_uninitialized());
2056                 }
2057                 unique_lock<boost::mutex> lk(this->future_->mutex);
2058                 if (! this->future_->valid(lk))
2059                 {
2060                     boost::throw_exception(future_uninitialized());
2061                 }
2062     #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
2063                 this->future_->invalidate(lk);
2064     #endif
2065                 return this->future_->get(lk);
2066             }
2067             move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
2068             {
2069                 if (this->future_.get() == 0)
2070                 {
2071                     boost::throw_exception(future_uninitialized());
2072                 }
2073                 unique_lock<boost::mutex> lk(this->future_->mutex);
2074                 if (! this->future_->valid(lk))
2075                 {
2076                     boost::throw_exception(future_uninitialized());
2077                 }
2078                 this->future_->wait(lk, false);
2079     #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
2080                 this->future_->invalidate(lk);
2081     #endif
2082                 if (this->future_->has_value(lk)) return this->future_->get(lk);
2083                 else return boost::move(v);
2084             }
2085 
2086             move_dest_type get_or(R const& v) // EXTENSION
2087             {
2088                 if (this->future_.get() == 0)
2089                 {
2090                     boost::throw_exception(future_uninitialized());
2091                 }
2092                 unique_lock<boost::mutex> lk(this->future_->mutex);
2093                 if (! this->future_->valid(lk))
2094                 {
2095                     boost::throw_exception(future_uninitialized());
2096                 }
2097                 this->future_->wait(lk, false);
2098     #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
2099                 this->future_->invalidate(lk);
2100     #endif
2101                 if (this->future_->has_value(lk)) return this->future_->get(lk);
2102                 else return v;
2103             }
2104 
2105 
2106     #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2107             template<typename F>
2108             inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2109             then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2110             template<typename F>
2111             inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2112             then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2113       #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2114             template<typename Ex, typename F>
2115             inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2116             then(Ex &ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2117       #endif
2118     #endif
2119 
2120     #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
2121             inline
2122             BOOST_THREAD_FUTURE<R2>
2123             unwrap(); // EXTENSION
2124     #endif
2125 
2126   };
2127 
2128     template <typename R>
2129     class shared_future : public detail::basic_future<R>
2130     {
2131         typedef detail::basic_future<R> base_type;
2132         typedef typename base_type::future_ptr future_ptr;
2133 
2134         friend class detail::future_waiter;
2135         friend class promise<R>;
2136 
2137 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2138         template <typename, typename, typename>
2139         friend struct detail::future_async_continuation_shared_state;
2140         template <typename, typename, typename>
2141         friend struct detail::future_deferred_continuation_shared_state;
2142 
2143         template <class F, class Rp, class Fp>
2144         friend BOOST_THREAD_FUTURE<Rp>
2145         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);
2146 
2147         template <class F, class Rp, class Fp>
2148         friend BOOST_THREAD_FUTURE<Rp>
2149         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);
2150 
2151         template <class F, class Rp, class Fp>
2152         friend BOOST_THREAD_FUTURE<Rp>
2153         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);
2154 #endif
2155 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2156         template <class> friend class packaged_task;// todo check if this works in windows
2157 #else
2158         friend class packaged_task<R>;
2159 #endif
2160         shared_future(future_ptr a_future):
2161           base_type(a_future)
2162         {}
2163 
2164     public:
2165         BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_future)
2166         typedef R value_type; // EXTENSION
2167 
2168         shared_future(shared_future const& other):
2169         base_type(other.future_)
2170         {}
2171 
2172         typedef future_state::state state;
2173 
2174         BOOST_CONSTEXPR shared_future()
2175         {}
2176         //BOOST_CONSTEXPR
2177         shared_future(exceptional_ptr const& ex):
2178             base_type(ex) {}
2179         ~shared_future()
2180         {}
2181 
2182         shared_future& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_future) other)
2183         {
2184             this->future_ = other.future_;
2185             return *this;
2186         }
2187 
2188         shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
2189         base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2190         {
2191         }
2192         shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT :
2193         base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2194         {
2195         }
2196 
2197         shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
2198         {
2199             base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2200             return *this;
2201         }
2202         shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT
2203         {
2204             base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2205             return *this;
2206         }
2207 
2208         void swap(shared_future& other) BOOST_NOEXCEPT
2209         {
2210             static_cast<base_type*>(this)->swap(other);
2211         }
2212         bool run_if_is_deferred() {
2213           return this->future_->run_if_is_deferred();
2214         }
2215         bool run_if_is_deferred_or_ready() {
2216           return this->future_->run_if_is_deferred_or_ready();
2217         }
2218         // retrieving the value
2219         typename detail::shared_state<R>::shared_future_get_result_type get() const
2220         {
2221             if(!this->future_)
2222             {
2223                 boost::throw_exception(future_uninitialized());
2224             }
2225             return this->future_->get_sh();
2226         }
2227 
2228         template <typename R2>
2229         typename boost::disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type
2230         get_or(BOOST_THREAD_RV_REF(R2) v)  const // EXTENSION
2231         {
2232             if(!this->future_)
2233             {
2234                 boost::throw_exception(future_uninitialized());
2235             }
2236             this->future_->wait();
2237             if (this->future_->has_value()) return this->future_->get_sh();
2238             else return boost::move(v);
2239         }
2240 
2241 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2242         template<typename F>
2243         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2244         then(BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2245         template<typename F>
2246         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2247         then(launch policy, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2248   #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2249         template<typename Ex, typename F>
2250         inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2251         then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2252   #endif
2253 #endif
2254 
2255     };
2256 
2257     BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
2258 
2259     template <typename R>
2260     class promise
2261     {
2262         typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
2263 
2264         typedef typename detail::shared_state<R>::source_reference_type source_reference_type;
2265         typedef typename detail::shared_state<R>::rvalue_source_type rvalue_source_type;
2266         typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
2267         typedef typename detail::shared_state<R>::shared_future_get_result_type shared_future_get_result_type;
2268 
2269         future_ptr future_;
2270         bool future_obtained;
2271 
2272         void lazy_init()
2273         {
2274 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2275 #include <boost/thread/detail/atomic_undef_macros.hpp>
2276           if(!atomic_load(&future_))
2277             {
2278                 future_ptr blank;
2279                 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R>));
2280             }
2281 #include <boost/thread/detail/atomic_redef_macros.hpp>
2282 #endif
2283         }
2284 
2285     public:
2286         BOOST_THREAD_MOVABLE_ONLY(promise)
2287 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2288         template <class Allocator>
2289         promise(boost::allocator_arg_t, Allocator a)
2290         {
2291           typedef typename Allocator::template rebind<detail::shared_state<R> >::other A2;
2292           A2 a2(a);
2293           typedef thread_detail::allocator_destructor<A2> D;
2294 
2295           future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R>(), D(a2, 1) );
2296           future_obtained = false;
2297         }
2298 #endif
2299         promise():
2300 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2301             future_(),
2302 #else
2303             future_(new detail::shared_state<R>()),
2304 #endif
2305             future_obtained(false)
2306         {}
2307 
2308         ~promise()
2309         {
2310             if(future_)
2311             {
2312                 boost::unique_lock<boost::mutex> lock(future_->mutex);
2313 
2314                 if(!future_->done && !future_->is_constructed)
2315                 {
2316                     future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2317                 }
2318             }
2319         }
2320 
2321         // Assignment
2322         promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2323             future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2324         {
2325             BOOST_THREAD_RV(rhs).future_.reset();
2326             BOOST_THREAD_RV(rhs).future_obtained=false;
2327         }
2328         promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2329         {
2330             future_=BOOST_THREAD_RV(rhs).future_;
2331             future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2332             BOOST_THREAD_RV(rhs).future_.reset();
2333             BOOST_THREAD_RV(rhs).future_obtained=false;
2334             return *this;
2335         }
2336 
2337         void swap(promise& other)
2338         {
2339             future_.swap(other.future_);
2340             std::swap(future_obtained,other.future_obtained);
2341         }
2342 
2343 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2344         void set_executor(executor_ptr_type aex)
2345         {
2346           lazy_init();
2347           if (future_.get()==0)
2348           {
2349               boost::throw_exception(promise_moved());
2350           }
2351           boost::lock_guard<boost::mutex> lk(future_->mutex);
2352           future_->set_executor_policy(aex, lk);
2353         }
2354 #endif
2355         // Result retrieval
2356         BOOST_THREAD_FUTURE<R> get_future()
2357         {
2358             lazy_init();
2359             if (future_.get()==0)
2360             {
2361                 boost::throw_exception(promise_moved());
2362             }
2363             if (future_obtained)
2364             {
2365                 boost::throw_exception(future_already_retrieved());
2366             }
2367             future_obtained=true;
2368             return BOOST_THREAD_FUTURE<R>(future_);
2369         }
2370 
2371 #if defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2372         template <class TR>
2373         typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
2374             set_value(TR const &  r)
2375         {
2376             lazy_init();
2377             boost::unique_lock<boost::mutex> lock(future_->mutex);
2378             if(future_->done)
2379             {
2380                 boost::throw_exception(promise_already_satisfied());
2381             }
2382             future_->mark_finished_with_result_internal(r, lock);
2383         }
2384 #else
2385         void set_value(source_reference_type r)
2386         {
2387             lazy_init();
2388             boost::unique_lock<boost::mutex> lock(future_->mutex);
2389             if(future_->done)
2390             {
2391                 boost::throw_exception(promise_already_satisfied());
2392             }
2393             future_->mark_finished_with_result_internal(r, lock);
2394         }
2395 #endif
2396 
2397         void set_value(rvalue_source_type r)
2398         {
2399             lazy_init();
2400             boost::unique_lock<boost::mutex> lock(future_->mutex);
2401             if(future_->done)
2402             {
2403                 boost::throw_exception(promise_already_satisfied());
2404             }
2405 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2406             future_->mark_finished_with_result_internal(boost::move(r), lock);
2407 #else
2408             future_->mark_finished_with_result_internal(static_cast<rvalue_source_type>(r), lock);
2409 #endif
2410         }
2411 
2412 #if defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2413         template <class TR>
2414         typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
2415             set_value_deferred(TR const &  r)
2416         {
2417             lazy_init();
2418             if (future_.get()==0)
2419             {
2420                 boost::throw_exception(promise_moved());
2421             }
2422             future_->set_value_deferred(r);
2423         }
2424 #else
2425         void set_value_deferred(source_reference_type r)
2426         {
2427             lazy_init();
2428             if (future_.get()==0)
2429             {
2430                 boost::throw_exception(promise_moved());
2431             }
2432             future_->set_value_deferred(r);
2433         }
2434 #endif
2435 
2436         void set_value_deferred(rvalue_source_type r)
2437         {
2438             lazy_init();
2439             if (future_.get()==0)
2440             {
2441                 boost::throw_exception(promise_moved());
2442             }
2443 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2444             future_->set_value_deferred(boost::move(r));
2445 #else
2446             future_->set_value_deferred(static_cast<rvalue_source_type>(r));
2447 #endif
2448         }
2449 
2450 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
2451         template <class ...Args>
2452         void emplace(BOOST_THREAD_FWD_REF(Args) ...args)
2453         {
2454             lazy_init();
2455             boost::unique_lock<boost::mutex> lock(future_->mutex);
2456             if(future_->done)
2457             {
2458                 boost::throw_exception(promise_already_satisfied());
2459             }
2460             future_->mark_finished_with_result_internal(lock, boost::forward<Args>(args)...);
2461         }
2462 
2463 #endif
2464 
2465         void set_exception(boost::exception_ptr p)
2466         {
2467             lazy_init();
2468             boost::unique_lock<boost::mutex> lock(future_->mutex);
2469             if(future_->done)
2470             {
2471                 boost::throw_exception(promise_already_satisfied());
2472             }
2473             future_->mark_exceptional_finish_internal(p, lock);
2474         }
2475         template <typename E>
2476         void set_exception(E ex)
2477         {
2478           set_exception(boost::copy_exception(ex));
2479         }
2480         void set_exception_deferred(boost::exception_ptr p)
2481         {
2482             lazy_init();
2483             if (future_.get()==0)
2484             {
2485                 boost::throw_exception(promise_moved());
2486             }
2487             future_->set_exception_deferred(p);
2488         }
2489         template <typename E>
2490         void set_exception_deferred(E ex)
2491         {
2492           set_exception_deferred(boost::copy_exception(ex));
2493         }
2494 
2495         // setting the result with deferred notification
2496 #if defined  BOOST_NO_CXX11_RVALUE_REFERENCES
2497         template <class TR>
2498         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)
2499         {
2500           if (future_.get()==0)
2501           {
2502               boost::throw_exception(promise_moved());
2503           }
2504           future_->set_value_at_thread_exit(r);
2505         }
2506 #else
2507         void set_value_at_thread_exit(source_reference_type r)
2508         {
2509           if (future_.get()==0)
2510           {
2511               boost::throw_exception(promise_moved());
2512           }
2513           future_->set_value_at_thread_exit(r);
2514         }
2515 #endif
2516         void set_value_at_thread_exit(BOOST_THREAD_RV_REF(R) r)
2517         {
2518           if (future_.get()==0)
2519           {
2520               boost::throw_exception(promise_moved());
2521           }
2522           future_->set_value_at_thread_exit(boost::move(r));
2523         }
2524         void set_exception_at_thread_exit(exception_ptr e)
2525         {
2526           if (future_.get()==0)
2527           {
2528               boost::throw_exception(promise_moved());
2529           }
2530           future_->set_exception_at_thread_exit(e);
2531         }
2532         template <typename E>
2533         void set_exception_at_thread_exit(E ex)
2534         {
2535           set_exception_at_thread_exit(boost::copy_exception(ex));
2536         }
2537 
2538         template<typename F>
2539         void set_wait_callback(F f)
2540         {
2541             lazy_init();
2542             future_->set_wait_callback(f,this);
2543         }
2544         void notify_deferred()
2545         {
2546             if (future_.get()==0)
2547             {
2548                 boost::throw_exception(promise_moved());
2549             }
2550             future_->notify_deferred();
2551         }
2552 
2553     };
2554 
2555     template <typename R>
2556     class promise<R&>
2557     {
2558         typedef boost::shared_ptr<detail::shared_state<R&> > future_ptr;
2559 
2560         future_ptr future_;
2561         bool future_obtained;
2562 
2563         void lazy_init()
2564         {
2565 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2566 #include <boost/thread/detail/atomic_undef_macros.hpp>
2567             if(!atomic_load(&future_))
2568             {
2569                 future_ptr blank;
2570                 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
2571             }
2572 #include <boost/thread/detail/atomic_redef_macros.hpp>
2573 #endif
2574         }
2575 
2576     public:
2577         BOOST_THREAD_MOVABLE_ONLY(promise)
2578 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2579         template <class Allocator>
2580         promise(boost::allocator_arg_t, Allocator a)
2581         {
2582           typedef typename Allocator::template rebind<detail::shared_state<R&> >::other A2;
2583           A2 a2(a);
2584           typedef thread_detail::allocator_destructor<A2> D;
2585 
2586           future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R&>(), D(a2, 1) );
2587           future_obtained = false;
2588         }
2589 #endif
2590         promise():
2591 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2592             future_(),
2593 #else
2594             future_(new detail::shared_state<R&>()),
2595 #endif
2596             future_obtained(false)
2597         {}
2598 
2599         ~promise()
2600         {
2601             if(future_)
2602             {
2603                 boost::unique_lock<boost::mutex> lock(future_->mutex);
2604 
2605                 if(!future_->done && !future_->is_constructed)
2606                 {
2607                     future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2608                 }
2609             }
2610         }
2611 
2612         // Assignment
2613         promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2614             future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2615         {
2616             BOOST_THREAD_RV(rhs).future_.reset();
2617             BOOST_THREAD_RV(rhs).future_obtained=false;
2618         }
2619         promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2620         {
2621             future_=BOOST_THREAD_RV(rhs).future_;
2622             future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2623             BOOST_THREAD_RV(rhs).future_.reset();
2624             BOOST_THREAD_RV(rhs).future_obtained=false;
2625             return *this;
2626         }
2627 
2628         void swap(promise& other)
2629         {
2630             future_.swap(other.future_);
2631             std::swap(future_obtained,other.future_obtained);
2632         }
2633 
2634         // Result retrieval
2635         BOOST_THREAD_FUTURE<R&> get_future()
2636         {
2637             lazy_init();
2638             if (future_.get()==0)
2639             {
2640                 boost::throw_exception(promise_moved());
2641             }
2642             if (future_obtained)
2643             {
2644                 boost::throw_exception(future_already_retrieved());
2645             }
2646             future_obtained=true;
2647             return BOOST_THREAD_FUTURE<R&>(future_);
2648         }
2649 
2650         void set_value(R& r)
2651         {
2652             lazy_init();
2653             boost::unique_lock<boost::mutex> lock(future_->mutex);
2654             if(future_->done)
2655             {
2656                 boost::throw_exception(promise_already_satisfied());
2657             }
2658             future_->mark_finished_with_result_internal(r, lock);
2659         }
2660         void set_value_deferred(R& r)
2661         {
2662             lazy_init();
2663             if (future_.get()==0)
2664             {
2665                 boost::throw_exception(promise_already_satisfied());
2666             }
2667             future_->set_value_deferred(r);
2668         }
2669         void set_exception(boost::exception_ptr p)
2670         {
2671             lazy_init();
2672             boost::unique_lock<boost::mutex> lock(future_->mutex);
2673             if(future_->done)
2674             {
2675                 boost::throw_exception(promise_already_satisfied());
2676             }
2677             future_->mark_exceptional_finish_internal(p, lock);
2678         }
2679         template <typename E>
2680         void set_exception(E ex)
2681         {
2682           set_exception(boost::copy_exception(ex));
2683         }
2684         void set_exception_deferred(boost::exception_ptr p)
2685         {
2686             lazy_init();
2687             if (future_.get()==0)
2688             {
2689                 boost::throw_exception(promise_moved());
2690             }
2691             future_->set_exception_deferred(p);
2692         }
2693         template <typename E>
2694         void set_exception_deferred(E ex)
2695         {
2696           set_exception_deferred(boost::copy_exception(ex));
2697         }
2698         // setting the result with deferred notification
2699         void set_value_at_thread_exit(R& r)
2700         {
2701           if (future_.get()==0)
2702           {
2703               boost::throw_exception(promise_moved());
2704           }
2705           future_->set_value_at_thread_exit(r);
2706         }
2707 
2708         void set_exception_at_thread_exit(exception_ptr e)
2709         {
2710           if (future_.get()==0)
2711           {
2712               boost::throw_exception(promise_moved());
2713           }
2714           future_->set_exception_at_thread_exit(e);
2715         }
2716         template <typename E>
2717         void set_exception_at_thread_exit(E ex)
2718         {
2719           set_exception_at_thread_exit(boost::copy_exception(ex));
2720         }
2721 
2722         template<typename F>
2723         void set_wait_callback(F f)
2724         {
2725             lazy_init();
2726             future_->set_wait_callback(f,this);
2727         }
2728         void notify_deferred()
2729         {
2730             if (future_.get()==0)
2731             {
2732                 boost::throw_exception(promise_moved());
2733             }
2734             future_->notify_deferred();
2735         }
2736     };
2737 
2738     template <>
2739     class promise<void>
2740     {
2741         typedef boost::shared_ptr<detail::shared_state<void> > future_ptr;
2742 
2743         future_ptr future_;
2744         bool future_obtained;
2745 
2746         void lazy_init()
2747         {
2748 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2749             if(!atomic_load(&future_))
2750             {
2751                 future_ptr blank;
2752                 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<void>));
2753             }
2754 #endif
2755         }
2756     public:
2757         BOOST_THREAD_MOVABLE_ONLY(promise)
2758 
2759 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2760         template <class Allocator>
2761         promise(boost::allocator_arg_t, Allocator a)
2762         {
2763           typedef typename Allocator::template rebind<detail::shared_state<void> >::other A2;
2764           A2 a2(a);
2765           typedef thread_detail::allocator_destructor<A2> D;
2766 
2767           future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<void>(), D(a2, 1) );
2768           future_obtained = false;
2769         }
2770 #endif
2771         promise():
2772 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2773             future_(),
2774 #else
2775             future_(new detail::shared_state<void>),
2776 #endif
2777             future_obtained(false)
2778         {}
2779 
2780         ~promise()
2781         {
2782             if(future_)
2783             {
2784                 boost::unique_lock<boost::mutex> lock(future_->mutex);
2785 
2786                 if(!future_->done && !future_->is_constructed)
2787                 {
2788                     future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2789                 }
2790             }
2791         }
2792 
2793         // Assignment
2794         promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2795             future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2796         {
2797           // we need to release the future as shared_ptr doesn't implements move semantics
2798             BOOST_THREAD_RV(rhs).future_.reset();
2799             BOOST_THREAD_RV(rhs).future_obtained=false;
2800         }
2801 
2802         promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2803         {
2804             future_=BOOST_THREAD_RV(rhs).future_;
2805             future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2806             BOOST_THREAD_RV(rhs).future_.reset();
2807             BOOST_THREAD_RV(rhs).future_obtained=false;
2808             return *this;
2809         }
2810 
2811         void swap(promise& other)
2812         {
2813             future_.swap(other.future_);
2814             std::swap(future_obtained,other.future_obtained);
2815         }
2816 
2817         // Result retrieval
2818         BOOST_THREAD_FUTURE<void> get_future()
2819         {
2820             lazy_init();
2821 
2822             if (future_.get()==0)
2823             {
2824                 boost::throw_exception(promise_moved());
2825             }
2826             if(future_obtained)
2827             {
2828                 boost::throw_exception(future_already_retrieved());
2829             }
2830             future_obtained=true;
2831             //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<void>(future_));
2832             return BOOST_THREAD_FUTURE<void>(future_);
2833         }
2834 
2835         void set_value()
2836         {
2837             lazy_init();
2838             boost::unique_lock<boost::mutex> lock(future_->mutex);
2839             if(future_->done)
2840             {
2841                 boost::throw_exception(promise_already_satisfied());
2842             }
2843             future_->mark_finished_with_result_internal(lock);
2844         }
2845         void set_value_deferred()
2846         {
2847             lazy_init();
2848             if (future_.get()==0)
2849             {
2850                 boost::throw_exception(promise_moved());
2851             }
2852             future_->set_value_deferred();
2853         }
2854 
2855         void set_exception(boost::exception_ptr p)
2856         {
2857             lazy_init();
2858             boost::unique_lock<boost::mutex> lock(future_->mutex);
2859             if(future_->done)
2860             {
2861                 boost::throw_exception(promise_already_satisfied());
2862             }
2863             future_->mark_exceptional_finish_internal(p,lock);
2864         }
2865         template <typename E>
2866         void set_exception(E ex)
2867         {
2868           set_exception(boost::copy_exception(ex));
2869         }
2870         void set_exception_deferred(boost::exception_ptr p)
2871         {
2872             lazy_init();
2873             if (future_.get()==0)
2874             {
2875                 boost::throw_exception(promise_moved());
2876             }
2877             future_->set_exception_deferred(p);
2878         }
2879         template <typename E>
2880         void set_exception_deferred(E ex)
2881         {
2882           set_exception_deferred(boost::copy_exception(ex));
2883         }
2884         // setting the result with deferred notification
2885         void set_value_at_thread_exit()
2886         {
2887           if (future_.get()==0)
2888           {
2889               boost::throw_exception(promise_moved());
2890           }
2891           future_->set_value_at_thread_exit();
2892         }
2893 
2894         void set_exception_at_thread_exit(exception_ptr e)
2895         {
2896           if (future_.get()==0)
2897           {
2898               boost::throw_exception(promise_moved());
2899           }
2900           future_->set_exception_at_thread_exit(e);
2901         }
2902         template <typename E>
2903         void set_exception_at_thread_exit(E ex)
2904         {
2905           set_exception_at_thread_exit(boost::copy_exception(ex));
2906         }
2907 
2908         template<typename F>
2909         void set_wait_callback(F f)
2910         {
2911             lazy_init();
2912             future_->set_wait_callback(f,this);
2913         }
2914         void notify_deferred()
2915         {
2916             if (future_.get()==0)
2917             {
2918                 boost::throw_exception(promise_moved());
2919             }
2920             future_->notify_deferred();
2921         }
2922     };
2923 }
2924 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2925 namespace boost { namespace container {
2926     template <class R, class Alloc>
2927     struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2928     {
2929     };
2930 }}
2931 #if ! defined  BOOST_NO_CXX11_ALLOCATOR
2932 namespace std {
2933     template <class R, class Alloc>
2934     struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2935     {
2936     };
2937 }
2938 #endif
2939 #endif
2940 
2941 namespace boost
2942 {
2943 
2944     BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
2945 
2946     namespace detail
2947     {
2948 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2949       template<typename R>
2950       struct task_base_shared_state;
2951 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2952       template<typename R, typename ...ArgTypes>
2953       struct task_base_shared_state<R(ArgTypes...)>:
2954 #else
2955       template<typename R>
2956       struct task_base_shared_state<R()>:
2957 #endif
2958 #else
2959       template<typename R>
2960       struct task_base_shared_state:
2961 #endif
2962             detail::shared_state<R>
2963         {
2964             bool started;
2965 
2966             task_base_shared_state():
2967                 started(false)
2968             {}
2969 
2970             void reset()
2971             {
2972               // todo The packaged_task::reset must be as if an assignemnt froma new packaged_task with the same function
2973               // the reset function is an optimization that avoids reallocating a new task.
2974               started=false;
2975               this->validate();
2976             }
2977 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2978             virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
2979             void run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2980 #else
2981             virtual void do_run()=0;
2982             void run()
2983 #endif
2984             {
2985                 {
2986                     boost::lock_guard<boost::mutex> lk(this->mutex);
2987                     if(started)
2988                     {
2989                         boost::throw_exception(task_already_started());
2990                     }
2991                     started=true;
2992                 }
2993 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2994                 do_run(boost::move(args)...);
2995 #else
2996                 do_run();
2997 #endif
2998             }
2999 
3000 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3001             virtual void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
3002             void apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3003 #else
3004             virtual void do_apply()=0;
3005             void apply()
3006 #endif
3007             {
3008                 {
3009                     boost::lock_guard<boost::mutex> lk(this->mutex);
3010                     if(started)
3011                     {
3012                         boost::throw_exception(task_already_started());
3013                     }
3014                     started=true;
3015                 }
3016 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3017                 do_apply(boost::move(args)...);
3018 #else
3019                 do_apply();
3020 #endif
3021             }
3022 
3023             void owner_destroyed()
3024             {
3025                 boost::unique_lock<boost::mutex> lk(this->mutex);
3026                 if(!started)
3027                 {
3028                     started=true;
3029                     this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk);
3030                 }
3031             }
3032         };
3033 
3034 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3035         template<typename F, typename R>
3036         struct task_shared_state;
3037 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3038         template<typename F, typename R, typename ...ArgTypes>
3039         struct task_shared_state<F, R(ArgTypes...)>:
3040           task_base_shared_state<R(ArgTypes...)>
3041 #else
3042         template<typename F, typename R>
3043         struct task_shared_state<F, R()>:
3044           task_base_shared_state<R()>
3045 #endif
3046 #else
3047         template<typename F, typename R>
3048         struct task_shared_state:
3049             task_base_shared_state<R>
3050 #endif
3051         {
3052         private:
3053           task_shared_state(task_shared_state&);
3054         public:
3055             F f;
3056             task_shared_state(F const& f_):
3057                 f(f_)
3058             {}
3059             task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3060               f(boost::move(f_))
3061             {}
3062 
3063             F callable()
3064             {
3065               return boost::move(f);
3066             }
3067 
3068 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3069             void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3070             {
3071                 try
3072                 {
3073                     this->set_value_at_thread_exit(f(boost::move(args)...));
3074                 }
3075 #else
3076             void do_apply()
3077             {
3078                 try
3079                 {
3080                     this->set_value_at_thread_exit(f());
3081                 }
3082 #endif
3083                 catch(...)
3084                 {
3085                     this->set_exception_at_thread_exit(current_exception());
3086                 }
3087             }
3088 
3089 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3090             void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3091             {
3092                 try
3093                 {
3094                     this->mark_finished_with_result(f(boost::move(args)...));
3095                 }
3096 #else
3097             void do_run()
3098             {
3099                 try
3100                 {
3101 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
3102                   R res((f()));
3103                   this->mark_finished_with_result(boost::move(res));
3104 #else
3105                   this->mark_finished_with_result(f());
3106 #endif
3107                   }
3108 #endif
3109                 catch(...)
3110                 {
3111                     this->mark_exceptional_finish();
3112                 }
3113             }
3114         };
3115 
3116 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3117 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3118         template<typename F, typename R, typename ...ArgTypes>
3119         struct task_shared_state<F, R&(ArgTypes...)>:
3120           task_base_shared_state<R&(ArgTypes...)>
3121 #else
3122         template<typename F, typename R>
3123         struct task_shared_state<F, R&()>:
3124           task_base_shared_state<R&()>
3125 #endif
3126 #else
3127         template<typename F, typename R>
3128         struct task_shared_state<F,R&>:
3129             task_base_shared_state<R&>
3130 #endif
3131         {
3132         private:
3133           task_shared_state(task_shared_state&);
3134         public:
3135             F f;
3136             task_shared_state(F const& f_):
3137                 f(f_)
3138             {}
3139             task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3140                 f(boost::move(f_))
3141             {}
3142 
3143             F callable()
3144             {
3145               return f;
3146             }
3147 
3148 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3149             void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3150             {
3151                 try
3152                 {
3153                     this->set_value_at_thread_exit(f(boost::move(args)...));
3154                 }
3155 #else
3156             void do_apply()
3157             {
3158                 try
3159                 {
3160                     this->set_value_at_thread_exit(f());
3161                 }
3162 #endif
3163                 catch(...)
3164                 {
3165                     this->set_exception_at_thread_exit(current_exception());
3166                 }
3167             }
3168 
3169 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3170             void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3171             {
3172                 try
3173                 {
3174                     this->mark_finished_with_result(f(boost::move(args)...));
3175                 }
3176 #else
3177             void do_run()
3178             {
3179                 try
3180                 {
3181                   R& res((f()));
3182                   this->mark_finished_with_result(res);
3183                 }
3184 #endif
3185                 catch(...)
3186                 {
3187                     this->mark_exceptional_finish();
3188                 }
3189             }
3190         };
3191 
3192 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
3193 
3194 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3195 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3196         template<typename R, typename ...ArgTypes>
3197         struct task_shared_state<R (*)(ArgTypes...), R(ArgTypes...)>:
3198           task_base_shared_state<R(ArgTypes...)>
3199 #else
3200         template<typename R>
3201         struct task_shared_state<R (*)(), R()>:
3202           task_base_shared_state<R()>
3203 #endif
3204 #else
3205         template<typename R>
3206         struct task_shared_state<R (*)(), R> :
3207            task_base_shared_state<R>
3208 #endif
3209             {
3210             private:
3211               task_shared_state(task_shared_state&);
3212 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3213               typedef R (*CallableType)(ArgTypes ... );
3214 #else
3215               typedef R (*CallableType)();
3216 #endif
3217             public:
3218                 CallableType f;
3219                 task_shared_state(CallableType f_):
3220                     f(f_)
3221                 {}
3222 
3223                 CallableType callable()
3224                 {
3225                   return f;
3226                 }
3227 
3228 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3229                 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3230                 {
3231                     try
3232                     {
3233                         this->set_value_at_thread_exit(f(boost::move(args)...));
3234                     }
3235 #else
3236                 void do_apply()
3237                 {
3238                     try
3239                     {
3240                         R r((f()));
3241                         this->set_value_at_thread_exit(boost::move(r));
3242                     }
3243 #endif
3244                     catch(...)
3245                     {
3246                         this->set_exception_at_thread_exit(current_exception());
3247                     }
3248                 }
3249 
3250 
3251 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3252                 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3253                 {
3254                     try
3255                     {
3256                         this->mark_finished_with_result(f(boost::move(args)...));
3257                     }
3258 #else
3259                 void do_run()
3260                 {
3261                     try
3262                     {
3263                         R res((f()));
3264                         this->mark_finished_with_result(boost::move(res));
3265                     }
3266 #endif
3267                     catch(...)
3268                     {
3269                         this->mark_exceptional_finish();
3270                     }
3271                 }
3272             };
3273 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3274 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3275         template<typename R, typename ...ArgTypes>
3276         struct task_shared_state<R& (*)(ArgTypes...), R&(ArgTypes...)>:
3277           task_base_shared_state<R&(ArgTypes...)>
3278 #else
3279         template<typename R>
3280         struct task_shared_state<R& (*)(), R&()>:
3281           task_base_shared_state<R&()>
3282 #endif
3283 #else
3284         template<typename R>
3285         struct task_shared_state<R& (*)(), R&> :
3286            task_base_shared_state<R&>
3287 #endif
3288             {
3289             private:
3290               task_shared_state(task_shared_state&);
3291             public:
3292 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3293                 typedef R& (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes) ... );
3294 #else
3295                 typedef R& (*CallableType)();
3296 #endif
3297                 CallableType f;
3298                 task_shared_state(CallableType f_):
3299                     f(f_)
3300                 {}
3301 
3302                 CallableType callable()
3303                 {
3304                   return boost::move(f);
3305                 }
3306 
3307 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3308                 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3309                 {
3310                     try
3311                     {
3312                         this->set_value_at_thread_exit(f(boost::move(args)...));
3313                     }
3314 #else
3315                 void do_apply()
3316                 {
3317                     try
3318                     {
3319                       this->set_value_at_thread_exit(f());
3320                     }
3321 #endif
3322                     catch(...)
3323                     {
3324                         this->set_exception_at_thread_exit(current_exception());
3325                     }
3326                 }
3327 
3328 
3329 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3330                 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3331                 {
3332                     try
3333                     {
3334                         this->mark_finished_with_result(f(boost::move(args)...));
3335                     }
3336 #else
3337                 void do_run()
3338                 {
3339                     try
3340                     {
3341                         this->mark_finished_with_result(f());
3342                     }
3343 #endif
3344                     catch(...)
3345                     {
3346                         this->mark_exceptional_finish();
3347                     }
3348                 }
3349             };
3350 #endif
3351 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3352 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3353         template<typename F, typename ...ArgTypes>
3354         struct task_shared_state<F, void(ArgTypes...)>:
3355           task_base_shared_state<void(ArgTypes...)>
3356 #else
3357         template<typename F>
3358         struct task_shared_state<F, void()>:
3359           task_base_shared_state<void()>
3360 #endif
3361 #else
3362         template<typename F>
3363         struct task_shared_state<F,void>:
3364           task_base_shared_state<void>
3365 #endif
3366         {
3367         private:
3368           task_shared_state(task_shared_state&);
3369         public:
3370             typedef F CallableType;
3371             F f;
3372             task_shared_state(F const& f_):
3373                 f(f_)
3374             {}
3375             task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3376                 f(boost::move(f_))
3377             {}
3378             F callable()
3379             {
3380               return boost::move(f);
3381             }
3382 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3383             void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3384             {
3385               try
3386               {
3387                 f(boost::move(args)...);
3388 #else
3389             void do_apply()
3390             {
3391                 try
3392                 {
3393                     f();
3394 #endif
3395                   this->set_value_at_thread_exit();
3396                 }
3397                 catch(...)
3398                 {
3399                     this->set_exception_at_thread_exit(current_exception());
3400                 }
3401             }
3402 
3403 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3404             void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3405             {
3406                 try
3407                 {
3408                     f(boost::move(args)...);
3409 #else
3410             void do_run()
3411             {
3412                 try
3413                 {
3414                     f();
3415 #endif
3416                     this->mark_finished_with_result();
3417                 }
3418                 catch(...)
3419                 {
3420                     this->mark_exceptional_finish();
3421                 }
3422             }
3423         };
3424 
3425 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3426 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3427         template<typename ...ArgTypes>
3428         struct task_shared_state<void (*)(ArgTypes...), void(ArgTypes...)>:
3429         task_base_shared_state<void(ArgTypes...)>
3430 #else
3431         template<>
3432         struct task_shared_state<void (*)(), void()>:
3433         task_base_shared_state<void()>
3434 #endif
3435 #else
3436         template<>
3437         struct task_shared_state<void (*)(),void>:
3438           task_base_shared_state<void>
3439 #endif
3440         {
3441         private:
3442           task_shared_state(task_shared_state&);
3443 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3444             typedef void (*CallableType)(ArgTypes...);
3445 #else
3446             typedef void (*CallableType)();
3447 #endif
3448         public:
3449             CallableType f;
3450             task_shared_state(CallableType f_):
3451                 f(f_)
3452             {}
3453             CallableType callable()
3454             {
3455               return f;
3456             }
3457 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3458             void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3459             {
3460                 try
3461                 {
3462                     f(boost::move(args)...);
3463 #else
3464             void do_apply()
3465             {
3466                 try
3467                 {
3468                     f();
3469 #endif
3470                     this->set_value_at_thread_exit();
3471                 }
3472                 catch(...)
3473                 {
3474                     this->set_exception_at_thread_exit(current_exception());
3475                 }
3476             }
3477 
3478 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3479             void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3480             {
3481                 try
3482                 {
3483                     f(boost::move(args)...);
3484 #else
3485             void do_run()
3486             {
3487                 try
3488                 {
3489                   f();
3490 #endif
3491                   this->mark_finished_with_result();
3492                 }
3493                 catch(...)
3494                 {
3495                     this->mark_exceptional_finish();
3496                 }
3497             }
3498         };
3499     }
3500 
3501 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3502   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3503     template<typename R, typename ...ArgTypes>
3504     class packaged_task<R(ArgTypes...)>
3505     {
3506       typedef boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task_ptr;
3507       boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task;
3508   #else
3509     template<typename R>
3510     class packaged_task<R()>
3511     {
3512       typedef boost::shared_ptr<detail::task_base_shared_state<R()> > task_ptr;
3513       boost::shared_ptr<detail::task_base_shared_state<R()> > task;
3514   #endif
3515 #else
3516     template<typename R>
3517     class packaged_task
3518     {
3519       typedef boost::shared_ptr<detail::task_base_shared_state<R> > task_ptr;
3520       boost::shared_ptr<detail::task_base_shared_state<R> > task;
3521 #endif
3522         bool future_obtained;
3523         struct dummy;
3524 
3525     public:
3526         typedef R result_type;
3527         BOOST_THREAD_MOVABLE_ONLY(packaged_task)
3528 
3529         packaged_task():
3530             future_obtained(false)
3531         {}
3532 
3533         // construction and destruction
3534 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
3535 
3536 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3537   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3538         explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args)
3539         {
3540             typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3541             typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3542             task= task_ptr(new task_shared_state_type(f, boost::move(args)...));
3543             future_obtained=false;
3544         }
3545   #else
3546         explicit packaged_task(R(*f)())
3547         {
3548             typedef R(*FR)();
3549             typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3550             task= task_ptr(new task_shared_state_type(f));
3551             future_obtained=false;
3552         }
3553   #endif
3554 #else
3555         explicit packaged_task(R(*f)())
3556         {
3557               typedef R(*FR)();
3558             typedef detail::task_shared_state<FR,R> task_shared_state_type;
3559             task= task_ptr(new task_shared_state_type(f));
3560             future_obtained=false;
3561         }
3562 #endif
3563 #endif
3564 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
3565         template <class F>
3566         explicit packaged_task(BOOST_THREAD_FWD_REF(F) f
3567             , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3568             )
3569         {
3570           typedef typename decay<F>::type FR;
3571 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3572   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3573             typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3574   #else
3575             typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3576   #endif
3577 #else
3578             typedef detail::task_shared_state<FR,R> task_shared_state_type;
3579 #endif
3580             task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
3581             future_obtained = false;
3582 
3583         }
3584 
3585 #else
3586         template <class F>
3587         explicit packaged_task(F const& f
3588             , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3589             )
3590         {
3591 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3592   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3593             typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3594   #else
3595             typedef detail::task_shared_state<F,R()> task_shared_state_type;
3596   #endif
3597 #else
3598             typedef detail::task_shared_state<F,R> task_shared_state_type;
3599 #endif
3600             task = task_ptr(new task_shared_state_type(f));
3601             future_obtained=false;
3602         }
3603         template <class F>
3604         explicit packaged_task(BOOST_THREAD_RV_REF(F) f)
3605         {
3606 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3607 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3608             typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3609             task = task_ptr(new task_shared_state_type(boost::move(f)));
3610 #else
3611             typedef detail::task_shared_state<F,R()> task_shared_state_type;
3612             task = task_ptr(new task_shared_state_type(boost::move(f)));
3613 #endif
3614 #else
3615             typedef detail::task_shared_state<F,R> task_shared_state_type;
3616             task = task_ptr(new task_shared_state_type(boost::move(f)));
3617 #endif
3618             future_obtained=false;
3619 
3620         }
3621 #endif
3622 
3623 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3624 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
3625         template <class Allocator>
3626         packaged_task(boost::allocator_arg_t, Allocator a, R(*f)())
3627         {
3628           typedef R(*FR)();
3629 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3630   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3631           typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3632   #else
3633           typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3634   #endif
3635 #else
3636           typedef detail::task_shared_state<FR,R> task_shared_state_type;
3637 #endif
3638           typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3639           A2 a2(a);
3640           typedef thread_detail::allocator_destructor<A2> D;
3641 
3642           task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3643           future_obtained = false;
3644         }
3645 #endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
3646 
3647 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3648         template <class F, class Allocator>
3649         packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
3650         {
3651           typedef typename decay<F>::type FR;
3652 
3653 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3654   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3655           typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3656   #else
3657           typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3658   #endif
3659 #else
3660           typedef detail::task_shared_state<FR,R> task_shared_state_type;
3661 #endif
3662           typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3663           A2 a2(a);
3664           typedef thread_detail::allocator_destructor<A2> D;
3665 
3666           task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
3667           future_obtained = false;
3668         }
3669 #else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3670         template <class F, class Allocator>
3671         packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
3672         {
3673 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3674   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3675           typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3676   #else
3677           typedef detail::task_shared_state<F,R()> task_shared_state_type;
3678   #endif
3679 #else
3680           typedef detail::task_shared_state<F,R> task_shared_state_type;
3681 #endif
3682           typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3683           A2 a2(a);
3684           typedef thread_detail::allocator_destructor<A2> D;
3685 
3686           task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3687           future_obtained = false;
3688         }
3689         template <class F, class Allocator>
3690         packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f)
3691         {
3692 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3693   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3694           typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3695   #else
3696           typedef detail::task_shared_state<F,R()> task_shared_state_type;
3697   #endif
3698 #else
3699           typedef detail::task_shared_state<F,R> task_shared_state_type;
3700 #endif
3701           typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3702           A2 a2(a);
3703           typedef thread_detail::allocator_destructor<A2> D;
3704 
3705           task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) );
3706           future_obtained = false;
3707         }
3708 
3709 #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
3710 #endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3711 
3712         ~packaged_task() {
3713             if(task) {
3714                 task->owner_destroyed();
3715             }
3716         }
3717 
3718         // assignment
3719         packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
3720         : future_obtained(BOOST_THREAD_RV(other).future_obtained) {
3721             task.swap(BOOST_THREAD_RV(other).task);
3722             BOOST_THREAD_RV(other).future_obtained=false;
3723         }
3724         packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT {
3725 
3726 #if ! defined  BOOST_NO_CXX11_RVALUE_REFERENCES
3727             packaged_task temp(boost::move(other));
3728 #else
3729             packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
3730 #endif
3731             swap(temp);
3732             return *this;
3733         }
3734 
3735 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3736         void set_executor(executor_ptr_type aex)
3737         {
3738           if (!valid())
3739               boost::throw_exception(task_moved());
3740           boost::lock_guard<boost::mutex> lk(task->mutex);
3741           task->set_executor_policy(aex, lk);
3742         }
3743 #endif
3744         void reset() {
3745             if (!valid())
3746               boost::throw_exception(future_error(system::make_error_code(future_errc::no_state)));
3747 
3748             // As if *this = packaged_task(task->callable());
3749 
3750             task->reset();
3751             future_obtained=false;
3752         }
3753 
3754         void swap(packaged_task& other) BOOST_NOEXCEPT {
3755             task.swap(other.task);
3756             std::swap(future_obtained,other.future_obtained);
3757         }
3758         bool valid() const BOOST_NOEXCEPT {
3759           return task.get()!=0;
3760         }
3761 
3762         // result retrieval
3763         BOOST_THREAD_FUTURE<R> get_future() {
3764             if(!task) {
3765                 boost::throw_exception(task_moved());
3766             } else if(!future_obtained) {
3767                 future_obtained=true;
3768                 return BOOST_THREAD_FUTURE<R>(task);
3769             } else {
3770                 boost::throw_exception(future_already_retrieved());
3771             }
3772         }
3773 
3774         // execution
3775 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3776         void operator()(ArgTypes... args) {
3777             if(!task) {
3778                 boost::throw_exception(task_moved());
3779             }
3780             task->run(boost::move(args)...);
3781         }
3782         void make_ready_at_thread_exit(ArgTypes... args) {
3783           if(!task) {
3784               boost::throw_exception(task_moved());
3785           }
3786           if (task->has_value()) {
3787                 boost::throw_exception(promise_already_satisfied());
3788           }
3789           task->apply(boost::move(args)...);
3790         }
3791 #else
3792         void operator()() {
3793             if(!task) {
3794                 boost::throw_exception(task_moved());
3795             }
3796             task->run();
3797         }
3798         void make_ready_at_thread_exit() {
3799           if(!task) {
3800               boost::throw_exception(task_moved());
3801           }
3802           if (task->has_value()) boost::throw_exception(promise_already_satisfied());
3803           task->apply();
3804         }
3805 #endif
3806         template<typename F>
3807         void set_wait_callback(F f) {
3808             task->set_wait_callback(f,this);
3809         }
3810     };
3811 }
3812 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3813 namespace boost { namespace container {
3814     template <class R, class Alloc>
3815     struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3816     {};
3817 }}
3818 #if ! defined  BOOST_NO_CXX11_ALLOCATOR
3819 namespace std {
3820     template <class R, class Alloc>
3821     struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3822     {};
3823 }
3824 #endif
3825 #endif
3826 
3827 namespace boost
3828 {
3829   BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
3830 
3831 namespace detail
3832 {
3833   ////////////////////////////////
3834   // make_future_deferred_shared_state
3835   ////////////////////////////////
3836   template <class Rp, class Fp>
3837   BOOST_THREAD_FUTURE<Rp>
3838   make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3839     shared_ptr<future_deferred_shared_state<Rp, Fp> >
3840         h(new future_deferred_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
3841     return BOOST_THREAD_FUTURE<Rp>(h);
3842   }
3843 
3844   ////////////////////////////////
3845   // make_future_async_shared_state
3846   ////////////////////////////////
3847   template <class Rp, class Fp>
3848   BOOST_THREAD_FUTURE<Rp>
3849   make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3850     shared_ptr<future_async_shared_state<Rp, Fp> >
3851         h(new future_async_shared_state<Rp, Fp>());
3852     h->init(boost::forward<Fp>(f));
3853     return BOOST_THREAD_FUTURE<Rp>(h);
3854   }
3855 }
3856 
3857     ////////////////////////////////
3858     // template <class F, class... ArgTypes>
3859     // future<R> async(launch policy, F&&, ArgTypes&&...);
3860     ////////////////////////////////
3861 
3862 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
3863 
3864 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3865   template <class R, class... ArgTypes>
3866   BOOST_THREAD_FUTURE<R>
3867   async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3868     typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3869     typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3870     typedef typename BF::result_type Rp;
3871 
3872     if (underlying_cast<int>(policy) & int(launch::async)) {
3873       return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3874               BF(
3875                   f
3876                   , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3877               )
3878           ));
3879     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3880       return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3881               BF(
3882                   f
3883                   , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3884               )
3885           ));
3886     } else {
3887       std::terminate();
3888       //BOOST_THREAD_FUTURE<R> ret;
3889       //return ::boost::move(ret);
3890     }
3891   }
3892 
3893 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3894 
3895   template <class R>
3896   BOOST_THREAD_FUTURE<R>
3897   async(launch policy, R(*f)()) {
3898   #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3899     typedef packaged_task<R()> packaged_task_type;
3900   #else
3901     typedef packaged_task<R> packaged_task_type;
3902   #endif
3903 
3904     if (underlying_cast<int>(policy) & int(launch::async)) {
3905       packaged_task_type pt( f );
3906       BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
3907       ret.set_async();
3908       boost::thread( boost::move(pt) ).detach();
3909       return ::boost::move(ret);
3910     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3911       std::terminate();
3912       //BOOST_THREAD_FUTURE<R> ret;
3913       //return ::boost::move(ret);
3914     } else {
3915       std::terminate();
3916       //BOOST_THREAD_FUTURE<R> ret;
3917       //return ::boost::move(ret);
3918     }
3919   }
3920 #endif
3921 #endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
3922 
3923 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3924 
3925   template <class F, class ...ArgTypes>
3926   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3927       typename decay<ArgTypes>::type...
3928   )>::type>
3929   async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3930     typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3931     typedef typename BF::result_type Rp;
3932 
3933     if (underlying_cast<int>(policy) & int(launch::async)) {
3934       return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3935               BF(
3936                   thread_detail::decay_copy(boost::forward<F>(f))
3937                 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3938               )
3939           ));
3940     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3941       return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3942               BF(
3943                   thread_detail::decay_copy(boost::forward<F>(f))
3944                 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3945               )
3946           ));
3947     } else {
3948       std::terminate();
3949       //BOOST_THREAD_FUTURE<R> ret;
3950       //return ::boost::move(ret);
3951     }
3952   }
3953 
3954 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3955 
3956   template <class F>
3957   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3958   async(launch policy, BOOST_THREAD_FWD_REF(F) f) {
3959     typedef typename boost::result_of<typename decay<F>::type()>::type R;
3960 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3961     typedef packaged_task<R()> packaged_task_type;
3962 #else // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3963     typedef packaged_task<R> packaged_task_type;
3964 #endif // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3965 
3966     if (underlying_cast<int>(policy) & int(launch::async)) {
3967       packaged_task_type pt( boost::forward<F>(f) );
3968       BOOST_THREAD_FUTURE<R> ret = pt.get_future();
3969       ret.set_async();
3970       boost::thread( boost::move(pt) ).detach();
3971       return ::boost::move(ret);
3972     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3973       std::terminate();
3974       //BOOST_THREAD_FUTURE<R> ret;
3975       //return ::boost::move(ret);
3976       //          return boost::detail::make_future_deferred_shared_state<Rp>(
3977       //              BF(
3978       //                  thread_detail::decay_copy(boost::forward<F>(f))
3979       //              )
3980       //          );
3981     } else {
3982       std::terminate();
3983       //BOOST_THREAD_FUTURE<R> ret;
3984       //return ::boost::move(ret);
3985     }
3986   }
3987 #endif // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3988 
3989 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3990 namespace detail {
3991 
3992     /////////////////////////
3993     /// shared_state_nullary_task
3994     /////////////////////////
3995     template<typename Rp, typename Fp>
3996     struct shared_state_nullary_task
3997     {
3998 
3999       typedef shared_ptr<shared_state_base > storage_type;
4000       storage_type that;
4001       Fp f_;
4002     public:
4003 
4004       shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
4005       : that(st), f_(boost::move(f))
4006       {};
4007 
4008 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4009       BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
4010       shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
4011       : that(x.that), f_(x.f_)
4012       {}
4013       shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
4014       {
4015         if (this != &x) {
4016           that=x.that;
4017           f_=x.f_;
4018         }
4019         return *this;
4020       }
4021       // move
4022       shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
4023       : that(x.that), f_(boost::move(x.f_))
4024       {
4025         x.that.reset();
4026       }
4027       shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
4028       {
4029         if (this != &x) {
4030           that=x.that;
4031           f_=boost::move(x.f_);
4032           x.that.reset();
4033         }
4034         return *this;
4035       }
4036 #endif
4037       void operator()() {
4038         shared_ptr<shared_state<Rp> > that_ = static_pointer_cast<shared_state<Rp> >(that);
4039         try {
4040           that_->mark_finished_with_result(f_());
4041         } catch(...) {
4042           that_->mark_exceptional_finish();
4043         }
4044       }
4045       ~shared_state_nullary_task()
4046       {
4047       }
4048     };
4049 
4050     template<typename Fp>
4051     struct shared_state_nullary_task<void, Fp>
4052     {
4053       typedef shared_ptr<shared_state_base > storage_type;
4054       storage_type that;
4055       Fp f_;
4056     public:
4057       shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
4058       : that(st), f_(boost::move(f))
4059       {};
4060 
4061 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4062       BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
4063       shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
4064       : that(x.that), f_(x.f_)
4065       {}
4066       shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
4067       {
4068         if (this != &x) {
4069           that=x.that;
4070           f_=x.f_;
4071         }
4072         return *this;
4073       }
4074       // move
4075       shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
4076       : that(x.that), f_(boost::move(x.f_))
4077       {
4078         x.that.reset();
4079       }
4080       shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
4081         if (this != &x) {
4082           that=x.that;
4083           f_=boost::move(x.f_);
4084           x.that.reset();
4085         }
4086         return *this;
4087       }
4088 #endif
4089       void operator()() {
4090         shared_ptr<shared_state<void> > that_ = static_pointer_cast<shared_state<void> >(that);
4091         try {
4092           f_();
4093           that_->mark_finished_with_result();
4094         } catch(...) {
4095           that_->mark_exceptional_finish();
4096         }
4097       }
4098     };
4099 
4100 }
4101     BOOST_THREAD_DCL_MOVABLE_BEG2(R,F) detail::shared_state_nullary_task<R,F> BOOST_THREAD_DCL_MOVABLE_END
4102 namespace detail {
4103 
4104     /////////////////////////
4105     /// future_executor_shared_state_base
4106     /////////////////////////
4107     template<typename Rp>
4108     struct future_executor_shared_state: shared_state<Rp>
4109     {
4110       typedef shared_state<Rp> base_type;
4111     protected:
4112     public:
4113       future_executor_shared_state() {
4114       }
4115 
4116       template <class Fp, class Executor>
4117       void init(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f)
4118       {
4119         typedef typename decay<Fp>::type Cont;
4120         this->set_executor_policy(executor_ptr_type(new executor_ref<Executor>(ex)));
4121         shared_state_nullary_task<Rp,Cont> t(this->shared_from_this(), boost::forward<Fp>(f));
4122         ex.submit(boost::move(t));
4123       }
4124 
4125       ~future_executor_shared_state() {}
4126     };
4127 
4128     ////////////////////////////////
4129     // make_future_executor_shared_state
4130     ////////////////////////////////
4131     template <class Rp, class Fp, class Executor>
4132     BOOST_THREAD_FUTURE<Rp>
4133     make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
4134       shared_ptr<future_executor_shared_state<Rp> >
4135           h(new future_executor_shared_state<Rp>());
4136       h->init(ex, boost::forward<Fp>(f));
4137       return BOOST_THREAD_FUTURE<Rp>(h);
4138     }
4139 
4140 } // detail
4141 
4142     ////////////////////////////////
4143     // template <class Executor, class F, class... ArgTypes>
4144     // future<R> async(Executor& ex, F&&, ArgTypes&&...);
4145     ////////////////////////////////
4146 
4147 //#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4148 #if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
4149 
4150 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4151 
4152   template <class Executor, class R, class... ArgTypes>
4153   BOOST_THREAD_FUTURE<R>
4154   async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4155     typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
4156     typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
4157     typedef typename BF::result_type Rp;
4158 
4159     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4160         BF(
4161             f
4162             , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
4163         )
4164     ));
4165   }
4166 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4167 
4168   template <class Executor, class F, class ...ArgTypes>
4169   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4170       typename decay<ArgTypes>::type...
4171   )>::type>
4172   async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4173     typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
4174     typedef typename BF::result_type Rp;
4175 
4176     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4177         BF(
4178             thread_detail::decay_copy(boost::forward<F>(f))
4179             , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
4180         )
4181     ));
4182   }
4183 
4184 #else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4185 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4186 
4187   template <class Executor, class R>
4188   BOOST_THREAD_FUTURE<R>
4189   async(Executor& ex, R(*f)()) {
4190     typedef R(*F)();
4191     typedef detail::invoker<F> BF;
4192     typedef typename BF::result_type Rp;
4193 
4194     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4195         BF(
4196             f
4197         )
4198     ));
4199   }
4200 
4201   template <class Executor, class R, class A1>
4202   BOOST_THREAD_FUTURE<R>
4203   async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1) {
4204     typedef R(*F)(BOOST_THREAD_FWD_REF(A1));
4205     typedef detail::invoker<F, typename decay<A1>::type> BF;
4206     typedef typename BF::result_type Rp;
4207 
4208     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4209         BF(
4210             f
4211             , thread_detail::decay_copy(boost::forward<A1>(a1))
4212         )
4213     ));
4214   }
4215 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4216 
4217   template <class Executor, class F>
4218   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
4219   async(Executor& ex, BOOST_THREAD_FWD_REF(F) f)  {
4220     typedef detail::invoker<typename decay<F>::type> BF;
4221     typedef typename BF::result_type Rp;
4222 
4223     return boost::detail::make_future_executor_shared_state<Rp>(ex,
4224         BF(
4225             thread_detail::decay_copy(boost::forward<F>(f))
4226         )
4227     );
4228   }
4229 
4230   template <class Executor, class F, class A1>
4231   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4232       typename decay<A1>::type
4233   )>::type>
4234   async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) {
4235     typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type> BF;
4236     typedef typename BF::result_type Rp;
4237 
4238     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4239         BF(
4240             thread_detail::decay_copy(boost::forward<F>(f))
4241           , thread_detail::decay_copy(boost::forward<A1>(a1))
4242         )
4243     ));
4244   }
4245 
4246   template <class Executor, class F, class A1, class A2>
4247   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4248       typename decay<A1>::type, typename decay<A2>::type
4249   )>::type>
4250   async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) {
4251     typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type, typename decay<A2>::type> BF;
4252     typedef typename BF::result_type Rp;
4253 
4254     return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4255         BF(
4256             thread_detail::decay_copy(boost::forward<F>(f))
4257           , thread_detail::decay_copy(boost::forward<A1>(a1))
4258           , thread_detail::decay_copy(boost::forward<A2>(a2))
4259         )
4260     ));
4261   }
4262 
4263 #endif //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4264 #endif
4265 
4266   ////////////////////////////////
4267   // template <class F, class... ArgTypes>
4268   // future<R> async(F&&, ArgTypes&&...);
4269   ////////////////////////////////
4270 
4271 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
4272   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
4273   template <class R, class... ArgTypes>
4274   BOOST_THREAD_FUTURE<R>
4275   async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4276     return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
4277   }
4278   #else
4279   template <class R>
4280   BOOST_THREAD_FUTURE<R>
4281   async(R(*f)()) {
4282     return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
4283   }
4284   #endif
4285 #endif
4286 
4287 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
4288   template <class F, class ...ArgTypes>
4289   BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4290       typename decay<ArgTypes>::type...
4291   )>::type>
4292   async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4293       return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
4294   }
4295 #else
4296   template <class F>
4297   BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
4298   async(BOOST_THREAD_FWD_REF(F) f) {
4299       return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
4300   }
4301 #endif
4302 
4303   ////////////////////////////////
4304   // make_future deprecated
4305   ////////////////////////////////
4306   template <typename T>
4307   BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value) {
4308     typedef typename decay<T>::type future_value_type;
4309     promise<future_value_type> p;
4310     p.set_value(boost::forward<future_value_type>(value));
4311     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4312   }
4313 
4314 #if defined BOOST_THREAD_USES_MOVE
4315   inline BOOST_THREAD_FUTURE<void> make_future() {
4316     promise<void> p;
4317     p.set_value();
4318     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4319   }
4320 #endif
4321 
4322   ////////////////////////////////
4323   // make_ready_future
4324   ////////////////////////////////
4325   namespace detail {
4326     template <class T>
4327     struct deduced_type_impl
4328     {
4329         typedef T type;
4330     };
4331 
4332     template <class T>
4333     struct deduced_type_impl<reference_wrapper<T> const>
4334     {
4335         typedef T& type;
4336     };
4337     template <class T>
4338     struct deduced_type_impl<reference_wrapper<T> >
4339     {
4340         typedef T& type;
4341     };
4342 #if __cplusplus > 201103L
4343     template <class T>
4344     struct deduced_type_impl<std::reference_wrapper<T> >
4345     {
4346         typedef T& type;
4347     };
4348 #endif
4349     template <class T>
4350     struct deduced_type
4351     {
4352         typedef typename detail::deduced_type_impl<typename decay<T>::type>::type type;
4353     };
4354 
4355   }
4356 
4357 
4358 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4359   template <int = 0, int..., class T>
4360 #else
4361   template <class T>
4362 #endif
4363   BOOST_THREAD_FUTURE<typename detail::deduced_type<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
4364     typedef typename detail::deduced_type<T>::type future_value_type;
4365     promise<future_value_type> p;
4366     p.set_value(boost::forward<T>(value));
4367     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4368   }
4369 
4370   // explicit overloads
4371   template <class T>
4372   BOOST_THREAD_FUTURE<T> make_ready_future(typename remove_reference<T>::type & x)
4373   {
4374     promise<T> p;
4375     p.set_value(x);
4376     return p.get_future();
4377   }
4378 
4379   template <class T>
4380   BOOST_THREAD_FUTURE<T> make_ready_future(BOOST_THREAD_FWD_REF(typename remove_reference<T>::type) x)
4381   {
4382     promise<T> p;
4383     p.set_value(forward<typename remove_reference<T>::type>(x));
4384     return p.get_future();
4385   }
4386 
4387   // variadic overload
4388 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4389   template <class T, class ...Args>
4390   BOOST_THREAD_FUTURE<T> make_ready_future(Args&&... args)
4391   {
4392     promise<T> p;
4393     p.emplace(forward<Args>(args)...);
4394     return p.get_future();
4395 
4396   }
4397 #endif
4398 
4399   template <typename T, typename T1>
4400   BOOST_THREAD_FUTURE<T> make_ready_no_decay_future(T1 value) {
4401     typedef T future_value_type;
4402     promise<future_value_type> p;
4403     p.set_value(value);
4404     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4405   }
4406 
4407 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
4408   inline BOOST_THREAD_FUTURE<void> make_ready_future() {
4409     promise<void> p;
4410     p.set_value();
4411     return p.get_future();
4412   }
4413 #endif
4414 
4415 
4416   template <typename T>
4417   BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
4418     promise<T> p;
4419     p.set_exception(ex);
4420     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4421   }
4422 
4423   template <typename T, typename E>
4424   BOOST_THREAD_FUTURE<T> make_exceptional_future(E ex) {
4425     promise<T> p;
4426     p.set_exception(boost::copy_exception(ex));
4427     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4428   }
4429 
4430   template <typename T>
4431   BOOST_THREAD_FUTURE<T> make_exceptional_future() {
4432     promise<T> p;
4433     p.set_exception(boost::current_exception());
4434     return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4435   }
4436   template <typename T>
4437   BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex)  {
4438     return make_exceptional_future<T>(ex);
4439   }
4440 
4441 #if 0
4442   template<typename CLOSURE>
4443   make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE<decltype(closure())> {
4444       typedef decltype(closure()) T;
4445       promise<T> p;
4446       try {
4447         p.set_value(closure());
4448       } catch(...) {
4449         p.set_exception(std::current_exception());
4450       }
4451       return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4452   }
4453 #endif
4454 
4455   ////////////////////////////////
4456   // make_shared_future deprecated
4457   ////////////////////////////////
4458   template <typename T>
4459   shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value) {
4460     typedef typename decay<T>::type future_type;
4461     promise<future_type> p;
4462     p.set_value(boost::forward<T>(value));
4463     return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4464   }
4465 
4466   inline shared_future<void> make_shared_future()  {
4467     promise<void> p;
4468     return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4469   }
4470 
4471   ////////////////////////////////
4472   // detail::future_async_continuation_shared_state
4473   ////////////////////////////////
4474 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
4475 
4476 namespace detail
4477 {
4478   //////////////////////
4479   // detail::continuation_shared_state
4480   //////////////////////
4481   template<typename F, typename Rp, typename Fp, class ShSt=shared_state<Rp> >
4482   struct continuation_shared_state: ShSt
4483   {
4484     F parent;
4485     Fp continuation;
4486 
4487   public:
4488     continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4489     : parent(boost::move(f)),
4490       continuation(boost::move(c))
4491     {
4492     }
4493 
4494     void init(boost::unique_lock<boost::mutex> &lock)
4495     {
4496       parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
4497     }
4498 
4499     void call() {
4500       try {
4501         this->mark_finished_with_result(this->continuation(boost::move(this->parent)));
4502       } catch(...) {
4503         this->mark_exceptional_finish();
4504       }
4505       // make sure parent is really cleared to prevent memory "leaks"
4506       this->parent = F();
4507     }
4508 
4509     void call(boost::unique_lock<boost::mutex>& lck) {
4510       try {
4511         relocker relock(lck);
4512 
4513         // neither continuation nor parent are protected by the lock - call() must only
4514         // be called once, and no one else must modify it.
4515         Rp res = this->continuation(boost::move(this->parent));
4516 
4517         // make sure parent is really cleared to prevent memory "leaks"
4518         this->parent = F();
4519 
4520         relock.lock();
4521 
4522         this->mark_finished_with_result_internal(boost::move(res), lck);
4523       } catch (...) {
4524         this->mark_exceptional_finish_internal(current_exception(), lck);
4525 
4526         // make sure parent is really cleared to prevent memory "leaks"
4527         relocker relock(lck);
4528         this->parent = F();
4529       }
4530     }
4531 
4532     static void run(shared_ptr<boost::detail::shared_state_base> that_)
4533     {
4534       continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
4535       that->call();
4536     }
4537 
4538     ~continuation_shared_state() {}
4539   };
4540 
4541   template<typename F, typename Fp, class ShSt>
4542   struct continuation_shared_state<F, void, Fp, ShSt>: ShSt
4543   {
4544     F parent;
4545     Fp continuation;
4546 
4547   public:
4548     continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4549     : parent(boost::move(f)),
4550       continuation(boost::move(c))
4551     {
4552     }
4553 
4554     void init(boost::unique_lock<boost::mutex> &lock)
4555     {
4556       parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
4557     }
4558 
4559     void call()
4560     {
4561       try {
4562         this->continuation(boost::move(this->parent));
4563         this->mark_finished_with_result();
4564       } catch(...) {
4565         this->mark_exceptional_finish();
4566       }
4567       // make sure parent is really cleared to prevent memory "leaks"
4568       this->parent = F();
4569     }
4570 
4571     void call(boost::unique_lock<boost::mutex>& lck) {
4572       try {
4573         {
4574           relocker relock(lck);
4575           // neither continuation nor parent are protected by the lock - call() must only
4576           // be called once, and no one else must modify it.
4577           this->continuation(boost::move(this->parent));
4578 
4579           // make sure parent is really cleared to prevent memory "leaks"
4580           this->parent = F();
4581         }
4582         this->mark_finished_with_result_internal(lck);
4583       } catch (...) {
4584         this->mark_exceptional_finish_internal(current_exception(), lck);
4585 
4586         // make sure parent is really cleared to prevent memory "leaks"
4587         relocker relock(lck);
4588         this->parent = F();
4589       }
4590     }
4591 
4592     static void run(shared_ptr<boost::detail::shared_state_base> that_)
4593     {
4594       continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
4595       that->call();
4596     }
4597 
4598     ~continuation_shared_state() {}
4599   };
4600   /////////////////////////
4601   /// future_async_continuation_shared_state
4602   /////////////////////////
4603 
4604   template<typename F, typename Rp, typename Fp>
4605   struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
4606   {
4607     typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
4608   public:
4609     future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4610     : base_type(boost::move(f), boost::forward<Fp>(c))
4611     {    }
4612 
4613     void launch_continuation() {
4614 #if defined BOOST_THREAD_FUTURE_BLOCKING
4615       boost::lock_guard<boost::mutex> lk(this->mutex);
4616       this->thr_ = boost::thread(&future_async_continuation_shared_state::run, static_shared_from_this(this));
4617 #else
4618       boost::thread(&base_type::run, static_shared_from_this(this)).detach();
4619 #endif
4620     }
4621   };
4622 
4623   /////////////////////////
4624   /// future_sync_continuation_shared_state
4625   /////////////////////////
4626 
4627   template<typename F, typename Rp, typename Fp>
4628   struct future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
4629   {
4630     typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
4631   public:
4632     future_sync_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4633     : base_type(boost::move(f), boost::forward<Fp>(c))
4634     {    }
4635 
4636     void launch_continuation() {
4637       this->call();
4638     }
4639   };
4640 
4641 
4642   /////////////////////////
4643   /// future_executor_continuation_shared_state
4644   /////////////////////////
4645 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4646 
4647   template <typename FutureExecutorContinuationSharedState>
4648   struct run_it {
4649     shared_ptr<FutureExecutorContinuationSharedState> that_;
4650 
4651 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4652       BOOST_THREAD_COPYABLE_AND_MOVABLE(run_it)
4653       run_it(run_it const& x) //BOOST_NOEXCEPT
4654       : that_(x.that_)
4655       {}
4656       run_it& operator=(BOOST_THREAD_COPY_ASSIGN_REF(run_it) x) //BOOST_NOEXCEPT
4657       {
4658         if (this != &x) {
4659           that_=x.that_;
4660         }
4661         return *this;
4662       }
4663       // move
4664       run_it(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT
4665       : that_(x.that_)
4666       {
4667         x.that_.reset();
4668       }
4669       run_it& operator=(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT {
4670         if (this != &x) {
4671           that_=x.that_;
4672           x.that_.reset();
4673         }
4674         return *this;
4675       }
4676 #endif
4677     run_it(shared_ptr<FutureExecutorContinuationSharedState> that) : that_ (that) {}
4678 
4679     void operator()()
4680     {
4681       that_->run(that_);
4682     }
4683   };
4684 
4685 }
4686   BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::run_it<F> BOOST_THREAD_DCL_MOVABLE_END
4687 
4688 namespace detail {
4689 
4690   template<typename F, typename Rp, typename Fp>
4691   struct future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4692   {
4693     typedef continuation_shared_state<F,Rp,Fp> base_type;
4694 
4695   public:
4696     future_executor_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4697     : base_type(boost::move(f), boost::forward<Fp>(c))
4698     {
4699     }
4700 
4701     template <class Ex>
4702     void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
4703     {
4704       this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
4705       this->base_type::init(lk);
4706     }
4707 
4708     void launch_continuation() {
4709       run_it<base_type> fct(static_shared_from_this(this));
4710       this->get_executor()->submit(boost::move(fct));
4711     }
4712 
4713     ~future_executor_continuation_shared_state() {}
4714   };
4715 #endif
4716 
4717   /////////////////////////
4718   /// shared_future_async_continuation_shared_state
4719   /////////////////////////
4720 
4721   template<typename F, typename Rp, typename Fp>
4722   struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
4723   {
4724     typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
4725 
4726   public:
4727     shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4728     : base_type(boost::move(f), boost::forward<Fp>(c))
4729     {
4730     }
4731 
4732     void launch_continuation() {
4733 #if defined BOOST_THREAD_FUTURE_BLOCKING
4734       boost::lock_guard<boost::mutex> lk(this->mutex);
4735       this->thr_ = boost::thread(&base_type::run, static_shared_from_this(this));
4736 #else
4737       boost::thread(&base_type::run, static_shared_from_this(this)).detach();
4738 #endif
4739     }
4740   };
4741 
4742   /////////////////////////
4743   /// shared_future_async_continuation_shared_state
4744   /////////////////////////
4745 
4746   template<typename F, typename Rp, typename Fp>
4747   struct shared_future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
4748   {
4749     typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
4750 
4751   public:
4752     shared_future_sync_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4753     : base_type(boost::move(f), boost::forward<Fp>(c))
4754     {
4755     }
4756 
4757     void launch_continuation() {
4758       this->call();
4759     }
4760   };
4761 
4762 
4763   /////////////////////////
4764   /// shared_future_executor_continuation_shared_state
4765   /////////////////////////
4766 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4767 
4768   template<typename F, typename Rp, typename Fp>
4769   struct shared_future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4770   {
4771     typedef continuation_shared_state<F,Rp,Fp> base_type;
4772 
4773   public:
4774 
4775     shared_future_executor_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4776     : base_type(boost::move(f), boost::forward<Fp>(c))
4777     {
4778     }
4779 
4780     template <class Ex>
4781     void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
4782     {
4783       this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
4784       this->base_type::init(lk);
4785     }
4786 
4787     void launch_continuation() {
4788       run_it<base_type> fct(static_shared_from_this(this));
4789       this->get_executor()->submit(boost::move(fct));
4790     }
4791 
4792     ~shared_future_executor_continuation_shared_state() {}
4793   };
4794 
4795 #endif
4796   //////////////////////////
4797   /// future_deferred_continuation_shared_state
4798   //////////////////////////
4799   template<typename F, typename Rp, typename Fp>
4800   struct future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4801   {
4802     typedef continuation_shared_state<F,Rp,Fp> base_type;
4803   public:
4804     future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4805     : base_type(boost::move(f), boost::forward<Fp>(c))
4806     {
4807       this->set_deferred();
4808     }
4809 
4810     virtual void execute(boost::unique_lock<boost::mutex>& lk) {
4811       this->parent.wait();
4812       this->call(lk);
4813     }
4814 
4815     virtual void launch_continuation() {    }
4816   };
4817 
4818   //////////////////////////
4819   /// shared_future_deferred_continuation_shared_state
4820   //////////////////////////
4821   template<typename F, typename Rp, typename Fp>
4822   struct shared_future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4823   {
4824     typedef continuation_shared_state<F,Rp,Fp> base_type;
4825 
4826   public:
4827     shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4828     : base_type(boost::move(f), boost::forward<Fp>(c))
4829     {
4830       this->set_deferred();
4831     }
4832 
4833     virtual void execute(boost::unique_lock<boost::mutex>& lk) {
4834       this->parent.wait();
4835       this->call(lk);
4836     }
4837 
4838     virtual void launch_continuation() {    }
4839   };
4840 
4841   ////////////////////////////////
4842   // make_future_deferred_continuation_shared_state
4843   ////////////////////////////////
4844   template<typename F, typename Rp, typename Fp>
4845   BOOST_THREAD_FUTURE<Rp>
4846   make_future_deferred_continuation_shared_state(
4847       boost::unique_lock<boost::mutex> &lock,
4848       BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c) {
4849     typedef typename decay<Fp>::type Cont;
4850     shared_ptr<future_deferred_continuation_shared_state<F, Rp, Cont> >
4851         h(new future_deferred_continuation_shared_state<F, Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4852     h->init(lock);
4853     return BOOST_THREAD_FUTURE<Rp>(h);
4854   }
4855 
4856   ////////////////////////////////
4857   // make_future_async_continuation_shared_state
4858   ////////////////////////////////
4859   template<typename F, typename Rp, typename Fp>
4860   BOOST_THREAD_FUTURE<Rp>
4861   make_future_async_continuation_shared_state(
4862       boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4863       BOOST_THREAD_FWD_REF(Fp) c) {
4864     typedef typename decay<Fp>::type Cont;
4865     shared_ptr<future_async_continuation_shared_state<F,Rp, Cont> >
4866         h(new future_async_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4867     h->init(lock);
4868 
4869     return BOOST_THREAD_FUTURE<Rp>(h);
4870   }
4871   ////////////////////////////////
4872   // make_future_sync_continuation_shared_state
4873   ////////////////////////////////
4874   template<typename F, typename Rp, typename Fp>
4875   BOOST_THREAD_FUTURE<Rp>
4876   make_future_sync_continuation_shared_state(
4877       boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4878       BOOST_THREAD_FWD_REF(Fp) c) {
4879     typedef typename decay<Fp>::type Cont;
4880     shared_ptr<future_sync_continuation_shared_state<F,Rp, Cont> >
4881         h(new future_sync_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4882     h->init(lock);
4883 
4884     return BOOST_THREAD_FUTURE<Rp>(h);
4885   }
4886 
4887   ////////////////////////////////
4888   // make_future_executor_continuation_shared_state
4889   ////////////////////////////////
4890 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4891 
4892   template<typename Ex, typename F, typename Rp, typename Fp>
4893   BOOST_THREAD_FUTURE<Rp>
4894   make_future_executor_continuation_shared_state(Ex& ex,
4895       boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4896       BOOST_THREAD_FWD_REF(Fp) c) {
4897     typedef typename decay<Fp>::type Cont;
4898     shared_ptr<future_executor_continuation_shared_state<F,Rp, Cont> >
4899         h(new future_executor_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4900     h->init(lock, ex);
4901 
4902     return BOOST_THREAD_FUTURE<Rp>(h);
4903   }
4904 #endif
4905 
4906   ////////////////////////////////
4907   // make_shared_future_deferred_continuation_shared_state
4908   ////////////////////////////////
4909   template<typename F, typename Rp, typename Fp>
4910   BOOST_THREAD_FUTURE<Rp>
4911   make_shared_future_deferred_continuation_shared_state(
4912       boost::unique_lock<boost::mutex> &lock,
4913       F f, BOOST_THREAD_FWD_REF(Fp) c) {
4914     typedef typename decay<Fp>::type Cont;
4915     shared_ptr<shared_future_deferred_continuation_shared_state<F, Rp, Cont> >
4916         h(new shared_future_deferred_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
4917     h->init(lock);
4918 
4919     return BOOST_THREAD_FUTURE<Rp>(h);
4920   }
4921   ////////////////////////////////
4922   // make_shared_future_async_continuation_shared_state
4923   ////////////////////////////////
4924   template<typename F, typename Rp, typename Fp>
4925   BOOST_THREAD_FUTURE<Rp>
4926   make_shared_future_async_continuation_shared_state(
4927       boost::unique_lock<boost::mutex> &lock, F f,
4928       BOOST_THREAD_FWD_REF(Fp) c) {
4929     typedef typename decay<Fp>::type Cont;
4930     shared_ptr<shared_future_async_continuation_shared_state<F,Rp, Cont> >
4931         h(new shared_future_async_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
4932     h->init(lock);
4933 
4934     return BOOST_THREAD_FUTURE<Rp>(h);
4935   }
4936   ////////////////////////////////
4937   // make_shared_future_sync_continuation_shared_state
4938   ////////////////////////////////
4939   template<typename F, typename Rp, typename Fp>
4940   BOOST_THREAD_FUTURE<Rp>
4941   make_shared_future_sync_continuation_shared_state(
4942       boost::unique_lock<boost::mutex> &lock, F f,
4943       BOOST_THREAD_FWD_REF(Fp) c) {
4944     typedef typename decay<Fp>::type Cont;
4945     shared_ptr<shared_future_sync_continuation_shared_state<F,Rp, Cont> >
4946         h(new shared_future_sync_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
4947     h->init(lock);
4948 
4949     return BOOST_THREAD_FUTURE<Rp>(h);
4950   }
4951   ////////////////////////////////
4952   // make_shared_future_executor_continuation_shared_state
4953   ////////////////////////////////
4954 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4955   template<typename Ex, typename F, typename Rp, typename Fp>
4956   BOOST_THREAD_FUTURE<Rp>
4957   make_shared_future_executor_continuation_shared_state(Ex& ex,
4958       boost::unique_lock<boost::mutex> &lock, F f,
4959       BOOST_THREAD_FWD_REF(Fp) c) {
4960     typedef typename decay<Fp>::type Cont;
4961     shared_ptr<shared_future_executor_continuation_shared_state<F, Rp, Cont> >
4962         h(new shared_future_executor_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
4963     h->init(lock, ex);
4964 
4965     return BOOST_THREAD_FUTURE<Rp>(h);
4966   }
4967 #endif
4968 }
4969 
4970   ////////////////////////////////
4971   // template<typename F>
4972   // auto future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4973   ////////////////////////////////
4974   template <typename R>
4975   template <typename F>
4976   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4977   BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
4978     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4979     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
4980 
4981     // keep state alive as we move ourself but hold the lock
4982     shared_ptr<detail::shared_state_base> sentinel(this->future_);
4983     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
4984 
4985     if (underlying_cast<int>(policy) & int(launch::async)) {
4986       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4987                   lock, boost::move(*this), boost::forward<F>(func)
4988               )));
4989     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
4990       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4991                   lock, boost::move(*this), boost::forward<F>(func)
4992               )));
4993     } else if (underlying_cast<int>(policy) & int(launch::sync)) {
4994       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4995                   lock, boost::move(*this), boost::forward<F>(func)
4996               )));
4997 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4998     } else if (underlying_cast<int>(policy) & int(launch::executor)) {
4999       assert(this->future_->get_executor());
5000       typedef executor Ex;
5001       Ex& ex = *(this->future_->get_executor());
5002       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5003                     lock, boost::move(*this), boost::forward<F>(func)
5004                 )));
5005 #endif
5006     } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
5007 
5008         launch policy_ = this->launch_policy(lock);
5009         if (underlying_cast<int>(policy_) & int(launch::async)) {
5010           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5011                       lock, boost::move(*this), boost::forward<F>(func)
5012                   )));
5013         } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
5014           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5015                       lock, boost::move(*this), boost::forward<F>(func)
5016                   )));
5017         } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
5018           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5019                       lock, boost::move(*this), boost::forward<F>(func)
5020                   )));
5021 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5022         } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
5023           assert(this->future_->get_executor());
5024           typedef executor Ex;
5025           Ex& ex = *(this->future_->get_executor());
5026           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5027                         lock, boost::move(*this), boost::forward<F>(func)
5028                     )));
5029 #endif
5030         } else {
5031           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5032                       lock, boost::move(*this), boost::forward<F>(func)
5033                   )));
5034         }
5035     } else {
5036       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5037                   lock, boost::move(*this), boost::forward<F>(func)
5038               )));
5039     }
5040   }
5041 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5042   ////////////////////////////////
5043   // template<typename Ex, typename F>
5044   // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5045   ////////////////////////////////
5046   template <typename R>
5047   template <typename Ex, typename F>
5048   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
5049   BOOST_THREAD_FUTURE<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
5050     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5051     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5052 
5053     // keep state alive as we move ourself but hold the lock
5054     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5055     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5056 
5057     return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5058                   lock, boost::move(*this), boost::forward<F>(func)
5059               )));
5060   }
5061 #endif
5062   ////////////////////////////////
5063   // template<typename F>
5064   // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5065   ////////////////////////////////
5066   template <typename R>
5067   template <typename F>
5068   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
5069   BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func)  {
5070 
5071 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5072     return this->then(this->launch_policy(), boost::forward<F>(func));
5073 #else
5074     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5075     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5076 
5077     // keep state alive as we move ourself but hold the lock
5078     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5079     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5080 
5081     launch policy = this->launch_policy(lock);
5082     if (underlying_cast<int>(policy) & int(launch::deferred)) {
5083       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5084                   lock, boost::move(*this), boost::forward<F>(func)
5085               )));
5086     } else {
5087       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5088                   lock, boost::move(*this), boost::forward<F>(func)
5089               )));
5090     }
5091 #endif
5092 
5093   }
5094 
5095   ////////////////////////////////
5096   // template<typename F>
5097   // auto future<future<R2> >::then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5098   ////////////////////////////////
5099   template <typename R2>
5100   template <typename F>
5101   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
5102   BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
5103     typedef BOOST_THREAD_FUTURE<R2> R;
5104     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5105     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5106 
5107     // keep state alive as we move ourself but hold the lock
5108     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5109     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5110 
5111     if (underlying_cast<int>(policy) & int(launch::async)) {
5112       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5113                   lock, boost::move(*this), boost::forward<F>(func)
5114               )));
5115     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
5116       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5117                   lock, boost::move(*this), boost::forward<F>(func)
5118               )));
5119     } else if (underlying_cast<int>(policy) & int(launch::sync)) {
5120       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5121                   lock, boost::move(*this), boost::forward<F>(func)
5122               )));
5123 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5124     } else if (underlying_cast<int>(policy) & int(launch::executor)) {
5125       assert(this->future_->get_executor());
5126       typedef executor Ex;
5127       Ex& ex = *(this->future_->get_executor());
5128       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5129                     lock, boost::move(*this), boost::forward<F>(func)
5130                 )));
5131 #endif
5132     } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
5133         launch policy_ = this->launch_policy(lock);
5134 
5135         if (underlying_cast<int>(policy_) & int(launch::async)) {
5136           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5137                       lock, boost::move(*this), boost::forward<F>(func)
5138                   )));
5139         } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
5140           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5141                       lock, boost::move(*this), boost::forward<F>(func)
5142                   )));
5143         } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
5144           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5145                       lock, boost::move(*this), boost::forward<F>(func)
5146                   )));
5147 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5148         } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
5149           assert(this->future_->get_executor());
5150           typedef executor Ex;
5151           Ex& ex = *(this->future_->get_executor());
5152           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5153                         lock, boost::move(*this), boost::forward<F>(func)
5154                     )));
5155 #endif
5156         } else {
5157           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5158                       lock, boost::move(*this), boost::forward<F>(func)
5159                   )));
5160         }
5161     } else {
5162       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5163                   lock, boost::move(*this), boost::forward<F>(func)
5164               )));
5165     }
5166   }
5167 
5168 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5169   ////////////////////////////////
5170   // template<typename Ex, typename F>
5171   // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5172   ////////////////////////////////
5173   template <typename R2>
5174   template <typename Ex, typename F>
5175   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
5176   BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
5177     typedef BOOST_THREAD_FUTURE<R2> R;
5178     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5179     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5180 
5181     // keep state alive as we move ourself but hold the lock
5182     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5183     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5184 
5185     return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5186                   lock, boost::move(*this), boost::forward<F>(func)
5187               )));
5188   }
5189 #endif
5190 
5191   ////////////////////////////////
5192   // template<typename F>
5193   // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5194   ////////////////////////////////
5195   template <typename R2>
5196   template <typename F>
5197   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
5198   BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(BOOST_THREAD_FWD_REF(F) func)  {
5199 
5200 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5201     return this->then(this->launch_policy(), boost::forward<F>(func));
5202 #else
5203     typedef BOOST_THREAD_FUTURE<R2> R;
5204     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5205     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5206 
5207     // keep state alive as we move ourself but hold the lock
5208     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5209     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5210 
5211     launch policy = this->launch_policy(lock);
5212 
5213     if  (underlying_cast<int>(policy) & int(launch::deferred)) {
5214       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5215                   lock, boost::move(*this), boost::forward<F>(func)
5216               )));
5217     } else {
5218       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5219                   lock, boost::move(*this), boost::forward<F>(func)
5220               )));
5221     }
5222 #endif
5223   }
5224 
5225   ////////////////////////////////
5226   // template<typename F>
5227   // auto shared_future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5228   ////////////////////////////////
5229   template <typename R>
5230   template <typename F>
5231   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5232   shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func)  const
5233   {
5234     typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5235     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5236 
5237     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5238     if (underlying_cast<int>(policy) & int(launch::async)) {
5239       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5240                   lock, *this, boost::forward<F>(func)
5241               )));
5242     } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
5243       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5244                   lock, *this, boost::forward<F>(func)
5245               )));
5246     } else if (underlying_cast<int>(policy) & int(launch::sync)) {
5247       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5248                   lock, *this, boost::forward<F>(func)
5249               )));
5250 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5251     } else if (underlying_cast<int>(policy) & int(launch::executor)) {
5252       typedef executor Ex;
5253       Ex& ex = *(this->future_->get_executor());
5254       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5255                     lock, *this, boost::forward<F>(func)
5256                 )));
5257 #endif
5258     } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
5259 
5260         launch policy_ = this->launch_policy(lock);
5261         if (underlying_cast<int>(policy_) & int(launch::async)) {
5262           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5263                       lock, *this, boost::forward<F>(func)
5264                   )));
5265         } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
5266           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5267                       lock, *this, boost::forward<F>(func)
5268                   )));
5269         } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
5270           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5271                       lock, *this, boost::forward<F>(func)
5272                   )));
5273 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5274         } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
5275           typedef executor Ex;
5276           Ex& ex = *(this->future_->get_executor());
5277           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5278                         lock, *this, boost::forward<F>(func)
5279                     )));
5280 #endif
5281         } else {
5282           return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5283                       lock, *this, boost::forward<F>(func)
5284                   )));
5285         }
5286 
5287     } else {
5288       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5289                   lock, *this, boost::forward<F>(func)
5290               )));
5291     }
5292   }
5293 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5294   ////////////////////////////////
5295   // template<typename Ex, typename F>
5296   // auto shared_future<R>::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5297   ////////////////////////////////
5298   template <typename R>
5299   template <typename Ex, typename F>
5300   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5301   shared_future<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func)  const
5302   {
5303     typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5304     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5305 
5306     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5307     return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5308                   lock, *this, boost::forward<F>(func)
5309               )));
5310   }
5311 #endif
5312 
5313   ////////////////////////////////
5314   // template<typename F>
5315   // auto shared_future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5316   ////////////////////////////////
5317   template <typename R>
5318   template <typename F>
5319   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5320   shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func)  const {
5321 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5322     return this->then(this->launch_policy(), boost::forward<F>(func));
5323 #else
5324     typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5325     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5326 
5327     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5328     launch policy = this->launch_policy(lock);
5329     if (underlying_cast<int>(policy) & int(launch::deferred)) {
5330       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5331                   lock, *this, boost::forward<F>(func)
5332               )));
5333     } else {
5334       return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5335                   lock, *this, boost::forward<F>(func)
5336               )));
5337     }
5338 #endif
5339   }
5340 
5341 namespace detail
5342 {
5343   template <typename T>
5344   struct mfallbacker_to
5345   {
5346     T value_;
5347     typedef T result_type;
5348     mfallbacker_to(BOOST_THREAD_RV_REF(T) v)
5349     : value_(boost::move(v))
5350     {}
5351 
5352     T operator()(BOOST_THREAD_FUTURE<T> fut) {
5353       return fut.get_or(boost::move(value_));
5354     }
5355   };
5356   template <typename T>
5357   struct cfallbacker_to
5358   {
5359     T value_;
5360     typedef T result_type;
5361     cfallbacker_to(T const& v)
5362     : value_(v)
5363     {}
5364 
5365     T operator()(BOOST_THREAD_FUTURE<T> fut) const {
5366       return fut.get_or(value_);
5367 
5368     }
5369   };
5370 }
5371   ////////////////////////////////
5372   // future<R> future<R>::fallback_to(R&& v);
5373   ////////////////////////////////
5374 
5375   template <typename R>
5376   template <typename R2>
5377   inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
5378   BOOST_THREAD_FUTURE<R>::fallback_to(BOOST_THREAD_RV_REF(R2) v) {
5379     return then(detail::mfallbacker_to<R>(boost::move(v)));
5380   }
5381 
5382   template <typename R>
5383   template <typename R2>
5384   inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
5385   BOOST_THREAD_FUTURE<R>::fallback_to(R2 const& v) {
5386     return then(detail::cfallbacker_to<R>(v));
5387   }
5388 
5389 #endif
5390 
5391 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
5392 namespace detail
5393 {
5394   /////////////////////////
5395   /// future_unwrap_shared_state
5396   /////////////////////////
5397 
5398   template<typename F, typename Rp>
5399   struct future_unwrap_shared_state: shared_state<Rp>
5400   {
5401     F wrapped;
5402     typename F::value_type unwrapped;
5403   public:
5404     explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
5405     : wrapped(boost::move(f)) {
5406     }
5407 
5408     void launch_continuation()
5409     {
5410       boost::unique_lock<boost::mutex> lk(this->mutex);
5411       // assert(wrapped.is_ready());
5412       if (! unwrapped.valid() )
5413       {
5414         if (wrapped.has_exception()) {
5415           this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
5416         } else {
5417           unwrapped = wrapped.get();
5418           if (unwrapped.valid())
5419           {
5420             lk.unlock();
5421             boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
5422             unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
5423           } else {
5424             this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
5425           }
5426         }
5427       } else {
5428         // assert(unwrapped.is_ready());
5429         if (unwrapped.has_exception()) {
5430           this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
5431         } else {
5432           this->mark_finished_with_result_internal(unwrapped.get(), lk);
5433         }
5434       }
5435     }
5436   };
5437 
5438   template<typename F>
5439   struct future_unwrap_shared_state<F,void>: shared_state<void>
5440   {
5441     F wrapped;
5442     typename F::value_type unwrapped;
5443   public:
5444     explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
5445     : wrapped(boost::move(f)) {
5446     }
5447 
5448     void launch_continuation()
5449     {
5450       boost::unique_lock<boost::mutex> lk(this->mutex);
5451       // assert(wrapped.is_ready());
5452       if (! unwrapped.valid() )
5453       {
5454         if (wrapped.has_exception()) {
5455           this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
5456         } else {
5457           unwrapped = wrapped.get();
5458           if (unwrapped.valid())
5459           {
5460             lk.unlock();
5461             boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
5462             unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
5463           } else {
5464             this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
5465           }
5466         }
5467       } else {
5468         // assert(unwrapped.is_ready());
5469         if (unwrapped.has_exception()) {
5470           this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
5471         } else {
5472           this->mark_finished_with_result_internal(lk);
5473         }
5474       }
5475     }
5476   };
5477 
5478   template <class F, class Rp>
5479   BOOST_THREAD_FUTURE<Rp>
5480   make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f) {
5481     shared_ptr<future_unwrap_shared_state<F, Rp> >
5482         h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
5483     h->wrapped.future_->set_continuation_ptr(h, lock);
5484 
5485     return BOOST_THREAD_FUTURE<Rp>(h);
5486   }
5487 }
5488 
5489   template <typename R>
5490   inline BOOST_THREAD_FUTURE<R>::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other)
5491   : base_type(other.unwrap()) {}
5492 
5493   template <typename R2>
5494   BOOST_THREAD_FUTURE<R2>
5495   BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
5496   {
5497     BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5498 
5499     // keep state alive as we move ourself but hold the lock
5500     shared_ptr<detail::shared_state_base> sentinel(this->future_);
5501     boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5502 
5503     return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
5504   }
5505 #endif
5506 
5507 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
5508 namespace detail
5509 {
5510   struct input_iterator_tag {};
5511   struct vector_tag {};
5512   struct values_tag {};
5513   template <typename T>
5514   struct alias_t { typedef T type; };
5515 
5516   BOOST_CONSTEXPR_OR_CONST input_iterator_tag input_iterator_tag_value = {};
5517   BOOST_CONSTEXPR_OR_CONST vector_tag vector_tag_value = {};
5518   BOOST_CONSTEXPR_OR_CONST values_tag values_tag_value = {};
5519   ////////////////////////////////
5520   // detail::future_async_when_all_shared_state
5521   ////////////////////////////////
5522   template<typename F>
5523   struct future_when_all_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
5524   {
5525     typedef csbl::vector<F> vector_type;
5526     typedef typename F::value_type value_type;
5527     vector_type vec_;
5528 
5529     static void run(shared_ptr<boost::detail::shared_state_base> that_) {
5530       future_when_all_vector_shared_state* that = static_cast<future_when_all_vector_shared_state*>(that_.get());
5531       try {
5532         boost::wait_for_all(that->vec_.begin(), that->vec_.end());
5533         that->mark_finished_with_result(boost::move(that->vec_));
5534       } catch(...) {
5535         that->mark_exceptional_finish();
5536       }
5537     }
5538     bool run_deferred() {
5539 
5540       bool res = false;
5541       for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
5542         if (! it->run_if_is_deferred())
5543         {
5544           res = true;
5545         }
5546       }
5547       return res;
5548     }
5549     void init() {
5550       if (! run_deferred())
5551       {
5552         future_when_all_vector_shared_state::run(this->shared_from_this());
5553         return;
5554       }
5555 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5556       this->thr_ = boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this());
5557 #else
5558       boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this()).detach();
5559 #endif
5560     }
5561 
5562   public:
5563     template< typename InputIterator>
5564     future_when_all_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
5565     : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
5566     {
5567     }
5568 
5569     future_when_all_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
5570     : vec_(boost::move(v))
5571     {
5572     }
5573 
5574 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5575     template< typename T0, typename ...T>
5576     future_when_all_vector_shared_state(values_tag, BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5577       vec_.push_back(boost::forward<T0>(f));
5578       typename alias_t<char[]>::type{
5579           ( //first part of magic unpacker
5580           vec_.push_back(boost::forward<T>(futures)),'0'
5581           )..., '0'
5582       }; //second part of magic unpacker
5583     }
5584 #endif
5585 
5586     ~future_when_all_vector_shared_state() {}
5587   };
5588 
5589   ////////////////////////////////
5590   // detail::future_async_when_any_shared_state
5591   ////////////////////////////////
5592   template<typename F>
5593   struct future_when_any_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
5594   {
5595     typedef csbl::vector<F> vector_type;
5596     typedef typename F::value_type value_type;
5597     vector_type vec_;
5598 
5599     static void run(shared_ptr<boost::detail::shared_state_base> that_)
5600     {
5601       future_when_any_vector_shared_state* that = static_cast<future_when_any_vector_shared_state*>(that_.get());
5602       try {
5603         boost::wait_for_any(that->vec_.begin(), that->vec_.end());
5604         that->mark_finished_with_result(boost::move(that->vec_));
5605       } catch(...) {
5606         that->mark_exceptional_finish();
5607       }
5608     }
5609     bool run_deferred() {
5610 
5611       for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
5612         if (it->run_if_is_deferred_or_ready())
5613         {
5614           return true;
5615         }
5616       }
5617       return false;
5618     }
5619     void init() {
5620       if (run_deferred())
5621       {
5622         future_when_any_vector_shared_state::run(this->shared_from_this());
5623         return;
5624       }
5625 
5626 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5627       this->thr_ = boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this());
5628 #else
5629       boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this()).detach();
5630 #endif
5631     }
5632 
5633   public:
5634     template< typename InputIterator>
5635     future_when_any_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
5636     : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
5637     {
5638     }
5639 
5640     future_when_any_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
5641     : vec_(boost::move(v))
5642     {
5643     }
5644 
5645 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5646     template< typename T0, typename ...T>
5647     future_when_any_vector_shared_state(values_tag,
5648         BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures
5649     ) {
5650       vec_.push_back(boost::forward<T0>(f));
5651       typename alias_t<char[]>::type{
5652           ( //first part of magic unpacker
5653           vec_.push_back(boost::forward<T>(futures))
5654           ,'0'
5655           )...,
5656           '0'
5657       }; //second part of magic unpacker
5658     }
5659 #endif
5660 
5661     ~future_when_any_vector_shared_state() {}
5662   };
5663 
5664 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5665   struct wait_for_all_fctr {
5666     template <class ...T>
5667     void operator()(T&&... v) {
5668       boost::wait_for_all(boost::forward<T>(v)...);
5669     }
5670   };
5671 
5672   struct wait_for_any_fctr {
5673     template <class ...T>
5674     void operator()(T&&... v) {
5675       boost::wait_for_any(boost::forward<T>(v)...);
5676     }
5677   };
5678 
5679 
5680   template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5681   struct accumulate_run_if_is_deferred {
5682     bool operator ()(Tuple& t)
5683     {
5684       return (! csbl::get<i-1>(t).run_if_is_deferred()) || accumulate_run_if_is_deferred<Tuple,i-1>()(t);
5685     }
5686   };
5687   template <class Tuple>
5688   struct accumulate_run_if_is_deferred<Tuple, 0> {
5689     bool operator ()(Tuple& )
5690     {
5691       return false;
5692     }
5693   };
5694 
5695 
5696   template< typename Tuple, typename T0, typename ...T>
5697   struct future_when_all_tuple_shared_state: future_async_shared_state_base<Tuple>
5698   {
5699     Tuple tup_;
5700     typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5701 
5702     static void run(shared_ptr<boost::detail::shared_state_base> that_) {
5703       future_when_all_tuple_shared_state* that = static_cast<future_when_all_tuple_shared_state*>(that_.get());
5704       try {
5705         // TODO make use of apply(that->tup_, boost::detail::wait_for_all_fctor());
5706         that->wait_for_all(Index());
5707 
5708         that->mark_finished_with_result(boost::move(that->tup_));
5709       } catch(...) {
5710         that->mark_exceptional_finish();
5711       }
5712     }
5713 
5714     template <size_t ...Indices>
5715     void wait_for_all(tuple_indices<Indices...>) {
5716 #if defined BOOST_THREAD_PROVIDES_INVOKE
5717       return invoke<void>(wait_for_all_fctr(), csbl::get<Indices>(tup_)...);
5718 #else
5719       return wait_for_all_fctr()(csbl::get<Indices>(tup_)...);
5720 #endif
5721     }
5722 
5723     bool run_deferred() {
5724 
5725       return accumulate_run_if_is_deferred<Tuple>()(tup_);
5726     }
5727     void init() {
5728       if (! run_deferred())
5729       {
5730         future_when_all_tuple_shared_state::run(this->shared_from_this());
5731         return;
5732       }
5733 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5734       this->thr_ = boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this());
5735 #else
5736       boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this()).detach();
5737 #endif
5738 
5739     }
5740   public:
5741     template< typename F, typename ...Fs>
5742     future_when_all_tuple_shared_state(values_tag, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures) :
5743       tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5744     {
5745     }
5746 
5747     ~future_when_all_tuple_shared_state() {}
5748 
5749   };
5750 
5751 
5752   template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5753   struct apply_any_run_if_is_deferred_or_ready {
5754     bool operator ()(Tuple& t)
5755     {
5756       if (csbl::get<i-1>(t).run_if_is_deferred_or_ready()) return true;
5757       return apply_any_run_if_is_deferred_or_ready<Tuple,i-1>()(t);
5758     }
5759   };
5760   template <class Tuple>
5761   struct apply_any_run_if_is_deferred_or_ready<Tuple, 0> {
5762     bool operator ()(Tuple& )
5763     {
5764       return false;
5765     }
5766   };
5767 
5768   template< typename Tuple, typename T0, typename ...T >
5769   struct future_when_any_tuple_shared_state: future_async_shared_state_base<Tuple>
5770   {
5771     Tuple tup_;
5772     typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5773 
5774     static void run(shared_ptr<boost::detail::shared_state_base> that_)
5775     {
5776       future_when_any_tuple_shared_state* that = static_cast<future_when_any_tuple_shared_state*>(that_.get());
5777       try {
5778         // TODO make use of apply(that->tup_, wait_for_any_fctr);
5779         that->wait_for_any(Index());
5780 
5781         that->mark_finished_with_result(boost::move(that->tup_));
5782       } catch(...) {
5783         that->mark_exceptional_finish();
5784       }
5785     }
5786     template <size_t ...Indices>
5787     void wait_for_any(tuple_indices<Indices...>) {
5788 #if defined BOOST_THREAD_PROVIDES_INVOKE
5789       return invoke<void>(wait_for_any_fctr(), csbl::get<Indices>(tup_)...);
5790 #else
5791       return wait_for_any_fctr()(csbl::get<Indices>(tup_)...);
5792 #endif
5793     }
5794     bool run_deferred() {
5795       return apply_any_run_if_is_deferred_or_ready<Tuple>()(tup_);
5796     }
5797     void init() {
5798       if (run_deferred())
5799       {
5800         future_when_any_tuple_shared_state::run(this->shared_from_this());
5801         return;
5802       }
5803 
5804 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5805       this->thr_ = boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this());
5806 #else
5807       boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this()).detach();
5808 #endif
5809     }
5810 
5811   public:
5812     template< typename F, typename ...Fs>
5813     future_when_any_tuple_shared_state(values_tag,
5814         BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures
5815     ) :
5816       tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5817     {
5818     }
5819 
5820     ~future_when_any_tuple_shared_state() {}
5821   };
5822 #endif
5823 
5824 }
5825 
5826   template< typename InputIterator>
5827   typename boost::disable_if<is_future_type<InputIterator>,
5828     BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
5829   >::type
5830   when_all(InputIterator first, InputIterator last) {
5831     typedef  typename InputIterator::value_type value_type;
5832     typedef  csbl::vector<value_type> container_type;
5833     typedef  detail::future_when_all_vector_shared_state<value_type> factory_type;
5834 
5835     if (first==last) return make_ready_future(container_type());
5836     shared_ptr<factory_type >
5837         h(new factory_type(detail::input_iterator_tag_value, first,last));
5838     h->init();
5839     return BOOST_THREAD_FUTURE<container_type>(h);
5840   }
5841 
5842   inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all() {
5843     return make_ready_future(csbl::tuple<>());
5844   }
5845 
5846 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5847   template< typename T0, typename ...T>
5848   BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5849   when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5850     typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5851     typedef detail::future_when_all_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5852 
5853     shared_ptr<factory_type>
5854         h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5855     h->init();
5856     return BOOST_THREAD_FUTURE<container_type>(h);
5857   }
5858 #endif
5859 
5860   template< typename InputIterator>
5861   typename boost::disable_if<is_future_type<InputIterator>,
5862     BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type>  >
5863   >::type
5864   when_any(InputIterator first, InputIterator last) {
5865     typedef  typename InputIterator::value_type value_type;
5866     typedef  csbl::vector<value_type> container_type;
5867     typedef  detail::future_when_any_vector_shared_state<value_type> factory_type;
5868 
5869     if (first==last) return make_ready_future(container_type());
5870     shared_ptr<factory_type >
5871         h(new factory_type(detail::input_iterator_tag_value, first,last));
5872     h->init();
5873     return BOOST_THREAD_FUTURE<container_type>(h);
5874   }
5875 
5876   inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any() {
5877     return make_ready_future(csbl::tuple<>());
5878   }
5879 
5880 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5881   template< typename T0, typename ...T>
5882   BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5883   when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5884     typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5885     typedef detail::future_when_any_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5886 
5887     shared_ptr<factory_type>
5888         h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5889     h->init();
5890     return BOOST_THREAD_FUTURE<container_type>(h);
5891   }
5892 #endif
5893 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
5894 }
5895 
5896 #endif // BOOST_NO_EXCEPTIONS
5897 #endif // header