File indexing completed on 2025-12-15 10:09:30
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_THREAD_FUTURE_HPP
0009 #define BOOST_THREAD_FUTURE_HPP
0010
0011 #include <boost/thread/detail/config.hpp>
0012
0013
0014
0015
0016
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
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
0170 continuations_type continuations;
0171 executor_ptr_type ex_;
0172
0173
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
0282
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
0478
0479
0480
0481
0482
0483
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
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
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
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
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
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
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
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
0825
0826
0827
0828
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
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
0898
0899
0900
0901
0902
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
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
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
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
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
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
1313
1314 template <typename R>
1315 class promise;
1316
1317 template <typename R>
1318 class packaged_task;
1319
1320 namespace detail
1321 {
1322
1323 class base_future
1324 {
1325 public:
1326 };
1327
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
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
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
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 }
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)
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
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
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
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
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
1710 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1711 template <class> friend class packaged_task;
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;
1736
1737 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1738
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);
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
1774 void set_async()
1775 {
1776 this->future_->set_async();
1777 }
1778
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
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)
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);
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);
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);
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);
1875 template <typename R2>
1876 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1877 fallback_to(R2 const& v);
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
1977
1978 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1979 template <class> friend class packaged_task;
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;
2004
2005 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
2006
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
2035 void set_async()
2036 {
2037 this->future_->set_async();
2038 }
2039
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
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)
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)
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);
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);
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);
2117 #endif
2118 #endif
2119
2120 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
2121 inline
2122 BOOST_THREAD_FUTURE<R2>
2123 unwrap();
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;
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;
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
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
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
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;
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;
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;
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
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
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
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
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
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
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
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
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
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
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
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
2973
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
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
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
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
3710 #endif
3711
3712 ~packaged_task() {
3713 if(task) {
3714 task->owner_destroyed();
3715 }
3716 }
3717
3718
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
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
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
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
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
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
3859
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
3889
3890 }
3891 }
3892
3893 #else
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
3913
3914 } else {
3915 std::terminate();
3916
3917
3918 }
3919 }
3920 #endif
3921 #endif
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
3950
3951 }
3952 }
3953
3954 #else
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
3963 typedef packaged_task<R> packaged_task_type;
3964 #endif
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
3975
3976
3977
3978
3979
3980
3981 } else {
3982 std::terminate();
3983
3984
3985 }
3986 }
3987 #endif
3988
3989 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3990 namespace detail {
3991
3992
3993
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)
4011 : that(x.that), f_(x.f_)
4012 {}
4013 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x)
4014 {
4015 if (this != &x) {
4016 that=x.that;
4017 f_=x.f_;
4018 }
4019 return *this;
4020 }
4021
4022 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x)
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)
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)
4064 : that(x.that), f_(x.f_)
4065 {}
4066 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x)
4067 {
4068 if (this != &x) {
4069 that=x.that;
4070 f_=x.f_;
4071 }
4072 return *this;
4073 }
4074
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
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
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 }
4141
4142
4143
4144
4145
4146
4147
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
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
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
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
4264 #endif
4265
4266
4267
4268
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
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
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
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
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
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
4473
4474 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
4475
4476 namespace detail
4477 {
4478
4479
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
4506 this->parent = F();
4507 }
4508
4509 void call(boost::unique_lock<boost::mutex>& lck) {
4510 try {
4511 relocker relock(lck);
4512
4513
4514
4515 Rp res = this->continuation(boost::move(this->parent));
4516
4517
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
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
4568 this->parent = F();
4569 }
4570
4571 void call(boost::unique_lock<boost::mutex>& lck) {
4572 try {
4573 {
4574 relocker relock(lck);
4575
4576
4577 this->continuation(boost::move(this->parent));
4578
4579
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
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
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
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
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)
4654 : that_(x.that_)
4655 {}
4656 run_it& operator=(BOOST_THREAD_COPY_ASSIGN_REF(run_it) x)
4657 {
4658 if (this != &x) {
4659 that_=x.that_;
4660 }
4661 return *this;
4662 }
4663
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
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
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
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
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
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
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
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
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
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
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
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
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
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
4972
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
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
5044
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
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
5064
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
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
5097
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
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
5171
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
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
5193
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
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
5227
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
5296
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
5315
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
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
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
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
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
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
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
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
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 (
5580 vec_.push_back(boost::forward<T>(futures)),'0'
5581 )..., '0'
5582 };
5583 }
5584 #endif
5585
5586 ~future_when_all_vector_shared_state() {}
5587 };
5588
5589
5590
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 (
5653 vec_.push_back(boost::forward<T>(futures))
5654 ,'0'
5655 )...,
5656 '0'
5657 };
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
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
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
5894 }
5895
5896 #endif
5897 #endif