1 // (C) Copyright 2008-10 Anthony Williams
2 // (C) Copyright 2011-2015 Vicente J. Botet Escriba
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_THREAD_FUTURE_HPP
9 #define BOOST_THREAD_FUTURE_HPP
11 #include <boost/thread/detail/config.hpp>
13 // boost::thread::future requires exception handling
14 // due to boost::exception::exception_ptr dependency
16 //#define BOOST_THREAD_CONTINUATION_SYNC
18 #ifndef BOOST_NO_EXCEPTIONS
20 #include <boost/thread/condition_variable.hpp>
21 #include <boost/thread/detail/move.hpp>
22 #include <boost/thread/detail/invoker.hpp>
23 #include <boost/thread/detail/invoke.hpp>
24 #include <boost/thread/detail/is_convertible.hpp>
25 #include <boost/thread/exceptional_ptr.hpp>
26 #include <boost/thread/futures/future_error.hpp>
27 #include <boost/thread/futures/future_error_code.hpp>
28 #include <boost/thread/futures/future_status.hpp>
29 #include <boost/thread/futures/is_future_type.hpp>
30 #include <boost/thread/futures/launch.hpp>
31 #include <boost/thread/futures/wait_for_all.hpp>
32 #include <boost/thread/futures/wait_for_any.hpp>
33 #include <boost/thread/lock_algorithms.hpp>
34 #include <boost/thread/lock_types.hpp>
35 #include <boost/thread/mutex.hpp>
36 #include <boost/thread/thread_only.hpp>
37 #include <boost/thread/thread_time.hpp>
38 #include <boost/thread/executor.hpp>
39 #include <boost/thread/executors/generic_executor_ref.hpp>
41 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
42 #include <boost/optional.hpp>
44 #include <boost/thread/csbl/memory/unique_ptr.hpp>
47 #include <boost/assert.hpp>
48 #include <boost/bind.hpp>
49 #ifdef BOOST_THREAD_USES_CHRONO
50 #include <boost/chrono/system_clocks.hpp>
52 #include <boost/core/enable_if.hpp>
53 #include <boost/core/ref.hpp>
54 #include <boost/enable_shared_from_this.hpp>
55 #include <boost/exception_ptr.hpp>
56 #include <boost/function.hpp>
57 #include <boost/next_prior.hpp>
58 #include <boost/scoped_array.hpp>
59 #include <boost/shared_ptr.hpp>
60 #include <boost/smart_ptr/make_shared.hpp>
61 #include <boost/throw_exception.hpp>
62 #include <boost/type_traits/conditional.hpp>
63 #include <boost/type_traits/decay.hpp>
64 #include <boost/type_traits/is_copy_constructible.hpp>
65 #include <boost/type_traits/is_fundamental.hpp>
66 #include <boost/type_traits/is_void.hpp>
67 #include <boost/utility/result_of.hpp>
70 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
71 #include <boost/thread/detail/memory.hpp>
72 #include <boost/container/scoped_allocator.hpp>
73 #if ! defined BOOST_NO_CXX11_ALLOCATOR
78 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
79 #include <boost/thread/csbl/tuple.hpp>
80 #include <boost/thread/csbl/vector.hpp>
88 #if defined BOOST_THREAD_PROVIDES_FUTURE
89 #define BOOST_THREAD_FUTURE future
91 #define BOOST_THREAD_FUTURE unique_future
97 shared_ptr<T> static_shared_from_this(T* that)
99 return static_pointer_cast<T>(that->shared_from_this());
102 shared_ptr<T const> static_shared_from_this(T const* that)
104 return static_pointer_cast<T const>(that->shared_from_this());
107 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
109 namespace executors {
113 typedef shared_ptr<executor> executor_ptr_type;
120 boost::unique_lock<boost::mutex>& lock_;
122 relocker(boost::unique_lock<boost::mutex>& lk):
129 if (! lock_.owns_lock()) {
134 if (! lock_.owns_lock()) {
139 relocker& operator=(relocker const&);
142 struct shared_state_base : enable_shared_from_this<shared_state_base>
144 typedef std::list<boost::condition_variable_any*> waiter_list;
145 typedef waiter_list::iterator notify_when_ready_handle;
146 // This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
147 typedef shared_ptr<shared_state_base> continuation_ptr_type;
148 typedef std::vector<continuation_ptr_type> continuations_type;
150 boost::exception_ptr exception;
156 mutable boost::mutex mutex;
157 boost::condition_variable waiters;
158 waiter_list external_waiters;
159 boost::function<void()> callback;
160 // This declaration should be only included conditionally, but is included to maintain the same layout.
161 continuations_type continuations;
162 executor_ptr_type ex;
164 // This declaration should be only included conditionally, but is included to maintain the same layout.
165 virtual void launch_continuation()
173 is_constructed(false),
174 policy_(launch::none),
179 shared_state_base(exceptional_ptr const& ex_):
184 is_constructed(false),
185 policy_(launch::none),
191 virtual ~shared_state_base()
194 executor_ptr_type get_executor()
199 void set_executor_policy(executor_ptr_type aex)
204 void set_executor_policy(executor_ptr_type aex, boost::lock_guard<boost::mutex>&)
209 void set_executor_policy(executor_ptr_type aex, boost::unique_lock<boost::mutex>&)
215 bool valid(boost::unique_lock<boost::mutex>&) { return is_valid_; }
217 boost::unique_lock<boost::mutex> lk(this->mutex);
220 void invalidate(boost::unique_lock<boost::mutex>&) { is_valid_ = false; }
222 boost::unique_lock<boost::mutex> lk(this->mutex);
225 void validate(boost::unique_lock<boost::mutex>&) { is_valid_ = true; }
227 boost::unique_lock<boost::mutex> lk(this->mutex);
234 policy_ = launch::deferred;
238 is_deferred_ = false;
239 policy_ = launch::async;
241 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
244 is_deferred_ = false;
245 policy_ = launch::executor;
252 notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
254 boost::unique_lock<boost::mutex> lock(this->mutex);
256 return external_waiters.insert(external_waiters.end(),&cv);
259 void unnotify_when_ready(notify_when_ready_handle it)
261 boost::lock_guard<boost::mutex> lock(this->mutex);
262 external_waiters.erase(it);
265 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
266 void do_continuation(boost::unique_lock<boost::mutex>& lock)
268 if (! continuations.empty()) {
269 continuations_type the_continuations = continuations;
270 continuations.clear();
272 for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) {
273 (*it)->launch_continuation();
278 void do_continuation(boost::unique_lock<boost::mutex>&)
282 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
283 virtual void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
285 continuations.push_back(continuation);
287 do_continuation(lock);
291 void mark_finished_internal(boost::unique_lock<boost::mutex>& lock)
294 waiters.notify_all();
295 for(waiter_list::const_iterator it=external_waiters.begin(),
296 end=external_waiters.end();it!=end;++it)
300 do_continuation(lock);
302 void notify_deferred()
304 boost::unique_lock<boost::mutex> lock(this->mutex);
305 mark_finished_internal(lock);
308 void do_callback(boost::unique_lock<boost::mutex>& lock)
310 if(callback && !done)
312 boost::function<void()> local_callback=callback;
313 relocker relock(lock);
318 virtual bool run_if_is_deferred()
320 boost::unique_lock<boost::mutex> lk(this->mutex);
330 virtual bool run_if_is_deferred_or_ready()
332 boost::unique_lock<boost::mutex> lk(this->mutex);
343 void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true)
355 if(rethrow && exception)
357 boost::rethrow_exception(exception);
361 virtual void wait(boost::unique_lock<boost::mutex>& lock, bool rethrow=true)
363 wait_internal(lock, rethrow);
366 void wait(bool rethrow=true)
368 boost::unique_lock<boost::mutex> lock(this->mutex);
372 #if defined BOOST_THREAD_USES_DATETIME
373 bool timed_wait_until(boost::system_time const& target_time)
375 boost::unique_lock<boost::mutex> lock(this->mutex);
382 bool const success=waiters.timed_wait(lock,target_time);
383 if(!success && !done)
391 #ifdef BOOST_THREAD_USES_CHRONO
393 template <class Clock, class Duration>
395 wait_until(const chrono::time_point<Clock, Duration>& abs_time)
397 boost::unique_lock<boost::mutex> lock(this->mutex);
399 return future_status::deferred;
403 cv_status const st=waiters.wait_until(lock,abs_time);
404 if(st==cv_status::timeout && !done)
406 return future_status::timeout;
409 return future_status::ready;
412 void mark_exceptional_finish_internal(boost::exception_ptr const& e, boost::unique_lock<boost::mutex>& lock)
415 mark_finished_internal(lock);
418 void mark_exceptional_finish()
420 boost::unique_lock<boost::mutex> lock(this->mutex);
421 mark_exceptional_finish_internal(boost::current_exception(), lock);
424 void set_exception_deferred(exception_ptr e)
426 unique_lock<boost::mutex> lk(this->mutex);
429 throw_exception(promise_already_satisfied());
432 this->is_constructed = true;
434 void set_exception_at_thread_exit(exception_ptr e)
436 set_exception_deferred(e);
437 // unique_lock<boost::mutex> lk(this->mutex);
438 // if (has_value(lk))
440 // throw_exception(promise_already_satisfied());
443 // this->is_constructed = true;
444 detail::make_ready_at_thread_exit(shared_from_this());
447 bool has_value() const
449 boost::lock_guard<boost::mutex> lock(this->mutex);
450 return done && ! exception;
453 bool has_value(unique_lock<boost::mutex>& ) const
455 return done && ! exception;
458 bool has_exception() const
460 boost::lock_guard<boost::mutex> lock(this->mutex);
461 return done && exception;
464 launch launch_policy(boost::unique_lock<boost::mutex>&) const
469 future_state::state get_state(boost::unique_lock<boost::mutex>&) const
473 return future_state::waiting;
477 return future_state::ready;
480 future_state::state get_state() const
482 boost::lock_guard<boost::mutex> guard(this->mutex);
485 return future_state::waiting;
489 return future_state::ready;
493 exception_ptr get_exception_ptr()
495 boost::unique_lock<boost::mutex> lock(this->mutex);
496 wait_internal(lock, false);
500 template<typename F,typename U>
501 void set_wait_callback(F f,U* u)
503 boost::lock_guard<boost::mutex> lock(this->mutex);
504 callback=boost::bind(f,boost::ref(*u));
507 virtual void execute(boost::unique_lock<boost::mutex>&) {}
510 shared_state_base(shared_state_base const&);
511 shared_state_base& operator=(shared_state_base const&);
514 // Used to create stand-alone futures
517 detail::shared_state_base
519 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
520 typedef boost::optional<T> storage_type;
522 typedef boost::csbl::unique_ptr<T> storage_type;
524 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
525 typedef T const& source_reference_type;
526 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
527 typedef T move_dest_type;
528 #elif defined BOOST_THREAD_USES_MOVE
529 typedef typename conditional<boost::is_fundamental<T>::value,T,T const&>::type source_reference_type;
530 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
531 typedef T move_dest_type;
533 typedef T& source_reference_type;
534 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;
535 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;
538 typedef const T& shared_future_get_result_type;
545 shared_state(exceptional_ptr const& ex):
546 detail::shared_state_base(ex), result()
554 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
556 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
559 result.reset(new T(result_));
561 this->mark_finished_internal(lock);
564 void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
566 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
567 result = boost::move(result_);
568 #elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
569 result.reset(new T(boost::move(result_)));
571 result.reset(new T(static_cast<rvalue_source_type>(result_)));
573 this->mark_finished_internal(lock);
577 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
578 template <class ...Args>
579 void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock, BOOST_THREAD_FWD_REF(Args)... args)
581 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
582 result.emplace(boost::forward<Args>(args)...);
584 result.reset(new T(boost::forward<Args>(args)...));
586 this->mark_finished_internal(lock);
590 void mark_finished_with_result(source_reference_type result_)
592 boost::unique_lock<boost::mutex> lock(this->mutex);
593 this->mark_finished_with_result_internal(result_, lock);
596 void mark_finished_with_result(rvalue_source_type result_)
598 boost::unique_lock<boost::mutex> lock(this->mutex);
600 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
601 mark_finished_with_result_internal(boost::move(result_), lock);
603 mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
607 storage_type& get_storage(boost::unique_lock<boost::mutex>& lk)
612 virtual move_dest_type get(boost::unique_lock<boost::mutex>& lk)
614 return boost::move(*get_storage(lk));
618 boost::unique_lock<boost::mutex> lk(this->mutex);
619 return this->get(lk);
622 virtual shared_future_get_result_type get_sh(boost::unique_lock<boost::mutex>& lk)
624 return *get_storage(lk);
626 shared_future_get_result_type get_sh()
628 boost::unique_lock<boost::mutex> lk(this->mutex);
629 return this->get_sh(lk);
631 void set_value_deferred(source_reference_type result_)
633 unique_lock<boost::mutex> lk(this->mutex);
634 if (this->has_value(lk))
636 throw_exception(promise_already_satisfied());
638 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
641 result.reset(new T(result_));
644 this->is_constructed = true;
646 void set_value_deferred(rvalue_source_type result_)
648 unique_lock<boost::mutex> lk(this->mutex);
649 if (this->has_value(lk))
651 throw_exception(promise_already_satisfied());
654 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
655 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
656 result = boost::move(result_);
658 result.reset(new T(boost::move(result_)));
661 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
662 result = boost::move(result_);
664 result.reset(new T(static_cast<rvalue_source_type>(result_)));
667 this->is_constructed = true;
670 void set_value_at_thread_exit(source_reference_type result_)
672 set_value_deferred(result_);
673 // unique_lock<boost::mutex> lk(this->mutex);
674 // if (this->has_value(lk))
676 // throw_exception(promise_already_satisfied());
678 //#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
681 // result.reset(new T(result_));
684 // this->is_constructed = true;
685 detail::make_ready_at_thread_exit(shared_from_this());
687 void set_value_at_thread_exit(rvalue_source_type result_)
689 set_value_deferred(boost::move(result_));
690 // unique_lock<boost::mutex> lk(this->mutex);
691 // if (this->has_value(lk))
692 // throw_exception(promise_already_satisfied());
694 //#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
695 //#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
696 // result = boost::move(result_);
698 // result.reset(new T(boost::move(result_)));
701 //#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
702 // result = boost::move(result_);
704 // result.reset(new T(static_cast<rvalue_source_type>(result_)));
707 // this->is_constructed = true;
708 detail::make_ready_at_thread_exit(shared_from_this());
712 shared_state(shared_state const&);
713 shared_state& operator=(shared_state const&);
717 struct shared_state<T&>:
718 detail::shared_state_base
720 typedef T* storage_type;
721 typedef T& source_reference_type;
722 typedef T& move_dest_type;
723 typedef T& shared_future_get_result_type;
731 shared_state(exceptional_ptr const& ex):
732 detail::shared_state_base(ex), result(0)
739 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
742 mark_finished_internal(lock);
745 void mark_finished_with_result(source_reference_type result_)
747 boost::unique_lock<boost::mutex> lock(this->mutex);
748 mark_finished_with_result_internal(result_, lock);
751 virtual T& get(boost::unique_lock<boost::mutex>& lock)
758 boost::unique_lock<boost::mutex> lk(this->mutex);
762 virtual T& get_sh(boost::unique_lock<boost::mutex>& lock)
769 boost::unique_lock<boost::mutex> lock(this->mutex);
773 void set_value_deferred(T& result_)
775 unique_lock<boost::mutex> lk(this->mutex);
776 if (this->has_value(lk))
778 throw_exception(promise_already_satisfied());
781 this->is_constructed = true;
784 void set_value_at_thread_exit(T& result_)
786 set_value_deferred(result_);
787 // unique_lock<boost::mutex> lk(this->mutex);
788 // if (this->has_value(lk))
789 // throw_exception(promise_already_satisfied());
791 // this->is_constructed = true;
792 detail::make_ready_at_thread_exit(shared_from_this());
796 shared_state(shared_state const&);
797 shared_state& operator=(shared_state const&);
801 struct shared_state<void>:
802 detail::shared_state_base
804 typedef void shared_future_get_result_type;
805 typedef void move_dest_type;
810 shared_state(exceptional_ptr const& ex):
811 detail::shared_state_base(ex)
814 void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
816 mark_finished_internal(lock);
819 void mark_finished_with_result()
821 boost::unique_lock<boost::mutex> lock(this->mutex);
822 mark_finished_with_result_internal(lock);
825 virtual void get(boost::unique_lock<boost::mutex>& lock)
827 this->wait_internal(lock);
831 boost::unique_lock<boost::mutex> lock(this->mutex);
835 virtual void get_sh(boost::unique_lock<boost::mutex>& lock)
837 this->wait_internal(lock);
841 boost::unique_lock<boost::mutex> lock(this->mutex);
845 void set_value_deferred()
847 unique_lock<boost::mutex> lk(this->mutex);
848 if (this->has_value(lk))
850 throw_exception(promise_already_satisfied());
852 this->is_constructed = true;
854 void set_value_at_thread_exit()
856 set_value_deferred();
857 // unique_lock<boost::mutex> lk(this->mutex);
858 // if (this->has_value(lk))
860 // throw_exception(promise_already_satisfied());
862 // this->is_constructed = true;
863 detail::make_ready_at_thread_exit(shared_from_this());
866 shared_state(shared_state const&);
867 shared_state& operator=(shared_state const&);
870 /////////////////////////
871 /// future_async_shared_state_base
872 /////////////////////////
873 template<typename Rp>
874 struct future_async_shared_state_base: shared_state<Rp>
876 typedef shared_state<Rp> base_type;
878 #ifdef BOOST_THREAD_FUTURE_BLOCKING
882 if (this_thread::get_id() == thr_.get_id())
887 if (thr_.joinable()) thr_.join();
891 future_async_shared_state_base()
896 ~future_async_shared_state_base()
898 #ifdef BOOST_THREAD_FUTURE_BLOCKING
900 #elif defined BOOST_THREAD_ASYNC_FUTURE_WAITS
901 unique_lock<boost::mutex> lk(this->mutex);
904 this->waiters.wait(lk);
909 virtual void wait(boost::unique_lock<boost::mutex>& lk, bool rethrow)
911 #ifdef BOOST_THREAD_FUTURE_BLOCKING
917 this->base_type::wait(lk, rethrow);
921 /////////////////////////
922 /// future_async_shared_state
923 /////////////////////////
924 template<typename Rp, typename Fp>
925 struct future_async_shared_state: future_async_shared_state_base<Rp>
927 future_async_shared_state()
931 void init(BOOST_THREAD_FWD_REF(Fp) f)
933 #ifdef BOOST_THREAD_FUTURE_BLOCKING
934 this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f));
936 boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f)).detach();
940 static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
944 that->mark_finished_with_result(f());
948 that->mark_exceptional_finish();
953 template<typename Fp>
954 struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void>
956 void init(BOOST_THREAD_FWD_REF(Fp) f)
958 #ifdef BOOST_THREAD_FUTURE_BLOCKING
959 this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
961 boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
965 static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
970 that->mark_finished_with_result();
974 that->mark_exceptional_finish();
979 template<typename Rp, typename Fp>
980 struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&>
982 void init(BOOST_THREAD_FWD_REF(Fp) f)
984 #ifdef BOOST_THREAD_FUTURE_BLOCKING
985 this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
987 boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
991 static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
995 that->mark_finished_with_result(f());
999 that->mark_exceptional_finish();
1004 //////////////////////////
1005 /// future_deferred_shared_state
1006 //////////////////////////
1007 template<typename Rp, typename Fp>
1008 struct future_deferred_shared_state: shared_state<Rp>
1010 typedef shared_state<Rp> base_type;
1014 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1015 : func_(boost::move(f))
1017 this->set_deferred();
1020 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1023 Fp local_fuct=boost::move(func_);
1024 relocker relock(lck);
1025 Rp res = local_fuct();
1027 this->mark_finished_with_result_internal(boost::move(res), lck);
1031 this->mark_exceptional_finish_internal(current_exception(), lck);
1035 template<typename Rp, typename Fp>
1036 struct future_deferred_shared_state<Rp&,Fp>: shared_state<Rp&>
1038 typedef shared_state<Rp&> base_type;
1042 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1043 : func_(boost::move(f))
1045 this->set_deferred();
1048 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1051 this->mark_finished_with_result_internal(func_(), lck);
1055 this->mark_exceptional_finish_internal(current_exception(), lck);
1060 template<typename Fp>
1061 struct future_deferred_shared_state<void,Fp>: shared_state<void>
1063 typedef shared_state<void> base_type;
1067 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
1068 : func_(boost::move(f))
1070 this->set_deferred();
1073 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1076 Fp local_fuct=boost::move(func_);
1077 relocker relock(lck);
1080 this->mark_finished_with_result_internal(lck);
1084 this->mark_exceptional_finish_internal(current_exception(), lck);
1092 typedef std::vector<int>::size_type count_type;
1094 struct registered_waiter;
1095 struct registered_waiter
1097 boost::shared_ptr<detail::shared_state_base> future_;
1098 detail::shared_state_base::notify_when_ready_handle handle;
1101 registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
1102 detail::shared_state_base::notify_when_ready_handle handle_,
1104 future_(a_future),handle(handle_),index(index_)
1108 struct all_futures_lock
1111 typedef std::ptrdiff_t count_type_portable;
1113 typedef count_type count_type_portable;
1115 count_type_portable count;
1116 boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
1118 all_futures_lock(std::vector<registered_waiter>& futures):
1119 count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
1121 for(count_type_portable i=0;i<count;++i)
1123 locks[i]=BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(futures[i].future_->mutex));
1129 boost::lock(locks.get(),locks.get()+count);
1134 for(count_type_portable i=0;i<count;++i)
1141 boost::condition_variable_any cv;
1142 std::vector<registered_waiter> futures_;
1143 count_type future_count;
1150 template<typename F>
1155 registered_waiter waiter(f.future_,f.future_->notify_when_ready(cv),future_count);
1157 futures_.push_back(waiter);
1159 f.future_->unnotify_when_ready(waiter.handle);
1166 #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1167 template<typename F1, typename... Fs>
1168 void add(F1& f1, Fs&... fs)
1170 add(f1); add(fs...);
1176 all_futures_lock lk(futures_);
1179 for(count_type i=0;i<futures_.size();++i)
1181 if(futures_[i].future_->done)
1183 return futures_[i].index;
1192 for(count_type i=0;i<futures_.size();++i)
1194 futures_[i].future_->unnotify_when_ready(futures_[i].handle);
1201 template <typename R>
1202 class BOOST_THREAD_FUTURE;
1204 template <typename R>
1205 class shared_future;
1207 template<typename T>
1208 struct is_future_type<BOOST_THREAD_FUTURE<T> > : true_type
1212 template<typename T>
1213 struct is_future_type<shared_future<T> > : true_type
1217 // template<typename Iterator>
1218 // typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
1223 // detail::future_waiter waiter;
1224 // for(Iterator current=begin;current!=end;++current)
1226 // waiter.add(*current);
1228 // return boost::next(begin,waiter.wait());
1231 #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1232 template<typename F1,typename F2>
1233 typename boost::enable_if<is_future_type<F1>,typename detail::future_waiter::count_type>::type wait_for_any(F1& f1,F2& f2)
1235 detail::future_waiter waiter;
1238 return waiter.wait();
1241 template<typename F1,typename F2,typename F3>
1242 typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3)
1244 detail::future_waiter waiter;
1248 return waiter.wait();
1251 template<typename F1,typename F2,typename F3,typename F4>
1252 typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
1254 detail::future_waiter waiter;
1259 return waiter.wait();
1262 template<typename F1,typename F2,typename F3,typename F4,typename F5>
1263 typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
1265 detail::future_waiter waiter;
1271 return waiter.wait();
1274 template<typename F1, typename... Fs>
1275 typename boost::enable_if<is_future_type<F1>, typename detail::future_waiter::count_type>::type
1276 wait_for_any(F1& f1, Fs&... fs)
1278 detail::future_waiter waiter;
1279 waiter.add(f1, fs...);
1280 return waiter.wait();
1282 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1284 template <typename R>
1287 template <typename R>
1288 class packaged_task;
1292 /// Common implementation for all the futures independently of the return type
1297 /// Common implementation for future and shared_future.
1298 template <typename R>
1299 class basic_future : public base_future
1304 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
1305 typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
1307 static //BOOST_CONSTEXPR
1308 future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
1309 return future_ptr(new detail::shared_state<R>(ex));
1314 basic_future(future_ptr a_future):
1320 typedef future_state::state state;
1322 BOOST_THREAD_MOVABLE_ONLY(basic_future)
1323 basic_future(): future_() {}
1327 basic_future(exceptional_ptr const& ex)
1328 : future_(make_exceptional_future_ptr(ex))
1335 basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
1336 future_(BOOST_THREAD_RV(other).future_)
1338 BOOST_THREAD_RV(other).future_.reset();
1340 basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
1342 future_=BOOST_THREAD_RV(other).future_;
1343 BOOST_THREAD_RV(other).future_.reset();
1346 void swap(basic_future& that) BOOST_NOEXCEPT
1348 future_.swap(that.future_);
1350 // functions to check state, and wait for ready
1351 state get_state(boost::unique_lock<boost::mutex>& lk) const
1355 return future_state::uninitialized;
1357 return future_->get_state(lk);
1359 state get_state() const
1363 return future_state::uninitialized;
1365 return future_->get_state();
1368 bool is_ready() const
1370 return get_state()==future_state::ready;
1373 bool is_ready(boost::unique_lock<boost::mutex>& lk) const
1375 return get_state(lk)==future_state::ready;
1377 bool has_exception() const
1379 return future_ && future_->has_exception();
1382 bool has_value() const
1384 return future_ && future_->has_value();
1387 launch launch_policy(boost::unique_lock<boost::mutex>& lk) const
1389 if ( future_ ) return future_->launch_policy(lk);
1390 else return launch(launch::none);
1393 launch launch_policy() const
1396 boost::unique_lock<boost::mutex> lk(this->future_->mutex);
1397 return future_->launch_policy(lk);
1399 else return launch(launch::none);
1402 exception_ptr get_exception_ptr()
1405 ? future_->get_exception_ptr()
1409 bool valid() const BOOST_NOEXCEPT
1411 return future_.get() != 0 && future_->valid();
1418 boost::throw_exception(future_uninitialized());
1420 future_->wait(false);
1423 typedef detail::shared_state_base::notify_when_ready_handle notify_when_ready_handle;
1425 boost::mutex& mutex() {
1428 boost::throw_exception(future_uninitialized());
1430 return future_->mutex;
1433 notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
1437 boost::throw_exception(future_uninitialized());
1439 return future_->notify_when_ready(cv);
1442 void unnotify_when_ready(notify_when_ready_handle h)
1446 boost::throw_exception(future_uninitialized());
1448 return future_->unnotify_when_ready(h);
1451 #if defined BOOST_THREAD_USES_DATETIME
1452 template<typename Duration>
1453 bool timed_wait(Duration const& rel_time) const
1455 return timed_wait_until(boost::get_system_time()+rel_time);
1458 bool timed_wait_until(boost::system_time const& abs_time) const
1462 boost::throw_exception(future_uninitialized());
1464 return future_->timed_wait_until(abs_time);
1467 #ifdef BOOST_THREAD_USES_CHRONO
1468 template <class Rep, class Period>
1470 wait_for(const chrono::duration<Rep, Period>& rel_time) const
1472 return wait_until(chrono::steady_clock::now() + rel_time);
1475 template <class Clock, class Duration>
1477 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
1481 boost::throw_exception(future_uninitialized());
1483 return future_->wait_until(abs_time);
1490 BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END
1494 #if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005
1495 template <class Rp, class Fp>
1496 BOOST_THREAD_FUTURE<Rp>
1497 make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1499 template <class Rp, class Fp>
1500 BOOST_THREAD_FUTURE<Rp>
1501 make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1502 #endif // #if (!defined _MSC_VER || _MSC_VER >= 1400)
1503 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1504 template<typename F, typename Rp, typename Fp>
1505 struct future_deferred_continuation_shared_state;
1506 template<typename F, typename Rp, typename Fp>
1507 struct future_async_continuation_shared_state;
1509 template <class F, class Rp, class Fp>
1510 BOOST_THREAD_FUTURE<Rp>
1511 make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1513 template <class F, class Rp, class Fp>
1514 BOOST_THREAD_FUTURE<Rp>
1515 make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1517 template <class F, class Rp, class Fp>
1518 BOOST_THREAD_FUTURE<Rp>
1519 make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1521 template<typename F, typename Rp, typename Fp>
1522 BOOST_THREAD_FUTURE<Rp>
1523 make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1525 template<typename F, typename Rp, typename Fp>
1526 BOOST_THREAD_FUTURE<Rp>
1527 make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1529 template<typename F, typename Rp, typename Fp>
1530 BOOST_THREAD_FUTURE<Rp>
1531 make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1534 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1535 template<typename Ex, typename F, typename Rp, typename Fp>
1536 BOOST_THREAD_FUTURE<Rp>
1537 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);
1539 template<typename Ex, typename F, typename Rp, typename Fp>
1540 BOOST_THREAD_FUTURE<Rp>
1541 make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1543 template <class Rp, class Fp, class Executor>
1544 BOOST_THREAD_FUTURE<Rp>
1545 make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1548 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1549 template<typename F, typename Rp>
1550 struct future_unwrap_shared_state;
1551 template <class F, class Rp>
1552 inline BOOST_THREAD_FUTURE<Rp>
1553 make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1556 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1557 template< typename InputIterator>
1558 typename boost::disable_if<is_future_type<InputIterator>,
1559 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1561 when_all(InputIterator first, InputIterator last);
1563 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1565 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1566 template< typename T0, typename ...T>
1567 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1568 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1571 template< typename InputIterator>
1572 typename boost::disable_if<is_future_type<InputIterator>,
1573 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1575 when_any(InputIterator first, InputIterator last);
1577 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1579 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1580 template< typename T0, typename ...T>
1581 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1582 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1584 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1587 template <typename R>
1588 class BOOST_THREAD_FUTURE : public detail::basic_future<R>
1591 typedef detail::basic_future<R> base_type;
1592 typedef typename base_type::future_ptr future_ptr;
1594 friend class shared_future<R>;
1595 friend class promise<R>;
1596 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1597 template <typename, typename, typename>
1598 friend struct detail::future_async_continuation_shared_state;
1599 template <typename, typename, typename>
1600 friend struct detail::future_deferred_continuation_shared_state;
1602 template <class F, class Rp, class Fp>
1603 friend BOOST_THREAD_FUTURE<Rp>
1604 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);
1606 template <class F, class Rp, class Fp>
1607 friend BOOST_THREAD_FUTURE<Rp>
1608 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);
1610 template <class F, class Rp, class Fp>
1611 friend BOOST_THREAD_FUTURE<Rp>
1612 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);
1614 template<typename F, typename Rp, typename Fp>
1615 friend BOOST_THREAD_FUTURE<Rp>
1616 detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1618 template<typename F, typename Rp, typename Fp>
1619 friend BOOST_THREAD_FUTURE<Rp>
1620 detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1622 template<typename F, typename Rp, typename Fp>
1623 friend BOOST_THREAD_FUTURE<Rp>
1624 detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1626 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1627 template<typename Ex, typename F, typename Rp, typename Fp>
1628 friend BOOST_THREAD_FUTURE<Rp>
1629 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);
1631 template<typename Ex, typename F, typename Rp, typename Fp>
1632 friend BOOST_THREAD_FUTURE<Rp>
1633 detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1635 template <class Rp, class Fp, class Executor>
1636 friend BOOST_THREAD_FUTURE<Rp>
1637 detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1640 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1641 template<typename F, typename Rp>
1642 friend struct detail::future_unwrap_shared_state;
1643 template <class F, class Rp>
1644 friend BOOST_THREAD_FUTURE<Rp>
1645 detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1647 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1648 template< typename InputIterator>
1649 friend typename boost::disable_if<is_future_type<InputIterator>,
1650 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1652 when_all(InputIterator first, InputIterator last);
1654 //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1656 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1657 template< typename T0, typename ...T>
1658 friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1659 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1662 template< typename InputIterator>
1663 friend typename boost::disable_if<is_future_type<InputIterator>,
1664 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1666 when_any(InputIterator first, InputIterator last);
1668 //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1670 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1671 template< typename T0, typename ...T>
1672 friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1673 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1675 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1676 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1677 template <class> friend class packaged_task; // todo check if this works in windows
1679 friend class packaged_task<R>;
1681 friend class detail::future_waiter;
1683 template <class Rp, class Fp>
1684 friend BOOST_THREAD_FUTURE<Rp>
1685 detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1687 template <class Rp, class Fp>
1688 friend BOOST_THREAD_FUTURE<Rp>
1689 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1691 typedef typename base_type::move_dest_type move_dest_type;
1693 BOOST_THREAD_FUTURE(future_ptr a_future):
1699 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1700 typedef future_state::state state;
1701 typedef R value_type; // EXTENSION
1703 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1705 BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1708 ~BOOST_THREAD_FUTURE() {
1711 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1712 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1715 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1716 inline explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
1719 explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(shared_future<R>) other) :
1720 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1723 BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
1725 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1729 shared_future<R> share()
1731 return shared_future<R>(::boost::move(*this));
1734 void swap(BOOST_THREAD_FUTURE& other)
1736 static_cast<base_type*>(this)->swap(other);
1739 // todo this function must be private and friendship provided to the internal users.
1742 this->future_->set_async();
1744 // todo this function must be private and friendship provided to the internal users.
1747 this->future_->set_deferred();
1749 bool run_if_is_deferred() {
1750 return this->future_->run_if_is_deferred();
1752 bool run_if_is_deferred_or_ready() {
1753 return this->future_->run_if_is_deferred_or_ready();
1755 // retrieving the value
1756 move_dest_type get()
1758 if (this->future_.get() == 0)
1760 boost::throw_exception(future_uninitialized());
1762 unique_lock<boost::mutex> lk(this->future_->mutex);
1763 if (! this->future_->valid(lk))
1765 boost::throw_exception(future_uninitialized());
1767 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1768 this->future_->invalidate(lk);
1770 return this->future_->get(lk);
1773 template <typename R2>
1774 typename boost::disable_if< is_void<R2>, move_dest_type>::type
1775 get_or(BOOST_THREAD_RV_REF(R2) v)
1778 if (this->future_.get() == 0)
1780 boost::throw_exception(future_uninitialized());
1782 unique_lock<boost::mutex> lk(this->future_->mutex);
1783 if (! this->future_->valid(lk))
1785 boost::throw_exception(future_uninitialized());
1787 this->future_->wait(lk, false);
1788 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1789 this->future_->invalidate(lk);
1792 if (this->future_->has_value(lk)) {
1793 return this->future_->get(lk);
1796 return boost::move(v);
1800 template <typename R2>
1801 typename boost::disable_if< is_void<R2>, move_dest_type>::type
1802 get_or(R2 const& v) // EXTENSION
1804 if (this->future_.get() == 0)
1806 boost::throw_exception(future_uninitialized());
1808 unique_lock<boost::mutex> lk(this->future_->mutex);
1809 if (! this->future_->valid(lk))
1811 boost::throw_exception(future_uninitialized());
1813 this->future_->wait(lk, false);
1814 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1815 this->future_->invalidate(lk);
1817 if (this->future_->has_value(lk)) {
1818 return this->future_->get(lk);
1825 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1826 template<typename F>
1827 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1828 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1829 template<typename F>
1830 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1831 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1832 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1833 template<typename Ex, typename F>
1834 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1835 then(Ex& ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1838 template <typename R2>
1839 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1840 fallback_to(BOOST_THREAD_RV_REF(R2) v); // EXTENSION
1841 template <typename R2>
1842 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1843 fallback_to(R2 const& v); // EXTENSION
1849 BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
1851 template <typename R2>
1852 class BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> > : public detail::basic_future<BOOST_THREAD_FUTURE<R2> >
1854 typedef BOOST_THREAD_FUTURE<R2> R;
1857 typedef detail::basic_future<R> base_type;
1858 typedef typename base_type::future_ptr future_ptr;
1860 friend class shared_future<R>;
1861 friend class promise<R>;
1862 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1863 template <typename, typename, typename>
1864 friend struct detail::future_async_continuation_shared_state;
1865 template <typename, typename, typename>
1866 friend struct detail::future_deferred_continuation_shared_state;
1868 template <class F, class Rp, class Fp>
1869 friend BOOST_THREAD_FUTURE<Rp>
1870 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);
1872 template <class F, class Rp, class Fp>
1873 friend BOOST_THREAD_FUTURE<Rp>
1874 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);
1876 template <class F, class Rp, class Fp>
1877 friend BOOST_THREAD_FUTURE<Rp>
1878 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);
1880 template<typename F, typename Rp, typename Fp>
1881 friend BOOST_THREAD_FUTURE<Rp>
1882 detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1884 template<typename F, typename Rp, typename Fp>
1885 friend BOOST_THREAD_FUTURE<Rp>
1886 detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1888 template<typename F, typename Rp, typename Fp>
1889 friend BOOST_THREAD_FUTURE<Rp>
1890 detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1892 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1893 template<typename Ex, typename F, typename Rp, typename Fp>
1894 friend BOOST_THREAD_FUTURE<Rp>
1895 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);
1897 template<typename Ex, typename F, typename Rp, typename Fp>
1898 friend BOOST_THREAD_FUTURE<Rp>
1899 detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1901 template <class Rp, class Fp, class Executor>
1902 friend BOOST_THREAD_FUTURE<Rp>
1903 detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1907 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1908 template<typename F, typename Rp>
1909 friend struct detail::future_unwrap_shared_state;
1910 template <class F, class Rp>
1911 friend BOOST_THREAD_FUTURE<Rp>
1912 detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1914 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1915 template< typename InputIterator>
1916 friend typename boost::disable_if<is_future_type<InputIterator>,
1917 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1919 when_all(InputIterator first, InputIterator last);
1921 friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1923 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1924 template< typename T0, typename ...T>
1925 friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1926 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1929 template< typename InputIterator>
1930 friend typename boost::disable_if<is_future_type<InputIterator>,
1931 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1933 when_any(InputIterator first, InputIterator last);
1935 friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1937 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1938 template< typename T0, typename ...T>
1939 friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1940 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1942 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1944 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1945 template <class> friend class packaged_task; // todo check if this works in windows
1947 friend class packaged_task<R>;
1949 friend class detail::future_waiter;
1951 template <class Rp, class Fp>
1952 friend BOOST_THREAD_FUTURE<Rp>
1953 detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1955 template <class Rp, class Fp>
1956 friend BOOST_THREAD_FUTURE<Rp>
1957 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1959 typedef typename base_type::move_dest_type move_dest_type;
1961 BOOST_THREAD_FUTURE(future_ptr a_future):
1967 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1968 typedef future_state::state state;
1969 typedef R value_type; // EXTENSION
1971 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1973 BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1976 ~BOOST_THREAD_FUTURE() {
1979 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1980 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1984 BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
1986 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1990 shared_future<R> share()
1992 return shared_future<R>(::boost::move(*this));
1995 void swap(BOOST_THREAD_FUTURE& other)
1997 static_cast<base_type*>(this)->swap(other);
2000 // todo this function must be private and friendship provided to the internal users.
2003 this->future_->set_async();
2005 // todo this function must be private and friendship provided to the internal users.
2008 this->future_->set_deferred();
2010 bool run_if_is_deferred() {
2011 return this->future_->run_if_is_deferred();
2013 bool run_if_is_deferred_or_ready() {
2014 return this->future_->run_if_is_deferred_or_ready();
2016 // retrieving the value
2017 move_dest_type get()
2019 if (this->future_.get() == 0)
2021 boost::throw_exception(future_uninitialized());
2023 unique_lock<boost::mutex> lk(this->future_->mutex);
2024 if (! this->future_->valid(lk))
2026 boost::throw_exception(future_uninitialized());
2028 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
2029 this->future_->invalidate(lk);
2031 return this->future_->get(lk);
2033 move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
2035 if (this->future_.get() == 0)
2037 boost::throw_exception(future_uninitialized());
2039 unique_lock<boost::mutex> lk(this->future_->mutex);
2040 if (! this->future_->valid(lk))
2042 boost::throw_exception(future_uninitialized());
2044 this->future_->wait(lk, false);
2045 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
2046 this->future_->invalidate(lk);
2048 if (this->future_->has_value(lk)) return this->future_->get(lk);
2049 else return boost::move(v);
2052 move_dest_type get_or(R const& v) // EXTENSION
2054 if (this->future_.get() == 0)
2056 boost::throw_exception(future_uninitialized());
2058 unique_lock<boost::mutex> lk(this->future_->mutex);
2059 if (! this->future_->valid(lk))
2061 boost::throw_exception(future_uninitialized());
2063 this->future_->wait(lk, false);
2064 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
2065 this->future_->invalidate(lk);
2067 if (this->future_->has_value(lk)) return this->future_->get(lk);
2072 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2073 template<typename F>
2074 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2075 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2076 template<typename F>
2077 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2078 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2079 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2080 template<typename Ex, typename F>
2081 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2082 then(Ex &ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2086 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
2088 BOOST_THREAD_FUTURE<R2>
2089 unwrap(); // EXTENSION
2094 template <typename R>
2095 class shared_future : public detail::basic_future<R>
2097 typedef detail::basic_future<R> base_type;
2098 typedef typename base_type::future_ptr future_ptr;
2100 friend class detail::future_waiter;
2101 friend class promise<R>;
2103 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2104 template <typename, typename, typename>
2105 friend struct detail::future_async_continuation_shared_state;
2106 template <typename, typename, typename>
2107 friend struct detail::future_deferred_continuation_shared_state;
2109 template <class F, class Rp, class Fp>
2110 friend BOOST_THREAD_FUTURE<Rp>
2111 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);
2113 template <class F, class Rp, class Fp>
2114 friend BOOST_THREAD_FUTURE<Rp>
2115 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);
2117 template <class F, class Rp, class Fp>
2118 friend BOOST_THREAD_FUTURE<Rp>
2119 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);
2121 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2122 template <class> friend class packaged_task;// todo check if this works in windows
2124 friend class packaged_task<R>;
2126 shared_future(future_ptr a_future):
2131 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_future)
2132 typedef R value_type; // EXTENSION
2134 shared_future(shared_future const& other):
2135 base_type(other.future_)
2138 typedef future_state::state state;
2140 BOOST_CONSTEXPR shared_future()
2143 shared_future(exceptional_ptr const& ex):
2148 shared_future& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_future) other)
2150 this->future_ = other.future_;
2154 shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
2155 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2158 shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT :
2159 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2163 shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
2165 base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2168 shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT
2170 base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2174 void swap(shared_future& other) BOOST_NOEXCEPT
2176 static_cast<base_type*>(this)->swap(other);
2178 bool run_if_is_deferred() {
2179 return this->future_->run_if_is_deferred();
2181 bool run_if_is_deferred_or_ready() {
2182 return this->future_->run_if_is_deferred_or_ready();
2184 // retrieving the value
2185 typename detail::shared_state<R>::shared_future_get_result_type get() const
2189 boost::throw_exception(future_uninitialized());
2191 return this->future_->get_sh();
2194 template <typename R2>
2195 typename boost::disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type
2196 get_or(BOOST_THREAD_RV_REF(R2) v) const // EXTENSION
2200 boost::throw_exception(future_uninitialized());
2202 this->future_->wait();
2203 if (this->future_->has_value()) return this->future_->get_sh();
2204 else return boost::move(v);
2207 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2208 template<typename F>
2209 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2210 then(BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2211 template<typename F>
2212 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2213 then(launch policy, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2214 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2215 template<typename Ex, typename F>
2216 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2217 then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2223 BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
2225 template <typename R>
2228 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
2230 typedef typename detail::shared_state<R>::source_reference_type source_reference_type;
2231 typedef typename detail::shared_state<R>::rvalue_source_type rvalue_source_type;
2232 typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
2233 typedef typename detail::shared_state<R>::shared_future_get_result_type shared_future_get_result_type;
2236 bool future_obtained;
2240 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2241 #include <boost/thread/detail/atomic_undef_macros.hpp>
2242 if(!atomic_load(&future_))
2245 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R>));
2247 #include <boost/thread/detail/atomic_redef_macros.hpp>
2252 BOOST_THREAD_MOVABLE_ONLY(promise)
2253 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2254 template <class Allocator>
2255 promise(boost::allocator_arg_t, Allocator a)
2257 typedef typename Allocator::template rebind<detail::shared_state<R> >::other A2;
2259 typedef thread_detail::allocator_destructor<A2> D;
2261 future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R>(), D(a2, 1) );
2262 future_obtained = false;
2266 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2269 future_(new detail::shared_state<R>()),
2271 future_obtained(false)
2278 boost::unique_lock<boost::mutex> lock(future_->mutex);
2280 if(!future_->done && !future_->is_constructed)
2282 future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2288 promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2289 future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2291 BOOST_THREAD_RV(rhs).future_.reset();
2292 BOOST_THREAD_RV(rhs).future_obtained=false;
2294 promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2296 future_=BOOST_THREAD_RV(rhs).future_;
2297 future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2298 BOOST_THREAD_RV(rhs).future_.reset();
2299 BOOST_THREAD_RV(rhs).future_obtained=false;
2303 void swap(promise& other)
2305 future_.swap(other.future_);
2306 std::swap(future_obtained,other.future_obtained);
2309 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2310 void set_executor(executor_ptr_type aex)
2313 if (future_.get()==0)
2315 boost::throw_exception(promise_moved());
2317 boost::lock_guard<boost::mutex> lk(future_->mutex);
2318 future_->set_executor_policy(aex, lk);
2322 BOOST_THREAD_FUTURE<R> get_future()
2325 if (future_.get()==0)
2327 boost::throw_exception(promise_moved());
2329 if (future_obtained)
2331 boost::throw_exception(future_already_retrieved());
2333 future_obtained=true;
2334 return BOOST_THREAD_FUTURE<R>(future_);
2337 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
2339 typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
2340 set_value(TR const & r)
2343 boost::unique_lock<boost::mutex> lock(future_->mutex);
2346 boost::throw_exception(promise_already_satisfied());
2348 future_->mark_finished_with_result_internal(r, lock);
2351 void set_value(source_reference_type r)
2354 boost::unique_lock<boost::mutex> lock(future_->mutex);
2357 boost::throw_exception(promise_already_satisfied());
2359 future_->mark_finished_with_result_internal(r, lock);
2363 void set_value(rvalue_source_type r)
2366 boost::unique_lock<boost::mutex> lock(future_->mutex);
2369 boost::throw_exception(promise_already_satisfied());
2371 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
2372 future_->mark_finished_with_result_internal(boost::move(r), lock);
2374 future_->mark_finished_with_result_internal(static_cast<rvalue_source_type>(r), lock);
2378 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
2380 typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
2381 set_value_deferred(TR const & r)
2384 if (future_.get()==0)
2386 boost::throw_exception(promise_moved());
2388 future_->set_value_deferred(r);
2391 void set_value_deferred(source_reference_type r)
2394 if (future_.get()==0)
2396 boost::throw_exception(promise_moved());
2398 future_->set_value_deferred(r);
2402 void set_value_deferred(rvalue_source_type r)
2405 if (future_.get()==0)
2407 boost::throw_exception(promise_moved());
2409 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
2410 future_->set_value_deferred(boost::move(r));
2412 future_->set_value_deferred(static_cast<rvalue_source_type>(r));
2416 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
2417 template <class ...Args>
2418 void emplace(BOOST_THREAD_FWD_REF(Args) ...args)
2421 boost::unique_lock<boost::mutex> lock(future_->mutex);
2424 boost::throw_exception(promise_already_satisfied());
2426 future_->mark_finished_with_result_internal(lock, boost::forward<Args>(args)...);
2431 void set_exception(boost::exception_ptr p)
2434 boost::unique_lock<boost::mutex> lock(future_->mutex);
2437 boost::throw_exception(promise_already_satisfied());
2439 future_->mark_exceptional_finish_internal(p, lock);
2441 template <typename E>
2442 void set_exception(E ex)
2444 set_exception(boost::copy_exception(ex));
2446 void set_exception_deferred(boost::exception_ptr p)
2449 if (future_.get()==0)
2451 boost::throw_exception(promise_moved());
2453 future_->set_exception_deferred(p);
2455 template <typename E>
2456 void set_exception_deferred(E ex)
2458 set_exception_deferred(boost::copy_exception(ex));
2461 // setting the result with deferred notification
2462 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
2464 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)
2466 if (future_.get()==0)
2468 boost::throw_exception(promise_moved());
2470 future_->set_value_at_thread_exit(r);
2473 void set_value_at_thread_exit(source_reference_type r)
2475 if (future_.get()==0)
2477 boost::throw_exception(promise_moved());
2479 future_->set_value_at_thread_exit(r);
2482 void set_value_at_thread_exit(BOOST_THREAD_RV_REF(R) r)
2484 if (future_.get()==0)
2486 boost::throw_exception(promise_moved());
2488 future_->set_value_at_thread_exit(boost::move(r));
2490 void set_exception_at_thread_exit(exception_ptr e)
2492 if (future_.get()==0)
2494 boost::throw_exception(promise_moved());
2496 future_->set_exception_at_thread_exit(e);
2498 template <typename E>
2499 void set_exception_at_thread_exit(E ex)
2501 set_exception_at_thread_exit(boost::copy_exception(ex));
2504 template<typename F>
2505 void set_wait_callback(F f)
2508 future_->set_wait_callback(f,this);
2510 void notify_deferred()
2512 if (future_.get()==0)
2514 boost::throw_exception(promise_moved());
2516 future_->notify_deferred();
2521 template <typename R>
2524 typedef boost::shared_ptr<detail::shared_state<R&> > future_ptr;
2527 bool future_obtained;
2531 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2532 #include <boost/thread/detail/atomic_undef_macros.hpp>
2533 if(!atomic_load(&future_))
2536 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
2538 #include <boost/thread/detail/atomic_redef_macros.hpp>
2543 BOOST_THREAD_MOVABLE_ONLY(promise)
2544 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2545 template <class Allocator>
2546 promise(boost::allocator_arg_t, Allocator a)
2548 typedef typename Allocator::template rebind<detail::shared_state<R&> >::other A2;
2550 typedef thread_detail::allocator_destructor<A2> D;
2552 future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R&>(), D(a2, 1) );
2553 future_obtained = false;
2557 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2560 future_(new detail::shared_state<R&>()),
2562 future_obtained(false)
2569 boost::unique_lock<boost::mutex> lock(future_->mutex);
2571 if(!future_->done && !future_->is_constructed)
2573 future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2579 promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2580 future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2582 BOOST_THREAD_RV(rhs).future_.reset();
2583 BOOST_THREAD_RV(rhs).future_obtained=false;
2585 promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2587 future_=BOOST_THREAD_RV(rhs).future_;
2588 future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2589 BOOST_THREAD_RV(rhs).future_.reset();
2590 BOOST_THREAD_RV(rhs).future_obtained=false;
2594 void swap(promise& other)
2596 future_.swap(other.future_);
2597 std::swap(future_obtained,other.future_obtained);
2601 BOOST_THREAD_FUTURE<R&> get_future()
2604 if (future_.get()==0)
2606 boost::throw_exception(promise_moved());
2608 if (future_obtained)
2610 boost::throw_exception(future_already_retrieved());
2612 future_obtained=true;
2613 return BOOST_THREAD_FUTURE<R&>(future_);
2616 void set_value(R& r)
2619 boost::unique_lock<boost::mutex> lock(future_->mutex);
2622 boost::throw_exception(promise_already_satisfied());
2624 future_->mark_finished_with_result_internal(r, lock);
2626 void set_value_deferred(R& r)
2629 if (future_.get()==0)
2631 boost::throw_exception(promise_already_satisfied());
2633 future_->set_value_deferred(r);
2635 void set_exception(boost::exception_ptr p)
2638 boost::unique_lock<boost::mutex> lock(future_->mutex);
2641 boost::throw_exception(promise_already_satisfied());
2643 future_->mark_exceptional_finish_internal(p, lock);
2645 template <typename E>
2646 void set_exception(E ex)
2648 set_exception(boost::copy_exception(ex));
2650 void set_exception_deferred(boost::exception_ptr p)
2653 if (future_.get()==0)
2655 boost::throw_exception(promise_moved());
2657 future_->set_exception_deferred(p);
2659 template <typename E>
2660 void set_exception_deferred(E ex)
2662 set_exception_deferred(boost::copy_exception(ex));
2664 // setting the result with deferred notification
2665 void set_value_at_thread_exit(R& r)
2667 if (future_.get()==0)
2669 boost::throw_exception(promise_moved());
2671 future_->set_value_at_thread_exit(r);
2674 void set_exception_at_thread_exit(exception_ptr e)
2676 if (future_.get()==0)
2678 boost::throw_exception(promise_moved());
2680 future_->set_exception_at_thread_exit(e);
2682 template <typename E>
2683 void set_exception_at_thread_exit(E ex)
2685 set_exception_at_thread_exit(boost::copy_exception(ex));
2688 template<typename F>
2689 void set_wait_callback(F f)
2692 future_->set_wait_callback(f,this);
2694 void notify_deferred()
2696 if (future_.get()==0)
2698 boost::throw_exception(promise_moved());
2700 future_->notify_deferred();
2707 typedef boost::shared_ptr<detail::shared_state<void> > future_ptr;
2710 bool future_obtained;
2714 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2715 if(!atomic_load(&future_))
2718 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<void>));
2723 BOOST_THREAD_MOVABLE_ONLY(promise)
2725 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2726 template <class Allocator>
2727 promise(boost::allocator_arg_t, Allocator a)
2729 typedef typename Allocator::template rebind<detail::shared_state<void> >::other A2;
2731 typedef thread_detail::allocator_destructor<A2> D;
2733 future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<void>(), D(a2, 1) );
2734 future_obtained = false;
2738 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2741 future_(new detail::shared_state<void>),
2743 future_obtained(false)
2750 boost::unique_lock<boost::mutex> lock(future_->mutex);
2752 if(!future_->done && !future_->is_constructed)
2754 future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2760 promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2761 future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2763 // we need to release the future as shared_ptr doesn't implements move semantics
2764 BOOST_THREAD_RV(rhs).future_.reset();
2765 BOOST_THREAD_RV(rhs).future_obtained=false;
2768 promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2770 future_=BOOST_THREAD_RV(rhs).future_;
2771 future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2772 BOOST_THREAD_RV(rhs).future_.reset();
2773 BOOST_THREAD_RV(rhs).future_obtained=false;
2777 void swap(promise& other)
2779 future_.swap(other.future_);
2780 std::swap(future_obtained,other.future_obtained);
2784 BOOST_THREAD_FUTURE<void> get_future()
2788 if (future_.get()==0)
2790 boost::throw_exception(promise_moved());
2794 boost::throw_exception(future_already_retrieved());
2796 future_obtained=true;
2797 //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<void>(future_));
2798 return BOOST_THREAD_FUTURE<void>(future_);
2804 boost::unique_lock<boost::mutex> lock(future_->mutex);
2807 boost::throw_exception(promise_already_satisfied());
2809 future_->mark_finished_with_result_internal(lock);
2811 void set_value_deferred()
2814 if (future_.get()==0)
2816 boost::throw_exception(promise_moved());
2818 future_->set_value_deferred();
2821 void set_exception(boost::exception_ptr p)
2824 boost::unique_lock<boost::mutex> lock(future_->mutex);
2827 boost::throw_exception(promise_already_satisfied());
2829 future_->mark_exceptional_finish_internal(p,lock);
2831 template <typename E>
2832 void set_exception(E ex)
2834 set_exception(boost::copy_exception(ex));
2836 void set_exception_deferred(boost::exception_ptr p)
2839 if (future_.get()==0)
2841 boost::throw_exception(promise_moved());
2843 future_->set_exception_deferred(p);
2845 template <typename E>
2846 void set_exception_deferred(E ex)
2848 set_exception_deferred(boost::copy_exception(ex));
2850 // setting the result with deferred notification
2851 void set_value_at_thread_exit()
2853 if (future_.get()==0)
2855 boost::throw_exception(promise_moved());
2857 future_->set_value_at_thread_exit();
2860 void set_exception_at_thread_exit(exception_ptr e)
2862 if (future_.get()==0)
2864 boost::throw_exception(promise_moved());
2866 future_->set_exception_at_thread_exit(e);
2868 template <typename E>
2869 void set_exception_at_thread_exit(E ex)
2871 set_exception_at_thread_exit(boost::copy_exception(ex));
2874 template<typename F>
2875 void set_wait_callback(F f)
2878 future_->set_wait_callback(f,this);
2880 void notify_deferred()
2882 if (future_.get()==0)
2884 boost::throw_exception(promise_moved());
2886 future_->notify_deferred();
2890 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2891 namespace boost { namespace container {
2892 template <class R, class Alloc>
2893 struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2897 #if ! defined BOOST_NO_CXX11_ALLOCATOR
2899 template <class R, class Alloc>
2900 struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2910 BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
2914 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2915 template<typename R>
2916 struct task_base_shared_state;
2917 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2918 template<typename R, typename ...ArgTypes>
2919 struct task_base_shared_state<R(ArgTypes...)>:
2921 template<typename R>
2922 struct task_base_shared_state<R()>:
2925 template<typename R>
2926 struct task_base_shared_state:
2928 detail::shared_state<R>
2932 task_base_shared_state():
2938 // todo The packaged_task::reset must be as if an assignemnt froma new packaged_task with the same function
2939 // the reset function is an optimization that avoids reallocating a new task.
2943 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2944 virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
2945 void run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2947 virtual void do_run()=0;
2952 boost::lock_guard<boost::mutex> lk(this->mutex);
2955 boost::throw_exception(task_already_started());
2959 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2960 do_run(boost::move(args)...);
2966 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2967 virtual void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
2968 void apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2970 virtual void do_apply()=0;
2975 boost::lock_guard<boost::mutex> lk(this->mutex);
2978 boost::throw_exception(task_already_started());
2982 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2983 do_apply(boost::move(args)...);
2989 void owner_destroyed()
2991 boost::unique_lock<boost::mutex> lk(this->mutex);
2995 this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk);
3000 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3001 template<typename F, typename R>
3002 struct task_shared_state;
3003 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3004 template<typename F, typename R, typename ...ArgTypes>
3005 struct task_shared_state<F, R(ArgTypes...)>:
3006 task_base_shared_state<R(ArgTypes...)>
3008 template<typename F, typename R>
3009 struct task_shared_state<F, R()>:
3010 task_base_shared_state<R()>
3013 template<typename F, typename R>
3014 struct task_shared_state:
3015 task_base_shared_state<R>
3019 task_shared_state(task_shared_state&);
3022 task_shared_state(F const& f_):
3025 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3031 return boost::move(f);
3034 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3035 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3039 this->set_value_at_thread_exit(f(boost::move(args)...));
3046 this->set_value_at_thread_exit(f());
3051 this->set_exception_at_thread_exit(current_exception());
3055 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3056 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3060 this->mark_finished_with_result(f(boost::move(args)...));
3067 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3069 this->mark_finished_with_result(boost::move(res));
3071 this->mark_finished_with_result(f());
3077 this->mark_exceptional_finish();
3082 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3083 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3084 template<typename F, typename R, typename ...ArgTypes>
3085 struct task_shared_state<F, R&(ArgTypes...)>:
3086 task_base_shared_state<R&(ArgTypes...)>
3088 template<typename F, typename R>
3089 struct task_shared_state<F, R&()>:
3090 task_base_shared_state<R&()>
3093 template<typename F, typename R>
3094 struct task_shared_state<F,R&>:
3095 task_base_shared_state<R&>
3099 task_shared_state(task_shared_state&);
3102 task_shared_state(F const& f_):
3105 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3114 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3115 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3119 this->set_value_at_thread_exit(f(boost::move(args)...));
3126 this->set_value_at_thread_exit(f());
3131 this->set_exception_at_thread_exit(current_exception());
3135 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3136 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3140 this->mark_finished_with_result(f(boost::move(args)...));
3148 this->mark_finished_with_result(res);
3153 this->mark_exceptional_finish();
3158 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3160 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3161 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3162 template<typename R, typename ...ArgTypes>
3163 struct task_shared_state<R (*)(ArgTypes...), R(ArgTypes...)>:
3164 task_base_shared_state<R(ArgTypes...)>
3166 template<typename R>
3167 struct task_shared_state<R (*)(), R()>:
3168 task_base_shared_state<R()>
3171 template<typename R>
3172 struct task_shared_state<R (*)(), R> :
3173 task_base_shared_state<R>
3177 task_shared_state(task_shared_state&);
3178 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3179 typedef R (*CallableType)(ArgTypes ... );
3181 typedef R (*CallableType)();
3185 task_shared_state(CallableType f_):
3189 CallableType callable()
3194 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3195 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3199 this->set_value_at_thread_exit(f(boost::move(args)...));
3207 this->set_value_at_thread_exit(boost::move(r));
3212 this->set_exception_at_thread_exit(current_exception());
3217 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3218 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3222 this->mark_finished_with_result(f(boost::move(args)...));
3230 this->mark_finished_with_result(boost::move(res));
3235 this->mark_exceptional_finish();
3239 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3240 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3241 template<typename R, typename ...ArgTypes>
3242 struct task_shared_state<R& (*)(ArgTypes...), R&(ArgTypes...)>:
3243 task_base_shared_state<R&(ArgTypes...)>
3245 template<typename R>
3246 struct task_shared_state<R& (*)(), R&()>:
3247 task_base_shared_state<R&()>
3250 template<typename R>
3251 struct task_shared_state<R& (*)(), R&> :
3252 task_base_shared_state<R&>
3256 task_shared_state(task_shared_state&);
3258 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3259 typedef R& (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes) ... );
3261 typedef R& (*CallableType)();
3264 task_shared_state(CallableType f_):
3268 CallableType callable()
3270 return boost::move(f);
3273 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3274 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3278 this->set_value_at_thread_exit(f(boost::move(args)...));
3285 this->set_value_at_thread_exit(f());
3290 this->set_exception_at_thread_exit(current_exception());
3295 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3296 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3300 this->mark_finished_with_result(f(boost::move(args)...));
3307 this->mark_finished_with_result(f());
3312 this->mark_exceptional_finish();
3317 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3318 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3319 template<typename F, typename ...ArgTypes>
3320 struct task_shared_state<F, void(ArgTypes...)>:
3321 task_base_shared_state<void(ArgTypes...)>
3323 template<typename F>
3324 struct task_shared_state<F, void()>:
3325 task_base_shared_state<void()>
3328 template<typename F>
3329 struct task_shared_state<F,void>:
3330 task_base_shared_state<void>
3334 task_shared_state(task_shared_state&);
3336 typedef F CallableType;
3338 task_shared_state(F const& f_):
3341 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3346 return boost::move(f);
3348 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3349 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3353 f(boost::move(args)...);
3361 this->set_value_at_thread_exit();
3365 this->set_exception_at_thread_exit(current_exception());
3369 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3370 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3374 f(boost::move(args)...);
3382 this->mark_finished_with_result();
3386 this->mark_exceptional_finish();
3391 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3392 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3393 template<typename ...ArgTypes>
3394 struct task_shared_state<void (*)(ArgTypes...), void(ArgTypes...)>:
3395 task_base_shared_state<void(ArgTypes...)>
3398 struct task_shared_state<void (*)(), void()>:
3399 task_base_shared_state<void()>
3403 struct task_shared_state<void (*)(),void>:
3404 task_base_shared_state<void>
3408 task_shared_state(task_shared_state&);
3409 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3410 typedef void (*CallableType)(ArgTypes...);
3412 typedef void (*CallableType)();
3416 task_shared_state(CallableType f_):
3419 CallableType callable()
3423 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3424 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3428 f(boost::move(args)...);
3436 this->set_value_at_thread_exit();
3440 this->set_exception_at_thread_exit(current_exception());
3444 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3445 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3449 f(boost::move(args)...);
3457 this->mark_finished_with_result();
3461 this->mark_exceptional_finish();
3467 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3468 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3469 template<typename R, typename ...ArgTypes>
3470 class packaged_task<R(ArgTypes...)>
3472 typedef boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task_ptr;
3473 boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task;
3475 template<typename R>
3476 class packaged_task<R()>
3478 typedef boost::shared_ptr<detail::task_base_shared_state<R()> > task_ptr;
3479 boost::shared_ptr<detail::task_base_shared_state<R()> > task;
3482 template<typename R>
3485 typedef boost::shared_ptr<detail::task_base_shared_state<R> > task_ptr;
3486 boost::shared_ptr<detail::task_base_shared_state<R> > task;
3488 bool future_obtained;
3492 typedef R result_type;
3493 BOOST_THREAD_MOVABLE_ONLY(packaged_task)
3496 future_obtained(false)
3499 // construction and destruction
3500 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3502 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3503 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3504 explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args)
3506 typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3507 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3508 task= task_ptr(new task_shared_state_type(f, boost::move(args)...));
3509 future_obtained=false;
3512 explicit packaged_task(R(*f)())
3515 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3516 task= task_ptr(new task_shared_state_type(f));
3517 future_obtained=false;
3521 explicit packaged_task(R(*f)())
3524 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3525 task= task_ptr(new task_shared_state_type(f));
3526 future_obtained=false;
3530 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
3532 explicit packaged_task(BOOST_THREAD_FWD_REF(F) f
3533 , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3536 typedef typename decay<F>::type FR;
3537 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3538 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3539 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3541 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3544 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3546 task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
3547 future_obtained = false;
3553 explicit packaged_task(F const& f
3554 , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3557 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3558 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3559 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3561 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3564 typedef detail::task_shared_state<F,R> task_shared_state_type;
3566 task = task_ptr(new task_shared_state_type(f));
3567 future_obtained=false;
3570 explicit packaged_task(BOOST_THREAD_RV_REF(F) f)
3572 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3573 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3574 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3575 task = task_ptr(new task_shared_state_type(boost::move(f)));
3577 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3578 task = task_ptr(new task_shared_state_type(boost::move(f)));
3581 typedef detail::task_shared_state<F,R> task_shared_state_type;
3582 task = task_ptr(new task_shared_state_type(boost::move(f)));
3584 future_obtained=false;
3589 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3590 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3591 template <class Allocator>
3592 packaged_task(boost::allocator_arg_t, Allocator a, R(*f)())
3595 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3596 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3597 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3599 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3602 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3604 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3606 typedef thread_detail::allocator_destructor<A2> D;
3608 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3609 future_obtained = false;
3611 #endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3613 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3614 template <class F, class Allocator>
3615 packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
3617 typedef typename decay<F>::type FR;
3619 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3620 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3621 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3623 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3626 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3628 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3630 typedef thread_detail::allocator_destructor<A2> D;
3632 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
3633 future_obtained = false;
3635 #else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3636 template <class F, class Allocator>
3637 packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
3639 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3640 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3641 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3643 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3646 typedef detail::task_shared_state<F,R> task_shared_state_type;
3648 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3650 typedef thread_detail::allocator_destructor<A2> D;
3652 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3653 future_obtained = false;
3655 template <class F, class Allocator>
3656 packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f)
3658 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3659 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3660 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3662 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3665 typedef detail::task_shared_state<F,R> task_shared_state_type;
3667 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3669 typedef thread_detail::allocator_destructor<A2> D;
3671 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) );
3672 future_obtained = false;
3675 #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
3676 #endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3680 task->owner_destroyed();
3685 packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
3686 : future_obtained(BOOST_THREAD_RV(other).future_obtained) {
3687 task.swap(BOOST_THREAD_RV(other).task);
3688 BOOST_THREAD_RV(other).future_obtained=false;
3690 packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT {
3692 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3693 packaged_task temp(boost::move(other));
3695 packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
3701 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3702 void set_executor(executor_ptr_type aex)
3705 boost::throw_exception(task_moved());
3706 boost::lock_guard<boost::mutex> lk(task->mutex);
3707 task->set_executor_policy(aex, lk);
3712 boost::throw_exception(future_error(system::make_error_code(future_errc::no_state)));
3714 // As if *this = packaged_task(task->callable());
3717 future_obtained=false;
3720 void swap(packaged_task& other) BOOST_NOEXCEPT {
3721 task.swap(other.task);
3722 std::swap(future_obtained,other.future_obtained);
3724 bool valid() const BOOST_NOEXCEPT {
3725 return task.get()!=0;
3729 BOOST_THREAD_FUTURE<R> get_future() {
3731 boost::throw_exception(task_moved());
3732 } else if(!future_obtained) {
3733 future_obtained=true;
3734 return BOOST_THREAD_FUTURE<R>(task);
3736 boost::throw_exception(future_already_retrieved());
3741 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3742 void operator()(ArgTypes... args) {
3744 boost::throw_exception(task_moved());
3746 task->run(boost::move(args)...);
3748 void make_ready_at_thread_exit(ArgTypes... args) {
3750 boost::throw_exception(task_moved());
3752 if (task->has_value()) {
3753 boost::throw_exception(promise_already_satisfied());
3755 task->apply(boost::move(args)...);
3760 boost::throw_exception(task_moved());
3764 void make_ready_at_thread_exit() {
3766 boost::throw_exception(task_moved());
3768 if (task->has_value()) boost::throw_exception(promise_already_satisfied());
3772 template<typename F>
3773 void set_wait_callback(F f) {
3774 task->set_wait_callback(f,this);
3778 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3779 namespace boost { namespace container {
3780 template <class R, class Alloc>
3781 struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3784 #if ! defined BOOST_NO_CXX11_ALLOCATOR
3786 template <class R, class Alloc>
3787 struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3795 BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
3799 ////////////////////////////////
3800 // make_future_deferred_shared_state
3801 ////////////////////////////////
3802 template <class Rp, class Fp>
3803 BOOST_THREAD_FUTURE<Rp>
3804 make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3805 shared_ptr<future_deferred_shared_state<Rp, Fp> >
3806 h(new future_deferred_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
3807 return BOOST_THREAD_FUTURE<Rp>(h);
3810 ////////////////////////////////
3811 // make_future_async_shared_state
3812 ////////////////////////////////
3813 template <class Rp, class Fp>
3814 BOOST_THREAD_FUTURE<Rp>
3815 make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3816 shared_ptr<future_async_shared_state<Rp, Fp> >
3817 h(new future_async_shared_state<Rp, Fp>());
3818 h->init(boost::forward<Fp>(f));
3819 return BOOST_THREAD_FUTURE<Rp>(h);
3823 ////////////////////////////////
3824 // template <class F, class... ArgTypes>
3825 // future<R> async(launch policy, F&&, ArgTypes&&...);
3826 ////////////////////////////////
3828 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3830 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3831 template <class R, class... ArgTypes>
3832 BOOST_THREAD_FUTURE<R>
3833 async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3834 typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3835 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3836 typedef typename BF::result_type Rp;
3838 if (underlying_cast<int>(policy) & int(launch::async)) {
3839 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3842 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3845 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3846 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3849 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3854 //BOOST_THREAD_FUTURE<R> ret;
3855 //return ::boost::move(ret);
3859 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3862 BOOST_THREAD_FUTURE<R>
3863 async(launch policy, R(*f)()) {
3864 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3865 typedef packaged_task<R()> packaged_task_type;
3867 typedef packaged_task<R> packaged_task_type;
3870 if (underlying_cast<int>(policy) & int(launch::async)) {
3871 packaged_task_type pt( f );
3872 BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
3874 boost::thread( boost::move(pt) ).detach();
3875 return ::boost::move(ret);
3876 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3878 //BOOST_THREAD_FUTURE<R> ret;
3879 //return ::boost::move(ret);
3882 //BOOST_THREAD_FUTURE<R> ret;
3883 //return ::boost::move(ret);
3887 #endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3889 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3891 template <class F, class ...ArgTypes>
3892 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3893 typename decay<ArgTypes>::type...
3895 async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3896 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3897 typedef typename BF::result_type Rp;
3899 if (underlying_cast<int>(policy) & int(launch::async)) {
3900 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3902 thread_detail::decay_copy(boost::forward<F>(f))
3903 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3906 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3907 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3909 thread_detail::decay_copy(boost::forward<F>(f))
3910 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3915 //BOOST_THREAD_FUTURE<R> ret;
3916 //return ::boost::move(ret);
3920 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3923 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3924 async(launch policy, BOOST_THREAD_FWD_REF(F) f) {
3925 typedef typename boost::result_of<typename decay<F>::type()>::type R;
3926 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3927 typedef packaged_task<R()> packaged_task_type;
3928 #else // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3929 typedef packaged_task<R> packaged_task_type;
3930 #endif // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3932 if (underlying_cast<int>(policy) & int(launch::async)) {
3933 packaged_task_type pt( boost::forward<F>(f) );
3934 BOOST_THREAD_FUTURE<R> ret = pt.get_future();
3936 boost::thread( boost::move(pt) ).detach();
3937 return ::boost::move(ret);
3938 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3940 //BOOST_THREAD_FUTURE<R> ret;
3941 //return ::boost::move(ret);
3942 // return boost::detail::make_future_deferred_shared_state<Rp>(
3944 // thread_detail::decay_copy(boost::forward<F>(f))
3949 //BOOST_THREAD_FUTURE<R> ret;
3950 //return ::boost::move(ret);
3953 #endif // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3955 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3958 /////////////////////////
3959 /// shared_state_nullary_task
3960 /////////////////////////
3961 template<typename Rp, typename Fp>
3962 struct shared_state_nullary_task
3965 typedef shared_ptr<shared_state_base > storage_type;
3970 shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
3971 : that(st), f_(boost::move(f))
3974 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
3975 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
3976 shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
3977 : that(x.that), f_(x.f_)
3979 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3988 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3989 : that(x.that), f_(boost::move(x.f_))
3993 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3997 f_=boost::move(x.f_);
4004 shared_ptr<shared_state<Rp> > that_ = static_pointer_cast<shared_state<Rp> >(that);
4006 that_->mark_finished_with_result(f_());
4008 that_->mark_exceptional_finish();
4011 ~shared_state_nullary_task()
4016 template<typename Fp>
4017 struct shared_state_nullary_task<void, Fp>
4019 typedef shared_ptr<shared_state_base > storage_type;
4023 shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
4024 : that(st), f_(boost::move(f))
4027 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4028 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
4029 shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
4030 : that(x.that), f_(x.f_)
4032 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
4041 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
4042 : that(x.that), f_(boost::move(x.f_))
4046 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
4049 f_=boost::move(x.f_);
4056 shared_ptr<shared_state<void> > that_ = static_pointer_cast<shared_state<void> >(that);
4059 that_->mark_finished_with_result();
4061 that_->mark_exceptional_finish();
4067 BOOST_THREAD_DCL_MOVABLE_BEG2(R,F) detail::shared_state_nullary_task<R,F> BOOST_THREAD_DCL_MOVABLE_END
4070 /////////////////////////
4071 /// future_executor_shared_state_base
4072 /////////////////////////
4073 template<typename Rp>
4074 struct future_executor_shared_state: shared_state<Rp>
4076 typedef shared_state<Rp> base_type;
4079 future_executor_shared_state() {
4082 template <class Fp, class Executor>
4083 void init(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f)
4085 typedef typename decay<Fp>::type Cont;
4086 this->set_executor_policy(executor_ptr_type(new executor_ref<Executor>(ex)));
4087 shared_state_nullary_task<Rp,Cont> t(this->shared_from_this(), boost::forward<Fp>(f));
4088 ex.submit(boost::move(t));
4091 ~future_executor_shared_state() {}
4094 ////////////////////////////////
4095 // make_future_executor_shared_state
4096 ////////////////////////////////
4097 template <class Rp, class Fp, class Executor>
4098 BOOST_THREAD_FUTURE<Rp>
4099 make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
4100 shared_ptr<future_executor_shared_state<Rp> >
4101 h(new future_executor_shared_state<Rp>());
4102 h->init(ex, boost::forward<Fp>(f));
4103 return BOOST_THREAD_FUTURE<Rp>(h);
4108 ////////////////////////////////
4109 // template <class Executor, class F, class... ArgTypes>
4110 // future<R> async(Executor& ex, F&&, ArgTypes&&...);
4111 ////////////////////////////////
4113 //#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4114 #if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
4116 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
4118 template <class Executor, class R, class... ArgTypes>
4119 BOOST_THREAD_FUTURE<R>
4120 async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4121 typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
4122 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
4123 typedef typename BF::result_type Rp;
4125 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4128 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
4132 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
4134 template <class Executor, class F, class ...ArgTypes>
4135 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4136 typename decay<ArgTypes>::type...
4138 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4139 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
4140 typedef typename BF::result_type Rp;
4142 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4144 thread_detail::decay_copy(boost::forward<F>(f))
4145 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
4150 #else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4151 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
4153 template <class Executor, class R>
4154 BOOST_THREAD_FUTURE<R>
4155 async(Executor& ex, R(*f)()) {
4157 typedef detail::invoker<F> BF;
4158 typedef typename BF::result_type Rp;
4160 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4167 template <class Executor, class R, class A1>
4168 BOOST_THREAD_FUTURE<R>
4169 async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1) {
4170 typedef R(*F)(BOOST_THREAD_FWD_REF(A1));
4171 typedef detail::invoker<F, typename decay<A1>::type> BF;
4172 typedef typename BF::result_type Rp;
4174 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4177 , thread_detail::decay_copy(boost::forward<A1>(a1))
4181 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
4183 template <class Executor, class F>
4184 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
4185 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f) {
4186 typedef detail::invoker<typename decay<F>::type> BF;
4187 typedef typename BF::result_type Rp;
4189 return boost::detail::make_future_executor_shared_state<Rp>(ex,
4191 thread_detail::decay_copy(boost::forward<F>(f))
4196 template <class Executor, class F, class A1>
4197 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4198 typename decay<A1>::type
4200 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) {
4201 typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type> BF;
4202 typedef typename BF::result_type Rp;
4204 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4206 thread_detail::decay_copy(boost::forward<F>(f))
4207 , thread_detail::decay_copy(boost::forward<A1>(a1))
4212 template <class Executor, class F, class A1, class A2>
4213 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4214 typename decay<A1>::type, typename decay<A2>::type
4216 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) {
4217 typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type, typename decay<A2>::type> BF;
4218 typedef typename BF::result_type Rp;
4220 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4222 thread_detail::decay_copy(boost::forward<F>(f))
4223 , thread_detail::decay_copy(boost::forward<A1>(a1))
4224 , thread_detail::decay_copy(boost::forward<A2>(a2))
4229 #endif //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4232 ////////////////////////////////
4233 // template <class F, class... ArgTypes>
4234 // future<R> async(F&&, ArgTypes&&...);
4235 ////////////////////////////////
4237 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
4238 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
4239 template <class R, class... ArgTypes>
4240 BOOST_THREAD_FUTURE<R>
4241 async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4242 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
4246 BOOST_THREAD_FUTURE<R>
4248 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
4253 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
4254 template <class F, class ...ArgTypes>
4255 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4256 typename decay<ArgTypes>::type...
4258 async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4259 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
4263 BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
4264 async(BOOST_THREAD_FWD_REF(F) f) {
4265 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
4269 ////////////////////////////////
4270 // make_future deprecated
4271 ////////////////////////////////
4272 template <typename T>
4273 BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value) {
4274 typedef typename decay<T>::type future_value_type;
4275 promise<future_value_type> p;
4276 p.set_value(boost::forward<future_value_type>(value));
4277 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4280 #if defined BOOST_THREAD_USES_MOVE
4281 inline BOOST_THREAD_FUTURE<void> make_future() {
4284 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4288 ////////////////////////////////
4289 // make_ready_future
4290 ////////////////////////////////
4293 struct deduced_type_impl
4299 struct deduced_type_impl<reference_wrapper<T> const>
4304 struct deduced_type_impl<reference_wrapper<T> >
4308 #if __cplusplus > 201103L
4310 struct deduced_type_impl<std::reference_wrapper<T> >
4318 typedef typename detail::deduced_type_impl<typename decay<T>::type>::type type;
4324 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4325 template <int = 0, int..., class T>
4329 BOOST_THREAD_FUTURE<typename detail::deduced_type<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
4330 typedef typename detail::deduced_type<T>::type future_value_type;
4331 promise<future_value_type> p;
4332 p.set_value(boost::forward<T>(value));
4333 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4336 // explicit overloads
4338 BOOST_THREAD_FUTURE<T> make_ready_future(typename remove_reference<T>::type & x)
4342 return p.get_future();
4346 BOOST_THREAD_FUTURE<T> make_ready_future(BOOST_THREAD_FWD_REF(typename remove_reference<T>::type) x)
4349 p.set_value(forward<typename remove_reference<T>::type>(x));
4350 return p.get_future();
4353 // variadic overload
4354 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4355 template <class T, class ...Args>
4356 BOOST_THREAD_FUTURE<T> make_ready_future(Args&&... args)
4359 p.emplace(forward<Args>(args)...);
4360 return p.get_future();
4365 template <typename T, typename T1>
4366 BOOST_THREAD_FUTURE<T> make_ready_no_decay_future(T1 value) {
4367 typedef T future_value_type;
4368 promise<future_value_type> p;
4370 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4373 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
4374 inline BOOST_THREAD_FUTURE<void> make_ready_future() {
4377 return p.get_future();
4382 template <typename T>
4383 BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
4385 p.set_exception(ex);
4386 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4389 template <typename T, typename E>
4390 BOOST_THREAD_FUTURE<T> make_exceptional_future(E ex) {
4392 p.set_exception(boost::copy_exception(ex));
4393 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4396 template <typename T>
4397 BOOST_THREAD_FUTURE<T> make_exceptional_future() {
4399 p.set_exception(boost::current_exception());
4400 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4402 template <typename T>
4403 BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex) {
4404 return make_exceptional_future<T>(ex);
4408 template<typename CLOSURE>
4409 make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE<decltype(closure())> {
4410 typedef decltype(closure()) T;
4413 p.set_value(closure());
4415 p.set_exception(std::current_exception());
4417 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4421 ////////////////////////////////
4422 // make_shared_future deprecated
4423 ////////////////////////////////
4424 template <typename T>
4425 shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value) {
4426 typedef typename decay<T>::type future_type;
4427 promise<future_type> p;
4428 p.set_value(boost::forward<T>(value));
4429 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4432 inline shared_future<void> make_shared_future() {
4434 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4437 ////////////////////////////////
4438 // detail::future_async_continuation_shared_state
4439 ////////////////////////////////
4440 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
4444 //////////////////////
4445 // detail::continuation_shared_state
4446 //////////////////////
4447 template<typename F, typename Rp, typename Fp, class ShSt=shared_state<Rp> >
4448 struct continuation_shared_state: ShSt
4454 continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4455 : parent(boost::move(f)),
4456 continuation(boost::move(c))
4460 void init(boost::unique_lock<boost::mutex> &lock)
4462 parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
4467 this->mark_finished_with_result(this->continuation(boost::move(this->parent)));
4469 this->mark_exceptional_finish();
4471 // make sure parent is really cleared to prevent memory "leaks"
4475 void call(boost::unique_lock<boost::mutex>& lck) {
4477 relocker relock(lck);
4479 // neither continuation nor parent are protected by the lock - call() must only
4480 // be called once, and no one else must modify it.
4481 Rp res = this->continuation(boost::move(this->parent));
4483 // make sure parent is really cleared to prevent memory "leaks"
4488 this->mark_finished_with_result_internal(boost::move(res), lck);
4490 this->mark_exceptional_finish_internal(current_exception(), lck);
4492 // make sure parent is really cleared to prevent memory "leaks"
4493 relocker relock(lck);
4498 static void run(shared_ptr<boost::detail::shared_state_base> that_)
4500 continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
4504 ~continuation_shared_state() {}
4507 template<typename F, typename Fp, class ShSt>
4508 struct continuation_shared_state<F, void, Fp, ShSt>: ShSt
4514 continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4515 : parent(boost::move(f)),
4516 continuation(boost::move(c))
4520 void init(boost::unique_lock<boost::mutex> &lock)
4522 parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
4528 this->continuation(boost::move(this->parent));
4529 this->mark_finished_with_result();
4531 this->mark_exceptional_finish();
4533 // make sure parent is really cleared to prevent memory "leaks"
4537 void call(boost::unique_lock<boost::mutex>& lck) {
4540 relocker relock(lck);
4541 // neither continuation nor parent are protected by the lock - call() must only
4542 // be called once, and no one else must modify it.
4543 this->continuation(boost::move(this->parent));
4545 // make sure parent is really cleared to prevent memory "leaks"
4548 this->mark_finished_with_result_internal(lck);
4550 this->mark_exceptional_finish_internal(current_exception(), lck);
4552 // make sure parent is really cleared to prevent memory "leaks"
4553 relocker relock(lck);
4558 static void run(shared_ptr<boost::detail::shared_state_base> that_)
4560 continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
4564 ~continuation_shared_state() {}
4566 /////////////////////////
4567 /// future_async_continuation_shared_state
4568 /////////////////////////
4570 template<typename F, typename Rp, typename Fp>
4571 struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
4573 typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
4575 future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4576 : base_type(boost::move(f), boost::forward<Fp>(c))
4579 void launch_continuation() {
4580 #if defined BOOST_THREAD_FUTURE_BLOCKING
4581 boost::lock_guard<boost::mutex> lk(this->mutex);
4582 this->thr_ = boost::thread(&future_async_continuation_shared_state::run, static_shared_from_this(this));
4584 boost::thread(&base_type::run, static_shared_from_this(this)).detach();
4589 /////////////////////////
4590 /// future_sync_continuation_shared_state
4591 /////////////////////////
4593 template<typename F, typename Rp, typename Fp>
4594 struct future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
4596 typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
4598 future_sync_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4599 : base_type(boost::move(f), boost::forward<Fp>(c))
4602 void launch_continuation() {
4608 /////////////////////////
4609 /// future_executor_continuation_shared_state
4610 /////////////////////////
4611 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4613 template <typename FutureExecutorContinuationSharedState>
4615 shared_ptr<FutureExecutorContinuationSharedState> that_;
4617 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4618 BOOST_THREAD_COPYABLE_AND_MOVABLE(run_it)
4619 run_it(run_it const& x) //BOOST_NOEXCEPT
4622 run_it& operator=(BOOST_THREAD_COPY_ASSIGN_REF(run_it) x) //BOOST_NOEXCEPT
4630 run_it(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT
4635 run_it& operator=(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT {
4643 run_it(shared_ptr<FutureExecutorContinuationSharedState> that) : that_ (that) {}
4652 BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::run_it<F> BOOST_THREAD_DCL_MOVABLE_END
4656 template<typename F, typename Rp, typename Fp>
4657 struct future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4659 typedef continuation_shared_state<F,Rp,Fp> base_type;
4662 future_executor_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4663 : base_type(boost::move(f), boost::forward<Fp>(c))
4668 void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
4670 this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
4671 this->base_type::init(lk);
4674 void launch_continuation() {
4675 run_it<base_type> fct(static_shared_from_this(this));
4676 this->get_executor()->submit(boost::move(fct));
4679 ~future_executor_continuation_shared_state() {}
4683 /////////////////////////
4684 /// shared_future_async_continuation_shared_state
4685 /////////////////////////
4687 template<typename F, typename Rp, typename Fp>
4688 struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
4690 typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
4693 shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4694 : base_type(boost::move(f), boost::forward<Fp>(c))
4698 void launch_continuation() {
4699 #if defined BOOST_THREAD_FUTURE_BLOCKING
4700 boost::lock_guard<boost::mutex> lk(this->mutex);
4701 this->thr_ = boost::thread(&base_type::run, static_shared_from_this(this));
4703 boost::thread(&base_type::run, static_shared_from_this(this)).detach();
4708 /////////////////////////
4709 /// shared_future_async_continuation_shared_state
4710 /////////////////////////
4712 template<typename F, typename Rp, typename Fp>
4713 struct shared_future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
4715 typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
4718 shared_future_sync_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4719 : base_type(boost::move(f), boost::forward<Fp>(c))
4723 void launch_continuation() {
4729 /////////////////////////
4730 /// shared_future_executor_continuation_shared_state
4731 /////////////////////////
4732 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4734 template<typename F, typename Rp, typename Fp>
4735 struct shared_future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4737 typedef continuation_shared_state<F,Rp,Fp> base_type;
4741 shared_future_executor_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4742 : base_type(boost::move(f), boost::forward<Fp>(c))
4747 void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
4749 this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
4750 this->base_type::init(lk);
4753 void launch_continuation() {
4754 run_it<base_type> fct(static_shared_from_this(this));
4755 this->get_executor()->submit(boost::move(fct));
4758 ~shared_future_executor_continuation_shared_state() {}
4762 //////////////////////////
4763 /// future_deferred_continuation_shared_state
4764 //////////////////////////
4765 template<typename F, typename Rp, typename Fp>
4766 struct future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4768 typedef continuation_shared_state<F,Rp,Fp> base_type;
4770 future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4771 : base_type(boost::move(f), boost::forward<Fp>(c))
4773 this->set_deferred();
4776 virtual void execute(boost::unique_lock<boost::mutex>& lk) {
4777 this->parent.wait();
4781 virtual void launch_continuation() { }
4784 //////////////////////////
4785 /// shared_future_deferred_continuation_shared_state
4786 //////////////////////////
4787 template<typename F, typename Rp, typename Fp>
4788 struct shared_future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4790 typedef continuation_shared_state<F,Rp,Fp> base_type;
4793 shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4794 : base_type(boost::move(f), boost::forward<Fp>(c))
4796 this->set_deferred();
4799 virtual void execute(boost::unique_lock<boost::mutex>& lk) {
4800 this->parent.wait();
4804 virtual void launch_continuation() { }
4807 ////////////////////////////////
4808 // make_future_deferred_continuation_shared_state
4809 ////////////////////////////////
4810 template<typename F, typename Rp, typename Fp>
4811 BOOST_THREAD_FUTURE<Rp>
4812 make_future_deferred_continuation_shared_state(
4813 boost::unique_lock<boost::mutex> &lock,
4814 BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c) {
4815 typedef typename decay<Fp>::type Cont;
4816 shared_ptr<future_deferred_continuation_shared_state<F, Rp, Cont> >
4817 h(new future_deferred_continuation_shared_state<F, Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4819 return BOOST_THREAD_FUTURE<Rp>(h);
4822 ////////////////////////////////
4823 // make_future_async_continuation_shared_state
4824 ////////////////////////////////
4825 template<typename F, typename Rp, typename Fp>
4826 BOOST_THREAD_FUTURE<Rp>
4827 make_future_async_continuation_shared_state(
4828 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4829 BOOST_THREAD_FWD_REF(Fp) c) {
4830 typedef typename decay<Fp>::type Cont;
4831 shared_ptr<future_async_continuation_shared_state<F,Rp, Cont> >
4832 h(new future_async_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4835 return BOOST_THREAD_FUTURE<Rp>(h);
4837 ////////////////////////////////
4838 // make_future_sync_continuation_shared_state
4839 ////////////////////////////////
4840 template<typename F, typename Rp, typename Fp>
4841 BOOST_THREAD_FUTURE<Rp>
4842 make_future_sync_continuation_shared_state(
4843 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4844 BOOST_THREAD_FWD_REF(Fp) c) {
4845 typedef typename decay<Fp>::type Cont;
4846 shared_ptr<future_sync_continuation_shared_state<F,Rp, Cont> >
4847 h(new future_sync_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4850 return BOOST_THREAD_FUTURE<Rp>(h);
4853 ////////////////////////////////
4854 // make_future_executor_continuation_shared_state
4855 ////////////////////////////////
4856 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4858 template<typename Ex, typename F, typename Rp, typename Fp>
4859 BOOST_THREAD_FUTURE<Rp>
4860 make_future_executor_continuation_shared_state(Ex& ex,
4861 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4862 BOOST_THREAD_FWD_REF(Fp) c) {
4863 typedef typename decay<Fp>::type Cont;
4864 shared_ptr<future_executor_continuation_shared_state<F,Rp, Cont> >
4865 h(new future_executor_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4868 return BOOST_THREAD_FUTURE<Rp>(h);
4872 ////////////////////////////////
4873 // make_shared_future_deferred_continuation_shared_state
4874 ////////////////////////////////
4875 template<typename F, typename Rp, typename Fp>
4876 BOOST_THREAD_FUTURE<Rp>
4877 make_shared_future_deferred_continuation_shared_state(
4878 boost::unique_lock<boost::mutex> &lock,
4879 F f, BOOST_THREAD_FWD_REF(Fp) c) {
4880 typedef typename decay<Fp>::type Cont;
4881 shared_ptr<shared_future_deferred_continuation_shared_state<F, Rp, Cont> >
4882 h(new shared_future_deferred_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
4885 return BOOST_THREAD_FUTURE<Rp>(h);
4887 ////////////////////////////////
4888 // make_shared_future_async_continuation_shared_state
4889 ////////////////////////////////
4890 template<typename F, typename Rp, typename Fp>
4891 BOOST_THREAD_FUTURE<Rp>
4892 make_shared_future_async_continuation_shared_state(
4893 boost::unique_lock<boost::mutex> &lock, F f,
4894 BOOST_THREAD_FWD_REF(Fp) c) {
4895 typedef typename decay<Fp>::type Cont;
4896 shared_ptr<shared_future_async_continuation_shared_state<F,Rp, Cont> >
4897 h(new shared_future_async_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
4900 return BOOST_THREAD_FUTURE<Rp>(h);
4902 ////////////////////////////////
4903 // make_shared_future_sync_continuation_shared_state
4904 ////////////////////////////////
4905 template<typename F, typename Rp, typename Fp>
4906 BOOST_THREAD_FUTURE<Rp>
4907 make_shared_future_sync_continuation_shared_state(
4908 boost::unique_lock<boost::mutex> &lock, F f,
4909 BOOST_THREAD_FWD_REF(Fp) c) {
4910 typedef typename decay<Fp>::type Cont;
4911 shared_ptr<shared_future_sync_continuation_shared_state<F,Rp, Cont> >
4912 h(new shared_future_sync_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
4915 return BOOST_THREAD_FUTURE<Rp>(h);
4917 ////////////////////////////////
4918 // make_shared_future_executor_continuation_shared_state
4919 ////////////////////////////////
4920 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4921 template<typename Ex, typename F, typename Rp, typename Fp>
4922 BOOST_THREAD_FUTURE<Rp>
4923 make_shared_future_executor_continuation_shared_state(Ex& ex,
4924 boost::unique_lock<boost::mutex> &lock, F f,
4925 BOOST_THREAD_FWD_REF(Fp) c) {
4926 typedef typename decay<Fp>::type Cont;
4927 shared_ptr<shared_future_executor_continuation_shared_state<F, Rp, Cont> >
4928 h(new shared_future_executor_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
4931 return BOOST_THREAD_FUTURE<Rp>(h);
4936 ////////////////////////////////
4937 // template<typename F>
4938 // auto future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4939 ////////////////////////////////
4940 template <typename R>
4941 template <typename F>
4942 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4943 BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
4944 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4945 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
4947 // keep state alive as we move ourself but hold the lock
4948 shared_ptr<detail::shared_state_base> sentinel(this->future_);
4949 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
4951 if (underlying_cast<int>(policy) & int(launch::async)) {
4952 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4953 lock, boost::move(*this), boost::forward<F>(func)
4955 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
4956 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4957 lock, boost::move(*this), boost::forward<F>(func)
4959 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4960 } else if (underlying_cast<int>(policy) & int(launch::executor)) {
4961 assert(this->future_->get_executor());
4962 typedef executor Ex;
4963 Ex& ex = *(this->future_->get_executor());
4964 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
4965 lock, boost::move(*this), boost::forward<F>(func)
4968 } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
4970 launch policy_ = this->launch_policy(lock);
4971 if (underlying_cast<int>(policy_) & int(launch::async)) {
4972 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4973 lock, boost::move(*this), boost::forward<F>(func)
4975 } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
4976 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4977 lock, boost::move(*this), boost::forward<F>(func)
4979 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4980 } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
4981 assert(this->future_->get_executor());
4982 typedef executor Ex;
4983 Ex& ex = *(this->future_->get_executor());
4984 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
4985 lock, boost::move(*this), boost::forward<F>(func)
4989 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4990 lock, boost::move(*this), boost::forward<F>(func)
4994 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4995 lock, boost::move(*this), boost::forward<F>(func)
4999 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5000 ////////////////////////////////
5001 // template<typename Ex, typename F>
5002 // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5003 ////////////////////////////////
5004 template <typename R>
5005 template <typename Ex, typename F>
5006 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
5007 BOOST_THREAD_FUTURE<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
5008 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5009 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5011 // keep state alive as we move ourself but hold the lock
5012 shared_ptr<detail::shared_state_base> sentinel(this->future_);
5013 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5015 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5016 lock, boost::move(*this), boost::forward<F>(func)
5020 ////////////////////////////////
5021 // template<typename F>
5022 // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5023 ////////////////////////////////
5024 template <typename R>
5025 template <typename F>
5026 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
5027 BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func) {
5029 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5030 return this->then(this->launch_policy(), boost::forward<F>(func));
5032 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5033 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5035 // keep state alive as we move ourself but hold the lock
5036 shared_ptr<detail::shared_state_base> sentinel(this->future_);
5037 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5039 launch policy = this->launch_policy(lock);
5040 if (underlying_cast<int>(policy) & int(launch::deferred)) {
5041 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5042 lock, boost::move(*this), boost::forward<F>(func)
5045 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5046 lock, boost::move(*this), boost::forward<F>(func)
5053 ////////////////////////////////
5054 // template<typename F>
5055 // auto future<future<R2> >::then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5056 ////////////////////////////////
5057 template <typename R2>
5058 template <typename F>
5059 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
5060 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
5061 typedef BOOST_THREAD_FUTURE<R2> R;
5062 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5063 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5065 // keep state alive as we move ourself but hold the lock
5066 shared_ptr<detail::shared_state_base> sentinel(this->future_);
5067 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5069 if (underlying_cast<int>(policy) & int(launch::async)) {
5070 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5071 lock, boost::move(*this), boost::forward<F>(func)
5073 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
5074 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5075 lock, boost::move(*this), boost::forward<F>(func)
5077 } else if (underlying_cast<int>(policy) & int(launch::sync)) {
5078 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5079 lock, boost::move(*this), boost::forward<F>(func)
5081 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5082 } else if (underlying_cast<int>(policy) & int(launch::executor)) {
5083 assert(this->future_->get_executor());
5084 typedef executor Ex;
5085 Ex& ex = *(this->future_->get_executor());
5086 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5087 lock, boost::move(*this), boost::forward<F>(func)
5090 } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
5091 launch policy_ = this->launch_policy(lock);
5093 if (underlying_cast<int>(policy_) & int(launch::async)) {
5094 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5095 lock, boost::move(*this), boost::forward<F>(func)
5097 } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
5098 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5099 lock, boost::move(*this), boost::forward<F>(func)
5101 } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
5102 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5103 lock, boost::move(*this), boost::forward<F>(func)
5105 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5106 } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
5107 assert(this->future_->get_executor());
5108 typedef executor Ex;
5109 Ex& ex = *(this->future_->get_executor());
5110 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5111 lock, boost::move(*this), boost::forward<F>(func)
5115 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5116 lock, boost::move(*this), boost::forward<F>(func)
5120 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5121 lock, boost::move(*this), boost::forward<F>(func)
5126 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5127 ////////////////////////////////
5128 // template<typename Ex, typename F>
5129 // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5130 ////////////////////////////////
5131 template <typename R2>
5132 template <typename Ex, typename F>
5133 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
5134 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
5135 typedef BOOST_THREAD_FUTURE<R2> R;
5136 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5137 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5139 // keep state alive as we move ourself but hold the lock
5140 shared_ptr<detail::shared_state_base> sentinel(this->future_);
5141 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5143 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
5144 lock, boost::move(*this), boost::forward<F>(func)
5149 ////////////////////////////////
5150 // template<typename F>
5151 // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5152 ////////////////////////////////
5153 template <typename R2>
5154 template <typename F>
5155 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
5156 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(BOOST_THREAD_FWD_REF(F) func) {
5158 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5159 return this->then(this->launch_policy(), boost::forward<F>(func));
5161 typedef BOOST_THREAD_FUTURE<R2> R;
5162 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
5163 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5165 // keep state alive as we move ourself but hold the lock
5166 shared_ptr<detail::shared_state_base> sentinel(this->future_);
5167 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5169 launch policy = this->launch_policy(lock);
5171 if (underlying_cast<int>(policy) & int(launch::deferred)) {
5172 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5173 lock, boost::move(*this), boost::forward<F>(func)
5176 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
5177 lock, boost::move(*this), boost::forward<F>(func)
5183 ////////////////////////////////
5184 // template<typename F>
5185 // auto shared_future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5186 ////////////////////////////////
5187 template <typename R>
5188 template <typename F>
5189 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5190 shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) const
5192 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5193 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5195 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5196 if (underlying_cast<int>(policy) & int(launch::async)) {
5197 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5198 lock, *this, boost::forward<F>(func)
5200 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
5201 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5202 lock, *this, boost::forward<F>(func)
5204 } else if (underlying_cast<int>(policy) & int(launch::sync)) {
5205 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5206 lock, *this, boost::forward<F>(func)
5208 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5209 } else if (underlying_cast<int>(policy) & int(launch::executor)) {
5210 typedef executor Ex;
5211 Ex& ex = *(this->future_->get_executor());
5212 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5213 lock, *this, boost::forward<F>(func)
5216 } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
5218 launch policy_ = this->launch_policy(lock);
5219 if (underlying_cast<int>(policy_) & int(launch::async)) {
5220 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5221 lock, *this, boost::forward<F>(func)
5223 } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
5224 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5225 lock, *this, boost::forward<F>(func)
5227 } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
5228 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5229 lock, *this, boost::forward<F>(func)
5231 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5232 } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
5233 typedef executor Ex;
5234 Ex& ex = *(this->future_->get_executor());
5235 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5236 lock, *this, boost::forward<F>(func)
5240 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5241 lock, *this, boost::forward<F>(func)
5246 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5247 lock, *this, boost::forward<F>(func)
5251 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5252 ////////////////////////////////
5253 // template<typename Ex, typename F>
5254 // auto shared_future<R>::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5255 ////////////////////////////////
5256 template <typename R>
5257 template <typename Ex, typename F>
5258 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5259 shared_future<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const
5261 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5262 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5264 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5265 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5266 lock, *this, boost::forward<F>(func)
5271 ////////////////////////////////
5272 // template<typename F>
5273 // auto shared_future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5274 ////////////////////////////////
5275 template <typename R>
5276 template <typename F>
5277 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5278 shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func) const {
5279 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5280 return this->then(this->launch_policy(), boost::forward<F>(func));
5282 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5283 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5285 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5286 launch policy = this->launch_policy(lock);
5287 if (underlying_cast<int>(policy) & int(launch::deferred)) {
5288 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5289 lock, *this, boost::forward<F>(func)
5292 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5293 lock, *this, boost::forward<F>(func)
5301 template <typename T>
5302 struct mfallbacker_to
5305 typedef T result_type;
5306 mfallbacker_to(BOOST_THREAD_RV_REF(T) v)
5307 : value_(boost::move(v))
5310 T operator()(BOOST_THREAD_FUTURE<T> fut) {
5311 return fut.get_or(boost::move(value_));
5314 template <typename T>
5315 struct cfallbacker_to
5318 typedef T result_type;
5319 cfallbacker_to(T const& v)
5323 T operator()(BOOST_THREAD_FUTURE<T> fut) const {
5324 return fut.get_or(value_);
5329 ////////////////////////////////
5330 // future<R> future<R>::fallback_to(R&& v);
5331 ////////////////////////////////
5333 template <typename R>
5334 template <typename R2>
5335 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
5336 BOOST_THREAD_FUTURE<R>::fallback_to(BOOST_THREAD_RV_REF(R2) v) {
5337 return then(detail::mfallbacker_to<R>(boost::move(v)));
5340 template <typename R>
5341 template <typename R2>
5342 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
5343 BOOST_THREAD_FUTURE<R>::fallback_to(R2 const& v) {
5344 return then(detail::cfallbacker_to<R>(v));
5349 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
5352 /////////////////////////
5353 /// future_unwrap_shared_state
5354 /////////////////////////
5356 template<typename F, typename Rp>
5357 struct future_unwrap_shared_state: shared_state<Rp>
5360 typename F::value_type unwrapped;
5362 explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
5363 : wrapped(boost::move(f)) {
5366 void launch_continuation()
5368 boost::unique_lock<boost::mutex> lk(this->mutex);
5369 // assert(wrapped.is_ready());
5370 if (! unwrapped.valid() )
5372 if (wrapped.has_exception()) {
5373 this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
5375 unwrapped = wrapped.get();
5376 if (unwrapped.valid())
5379 boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
5380 unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
5382 this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
5386 // assert(unwrapped.is_ready());
5387 if (unwrapped.has_exception()) {
5388 this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
5390 this->mark_finished_with_result_internal(unwrapped.get(), lk);
5396 template<typename F>
5397 struct future_unwrap_shared_state<F,void>: shared_state<void>
5400 typename F::value_type unwrapped;
5402 explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
5403 : wrapped(boost::move(f)) {
5406 void launch_continuation()
5408 boost::unique_lock<boost::mutex> lk(this->mutex);
5409 // assert(wrapped.is_ready());
5410 if (! unwrapped.valid() )
5412 if (wrapped.has_exception()) {
5413 this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
5415 unwrapped = wrapped.get();
5416 if (unwrapped.valid())
5419 boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
5420 unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
5422 this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
5426 // assert(unwrapped.is_ready());
5427 if (unwrapped.has_exception()) {
5428 this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
5430 this->mark_finished_with_result_internal(lk);
5436 template <class F, class Rp>
5437 BOOST_THREAD_FUTURE<Rp>
5438 make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f) {
5439 shared_ptr<future_unwrap_shared_state<F, Rp> >
5440 h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
5441 h->wrapped.future_->set_continuation_ptr(h, lock);
5443 return BOOST_THREAD_FUTURE<Rp>(h);
5447 template <typename R>
5448 inline BOOST_THREAD_FUTURE<R>::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other)
5449 : base_type(other.unwrap()) {}
5451 template <typename R2>
5452 BOOST_THREAD_FUTURE<R2>
5453 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
5455 BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
5457 // keep state alive as we move ourself but hold the lock
5458 shared_ptr<detail::shared_state_base> sentinel(this->future_);
5459 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5461 return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
5465 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
5468 struct input_iterator_tag {};
5469 struct vector_tag {};
5470 struct values_tag {};
5471 template <typename T>
5472 struct alias_t { typedef T type; };
5474 BOOST_CONSTEXPR_OR_CONST input_iterator_tag input_iterator_tag_value = {};
5475 BOOST_CONSTEXPR_OR_CONST vector_tag vector_tag_value = {};
5476 BOOST_CONSTEXPR_OR_CONST values_tag values_tag_value = {};
5477 ////////////////////////////////
5478 // detail::future_async_when_all_shared_state
5479 ////////////////////////////////
5480 template<typename F>
5481 struct future_when_all_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
5483 typedef csbl::vector<F> vector_type;
5484 typedef typename F::value_type value_type;
5487 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
5488 future_when_all_vector_shared_state* that = static_cast<future_when_all_vector_shared_state*>(that_.get());
5490 boost::wait_for_all(that->vec_.begin(), that->vec_.end());
5491 that->mark_finished_with_result(boost::move(that->vec_));
5493 that->mark_exceptional_finish();
5496 bool run_deferred() {
5499 for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
5500 if (! it->run_if_is_deferred())
5508 if (! run_deferred())
5510 future_when_all_vector_shared_state::run(this->shared_from_this());
5513 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5514 this->thr_ = boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this());
5516 boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this()).detach();
5521 template< typename InputIterator>
5522 future_when_all_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
5523 : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
5527 future_when_all_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
5528 : vec_(boost::move(v))
5532 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5533 template< typename T0, typename ...T>
5534 future_when_all_vector_shared_state(values_tag, BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5535 vec_.push_back(boost::forward<T0>(f));
5536 typename alias_t<char[]>::type{
5537 ( //first part of magic unpacker
5538 vec_.push_back(boost::forward<T>(futures)),'0'
5540 }; //second part of magic unpacker
5544 ~future_when_all_vector_shared_state() {}
5547 ////////////////////////////////
5548 // detail::future_async_when_any_shared_state
5549 ////////////////////////////////
5550 template<typename F>
5551 struct future_when_any_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
5553 typedef csbl::vector<F> vector_type;
5554 typedef typename F::value_type value_type;
5557 static void run(shared_ptr<boost::detail::shared_state_base> that_)
5559 future_when_any_vector_shared_state* that = static_cast<future_when_any_vector_shared_state*>(that_.get());
5561 boost::wait_for_any(that->vec_.begin(), that->vec_.end());
5562 that->mark_finished_with_result(boost::move(that->vec_));
5564 that->mark_exceptional_finish();
5567 bool run_deferred() {
5569 for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
5570 if (it->run_if_is_deferred_or_ready())
5580 future_when_any_vector_shared_state::run(this->shared_from_this());
5584 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5585 this->thr_ = boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this());
5587 boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this()).detach();
5592 template< typename InputIterator>
5593 future_when_any_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
5594 : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
5598 future_when_any_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
5599 : vec_(boost::move(v))
5603 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5604 template< typename T0, typename ...T>
5605 future_when_any_vector_shared_state(values_tag,
5606 BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures
5608 vec_.push_back(boost::forward<T0>(f));
5609 typename alias_t<char[]>::type{
5610 ( //first part of magic unpacker
5611 vec_.push_back(boost::forward<T>(futures))
5615 }; //second part of magic unpacker
5619 ~future_when_any_vector_shared_state() {}
5622 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5623 struct wait_for_all_fctr {
5624 template <class ...T>
5625 void operator()(T&&... v) {
5626 boost::wait_for_all(boost::forward<T>(v)...);
5630 struct wait_for_any_fctr {
5631 template <class ...T>
5632 void operator()(T&&... v) {
5633 boost::wait_for_any(boost::forward<T>(v)...);
5638 template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5639 struct accumulate_run_if_is_deferred {
5640 bool operator ()(Tuple& t)
5642 return (! csbl::get<i-1>(t).run_if_is_deferred()) || accumulate_run_if_is_deferred<Tuple,i-1>()(t);
5645 template <class Tuple>
5646 struct accumulate_run_if_is_deferred<Tuple, 0> {
5647 bool operator ()(Tuple& )
5654 template< typename Tuple, typename T0, typename ...T>
5655 struct future_when_all_tuple_shared_state: future_async_shared_state_base<Tuple>
5658 typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5660 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
5661 future_when_all_tuple_shared_state* that = static_cast<future_when_all_tuple_shared_state*>(that_.get());
5663 // TODO make use of apply(that->tup_, boost::detail::wait_for_all_fctor());
5664 that->wait_for_all(Index());
5666 that->mark_finished_with_result(boost::move(that->tup_));
5668 that->mark_exceptional_finish();
5672 template <size_t ...Indices>
5673 void wait_for_all(tuple_indices<Indices...>) {
5674 #if defined BOOST_THREAD_PROVIDES_INVOKE
5675 return invoke<void>(wait_for_all_fctr(), csbl::get<Indices>(tup_)...);
5677 return wait_for_all_fctr()(csbl::get<Indices>(tup_)...);
5681 bool run_deferred() {
5683 return accumulate_run_if_is_deferred<Tuple>()(tup_);
5686 if (! run_deferred())
5688 future_when_all_tuple_shared_state::run(this->shared_from_this());
5691 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5692 this->thr_ = boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this());
5694 boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this()).detach();
5699 template< typename F, typename ...Fs>
5700 future_when_all_tuple_shared_state(values_tag, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures) :
5701 tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5705 ~future_when_all_tuple_shared_state() {}
5710 template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5711 struct apply_any_run_if_is_deferred_or_ready {
5712 bool operator ()(Tuple& t)
5714 if (csbl::get<i-1>(t).run_if_is_deferred_or_ready()) return true;
5715 return apply_any_run_if_is_deferred_or_ready<Tuple,i-1>()(t);
5718 template <class Tuple>
5719 struct apply_any_run_if_is_deferred_or_ready<Tuple, 0> {
5720 bool operator ()(Tuple& )
5726 template< typename Tuple, typename T0, typename ...T >
5727 struct future_when_any_tuple_shared_state: future_async_shared_state_base<Tuple>
5730 typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5732 static void run(shared_ptr<boost::detail::shared_state_base> that_)
5734 future_when_any_tuple_shared_state* that = static_cast<future_when_any_tuple_shared_state*>(that_.get());
5736 // TODO make use of apply(that->tup_, wait_for_any_fctr);
5737 that->wait_for_any(Index());
5739 that->mark_finished_with_result(boost::move(that->tup_));
5741 that->mark_exceptional_finish();
5744 template <size_t ...Indices>
5745 void wait_for_any(tuple_indices<Indices...>) {
5746 #if defined BOOST_THREAD_PROVIDES_INVOKE
5747 return invoke<void>(wait_for_any_fctr(), csbl::get<Indices>(tup_)...);
5749 return wait_for_any_fctr()(csbl::get<Indices>(tup_)...);
5752 bool run_deferred() {
5753 return apply_any_run_if_is_deferred_or_ready<Tuple>()(tup_);
5758 future_when_any_tuple_shared_state::run(this->shared_from_this());
5762 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5763 this->thr_ = boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this());
5765 boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this()).detach();
5770 template< typename F, typename ...Fs>
5771 future_when_any_tuple_shared_state(values_tag,
5772 BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures
5774 tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5778 ~future_when_any_tuple_shared_state() {}
5784 template< typename InputIterator>
5785 typename boost::disable_if<is_future_type<InputIterator>,
5786 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
5788 when_all(InputIterator first, InputIterator last) {
5789 typedef typename InputIterator::value_type value_type;
5790 typedef csbl::vector<value_type> container_type;
5791 typedef detail::future_when_all_vector_shared_state<value_type> factory_type;
5793 if (first==last) return make_ready_future(container_type());
5794 shared_ptr<factory_type >
5795 h(new factory_type(detail::input_iterator_tag_value, first,last));
5797 return BOOST_THREAD_FUTURE<container_type>(h);
5800 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all() {
5801 return make_ready_future(csbl::tuple<>());
5804 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5805 template< typename T0, typename ...T>
5806 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5807 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5808 typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5809 typedef detail::future_when_all_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5811 shared_ptr<factory_type>
5812 h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5814 return BOOST_THREAD_FUTURE<container_type>(h);
5818 template< typename InputIterator>
5819 typename boost::disable_if<is_future_type<InputIterator>,
5820 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
5822 when_any(InputIterator first, InputIterator last) {
5823 typedef typename InputIterator::value_type value_type;
5824 typedef csbl::vector<value_type> container_type;
5825 typedef detail::future_when_any_vector_shared_state<value_type> factory_type;
5827 if (first==last) return make_ready_future(container_type());
5828 shared_ptr<factory_type >
5829 h(new factory_type(detail::input_iterator_tag_value, first,last));
5831 return BOOST_THREAD_FUTURE<container_type>(h);
5834 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any() {
5835 return make_ready_future(csbl::tuple<>());
5838 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5839 template< typename T0, typename ...T>
5840 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5841 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5842 typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5843 typedef detail::future_when_any_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5845 shared_ptr<factory_type>
5846 h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5848 return BOOST_THREAD_FUTURE<container_type>(h);
5851 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
5854 #endif // BOOST_NO_EXCEPTIONS