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);
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_at_thread_exit(exception_ptr e)
426 unique_lock<boost::mutex> lk(this->mutex);
429 throw_exception(promise_already_satisfied());
432 this->is_constructed = true;
433 detail::make_ready_at_thread_exit(shared_from_this());
436 bool has_value() const
438 boost::lock_guard<boost::mutex> lock(this->mutex);
439 return done && ! exception;
442 bool has_value(unique_lock<boost::mutex>& ) const
444 return done && ! exception;
447 bool has_exception() const
449 boost::lock_guard<boost::mutex> lock(this->mutex);
450 return done && exception;
453 launch launch_policy(boost::unique_lock<boost::mutex>&) const
458 future_state::state get_state(boost::unique_lock<boost::mutex>&) const
462 return future_state::waiting;
466 return future_state::ready;
469 future_state::state get_state() const
471 boost::lock_guard<boost::mutex> guard(this->mutex);
474 return future_state::waiting;
478 return future_state::ready;
482 exception_ptr get_exception_ptr()
484 boost::unique_lock<boost::mutex> lock(this->mutex);
485 wait_internal(lock, false);
489 template<typename F,typename U>
490 void set_wait_callback(F f,U* u)
492 boost::lock_guard<boost::mutex> lock(this->mutex);
493 callback=boost::bind(f,boost::ref(*u));
496 virtual void execute(boost::unique_lock<boost::mutex>&) {}
499 shared_state_base(shared_state_base const&);
500 shared_state_base& operator=(shared_state_base const&);
503 // Used to create stand-alone futures
506 detail::shared_state_base
508 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
509 typedef boost::optional<T> storage_type;
511 typedef boost::csbl::unique_ptr<T> storage_type;
513 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
514 typedef T const& source_reference_type;
515 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
516 typedef T move_dest_type;
517 #elif defined BOOST_THREAD_USES_MOVE
518 typedef typename conditional<boost::is_fundamental<T>::value,T,T const&>::type source_reference_type;
519 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
520 typedef T move_dest_type;
522 typedef T& source_reference_type;
523 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;
524 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;
527 typedef const T& shared_future_get_result_type;
534 shared_state(exceptional_ptr const& ex):
535 detail::shared_state_base(ex), result()
543 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
545 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
548 result.reset(new T(result_));
550 this->mark_finished_internal(lock);
553 void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
555 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
556 result = boost::move(result_);
557 #elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
558 result.reset(new T(boost::move(result_)));
560 result.reset(new T(static_cast<rvalue_source_type>(result_)));
562 this->mark_finished_internal(lock);
566 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
567 template <class ...Args>
568 void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock, BOOST_THREAD_FWD_REF(Args)... args)
570 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
571 result.emplace(boost::forward<Args>(args)...);
573 result.reset(new T(boost::forward<Args>(args)...));
575 this->mark_finished_internal(lock);
579 void mark_finished_with_result(source_reference_type result_)
581 boost::unique_lock<boost::mutex> lock(this->mutex);
582 this->mark_finished_with_result_internal(result_, lock);
585 void mark_finished_with_result(rvalue_source_type result_)
587 boost::unique_lock<boost::mutex> lock(this->mutex);
589 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
590 mark_finished_with_result_internal(boost::move(result_), lock);
592 mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
596 storage_type& get_storage(boost::unique_lock<boost::mutex>& lk)
601 virtual move_dest_type get(boost::unique_lock<boost::mutex>& lk)
603 return boost::move(*get_storage(lk));
607 boost::unique_lock<boost::mutex> lk(this->mutex);
608 return this->get(lk);
611 virtual shared_future_get_result_type get_sh(boost::unique_lock<boost::mutex>& lk)
613 return *get_storage(lk);
615 shared_future_get_result_type get_sh()
617 boost::unique_lock<boost::mutex> lk(this->mutex);
618 return this->get_sh(lk);
621 void set_value_at_thread_exit(source_reference_type result_)
623 unique_lock<boost::mutex> lk(this->mutex);
624 if (this->has_value(lk))
626 throw_exception(promise_already_satisfied());
628 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
631 result.reset(new T(result_));
634 this->is_constructed = true;
635 detail::make_ready_at_thread_exit(shared_from_this());
637 void set_value_at_thread_exit(rvalue_source_type result_)
639 unique_lock<boost::mutex> lk(this->mutex);
640 if (this->has_value(lk))
641 throw_exception(promise_already_satisfied());
643 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
644 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
645 result = boost::move(result_);
647 result.reset(new T(boost::move(result_)));
650 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
651 result = boost::move(result_);
653 result.reset(new T(static_cast<rvalue_source_type>(result_)));
656 this->is_constructed = true;
657 detail::make_ready_at_thread_exit(shared_from_this());
661 shared_state(shared_state const&);
662 shared_state& operator=(shared_state const&);
666 struct shared_state<T&>:
667 detail::shared_state_base
669 typedef T* storage_type;
670 typedef T& source_reference_type;
671 typedef T& move_dest_type;
672 typedef T& shared_future_get_result_type;
680 shared_state(exceptional_ptr const& ex):
681 detail::shared_state_base(ex), result(0)
688 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
691 mark_finished_internal(lock);
694 void mark_finished_with_result(source_reference_type result_)
696 boost::unique_lock<boost::mutex> lock(this->mutex);
697 mark_finished_with_result_internal(result_, lock);
700 virtual T& get(boost::unique_lock<boost::mutex>& lock)
707 boost::unique_lock<boost::mutex> lk(this->mutex);
711 virtual T& get_sh(boost::unique_lock<boost::mutex>& lock)
718 boost::unique_lock<boost::mutex> lock(this->mutex);
722 void set_value_at_thread_exit(T& result_)
724 unique_lock<boost::mutex> lk(this->mutex);
725 if (this->has_value(lk))
726 throw_exception(promise_already_satisfied());
728 this->is_constructed = true;
729 detail::make_ready_at_thread_exit(shared_from_this());
733 shared_state(shared_state const&);
734 shared_state& operator=(shared_state const&);
738 struct shared_state<void>:
739 detail::shared_state_base
741 typedef void shared_future_get_result_type;
742 typedef void move_dest_type;
747 shared_state(exceptional_ptr const& ex):
748 detail::shared_state_base(ex)
751 void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
753 mark_finished_internal(lock);
756 void mark_finished_with_result()
758 boost::unique_lock<boost::mutex> lock(this->mutex);
759 mark_finished_with_result_internal(lock);
762 virtual void get(boost::unique_lock<boost::mutex>& lock)
764 this->wait_internal(lock);
768 boost::unique_lock<boost::mutex> lock(this->mutex);
772 virtual void get_sh(boost::unique_lock<boost::mutex>& lock)
774 this->wait_internal(lock);
778 boost::unique_lock<boost::mutex> lock(this->mutex);
782 void set_value_at_thread_exit()
784 unique_lock<boost::mutex> lk(this->mutex);
785 if (this->has_value(lk))
787 throw_exception(promise_already_satisfied());
789 this->is_constructed = true;
790 detail::make_ready_at_thread_exit(shared_from_this());
793 shared_state(shared_state const&);
794 shared_state& operator=(shared_state const&);
797 /////////////////////////
798 /// future_async_shared_state_base
799 /////////////////////////
800 template<typename Rp>
801 struct future_async_shared_state_base: shared_state<Rp>
803 typedef shared_state<Rp> base_type;
805 #ifdef BOOST_THREAD_FUTURE_BLOCKING
809 if (this_thread::get_id() == thr_.get_id())
814 if (thr_.joinable()) thr_.join();
818 future_async_shared_state_base()
823 ~future_async_shared_state_base()
825 #ifdef BOOST_THREAD_FUTURE_BLOCKING
827 #elif defined BOOST_THREAD_ASYNC_FUTURE_WAITS
828 unique_lock<boost::mutex> lk(this->mutex);
831 this->waiters.wait(lk);
836 virtual void wait(boost::unique_lock<boost::mutex>& lk, bool rethrow)
838 #ifdef BOOST_THREAD_FUTURE_BLOCKING
844 this->base_type::wait(lk, rethrow);
848 /////////////////////////
849 /// future_async_shared_state
850 /////////////////////////
851 template<typename Rp, typename Fp>
852 struct future_async_shared_state: future_async_shared_state_base<Rp>
854 future_async_shared_state()
858 void init(BOOST_THREAD_FWD_REF(Fp) f)
860 #ifdef BOOST_THREAD_FUTURE_BLOCKING
861 this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f));
863 boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f)).detach();
867 static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
871 that->mark_finished_with_result(f());
875 that->mark_exceptional_finish();
880 template<typename Fp>
881 struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void>
883 void init(BOOST_THREAD_FWD_REF(Fp) f)
885 #ifdef BOOST_THREAD_FUTURE_BLOCKING
886 this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
888 boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
892 static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
897 that->mark_finished_with_result();
901 that->mark_exceptional_finish();
906 template<typename Rp, typename Fp>
907 struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&>
909 void init(BOOST_THREAD_FWD_REF(Fp) f)
911 #ifdef BOOST_THREAD_FUTURE_BLOCKING
912 this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
914 boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
918 static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
922 that->mark_finished_with_result(f());
926 that->mark_exceptional_finish();
931 //////////////////////////
932 /// future_deferred_shared_state
933 //////////////////////////
934 template<typename Rp, typename Fp>
935 struct future_deferred_shared_state: shared_state<Rp>
937 typedef shared_state<Rp> base_type;
941 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
942 : func_(boost::move(f))
944 this->set_deferred();
947 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
950 Fp local_fuct=boost::move(func_);
951 relocker relock(lck);
952 Rp res = local_fuct();
954 this->mark_finished_with_result_internal(boost::move(res), lck);
958 this->mark_exceptional_finish_internal(current_exception(), lck);
962 template<typename Rp, typename Fp>
963 struct future_deferred_shared_state<Rp&,Fp>: shared_state<Rp&>
965 typedef shared_state<Rp&> base_type;
969 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
970 : func_(boost::move(f))
972 this->set_deferred();
975 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
978 this->mark_finished_with_result_internal(func_(), lck);
982 this->mark_exceptional_finish_internal(current_exception(), lck);
987 template<typename Fp>
988 struct future_deferred_shared_state<void,Fp>: shared_state<void>
990 typedef shared_state<void> base_type;
994 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
995 : func_(boost::move(f))
997 this->set_deferred();
1000 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
1003 Fp local_fuct=boost::move(func_);
1004 relocker relock(lck);
1007 this->mark_finished_with_result_internal(lck);
1011 this->mark_exceptional_finish_internal(current_exception(), lck);
1019 typedef std::vector<int>::size_type count_type;
1021 struct registered_waiter;
1022 struct registered_waiter
1024 boost::shared_ptr<detail::shared_state_base> future_;
1025 detail::shared_state_base::notify_when_ready_handle handle;
1028 registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
1029 detail::shared_state_base::notify_when_ready_handle handle_,
1031 future_(a_future),handle(handle_),index(index_)
1035 struct all_futures_lock
1038 typedef std::ptrdiff_t count_type_portable;
1040 typedef count_type count_type_portable;
1042 count_type_portable count;
1043 boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
1045 all_futures_lock(std::vector<registered_waiter>& futures):
1046 count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
1048 for(count_type_portable i=0;i<count;++i)
1050 locks[i]=BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(futures[i].future_->mutex));
1056 boost::lock(locks.get(),locks.get()+count);
1061 for(count_type_portable i=0;i<count;++i)
1068 boost::condition_variable_any cv;
1069 std::vector<registered_waiter> futures_;
1070 count_type future_count;
1077 template<typename F>
1082 registered_waiter waiter(f.future_,f.future_->notify_when_ready(cv),future_count);
1084 futures_.push_back(waiter);
1086 f.future_->unnotify_when_ready(waiter.handle);
1093 #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1094 template<typename F1, typename... Fs>
1095 void add(F1& f1, Fs&... fs)
1097 add(f1); add(fs...);
1103 all_futures_lock lk(futures_);
1106 for(count_type i=0;i<futures_.size();++i)
1108 if(futures_[i].future_->done)
1110 return futures_[i].index;
1119 for(count_type i=0;i<futures_.size();++i)
1121 futures_[i].future_->unnotify_when_ready(futures_[i].handle);
1128 template <typename R>
1129 class BOOST_THREAD_FUTURE;
1131 template <typename R>
1132 class shared_future;
1134 template<typename T>
1135 struct is_future_type<BOOST_THREAD_FUTURE<T> > : true_type
1139 template<typename T>
1140 struct is_future_type<shared_future<T> > : true_type
1144 // template<typename Iterator>
1145 // typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
1150 // detail::future_waiter waiter;
1151 // for(Iterator current=begin;current!=end;++current)
1153 // waiter.add(*current);
1155 // return boost::next(begin,waiter.wait());
1158 #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1159 template<typename F1,typename F2>
1160 typename boost::enable_if<is_future_type<F1>,typename detail::future_waiter::count_type>::type wait_for_any(F1& f1,F2& f2)
1162 detail::future_waiter waiter;
1165 return waiter.wait();
1168 template<typename F1,typename F2,typename F3>
1169 typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3)
1171 detail::future_waiter waiter;
1175 return waiter.wait();
1178 template<typename F1,typename F2,typename F3,typename F4>
1179 typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
1181 detail::future_waiter waiter;
1186 return waiter.wait();
1189 template<typename F1,typename F2,typename F3,typename F4,typename F5>
1190 typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
1192 detail::future_waiter waiter;
1198 return waiter.wait();
1201 template<typename F1, typename... Fs>
1202 typename boost::enable_if<is_future_type<F1>, typename detail::future_waiter::count_type>::type
1203 wait_for_any(F1& f1, Fs&... fs)
1205 detail::future_waiter waiter;
1206 waiter.add(f1, fs...);
1207 return waiter.wait();
1209 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1211 template <typename R>
1214 template <typename R>
1215 class packaged_task;
1219 /// Common implementation for all the futures independently of the return type
1224 /// Common implementation for future and shared_future.
1225 template <typename R>
1226 class basic_future : public base_future
1231 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
1232 typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
1234 static //BOOST_CONSTEXPR
1235 future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
1236 return future_ptr(new detail::shared_state<R>(ex));
1241 basic_future(future_ptr a_future):
1247 typedef future_state::state state;
1249 BOOST_THREAD_MOVABLE_ONLY(basic_future)
1250 basic_future(): future_() {}
1254 basic_future(exceptional_ptr const& ex)
1255 : future_(make_exceptional_future_ptr(ex))
1262 basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
1263 future_(BOOST_THREAD_RV(other).future_)
1265 BOOST_THREAD_RV(other).future_.reset();
1267 basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
1269 future_=BOOST_THREAD_RV(other).future_;
1270 BOOST_THREAD_RV(other).future_.reset();
1273 void swap(basic_future& that) BOOST_NOEXCEPT
1275 future_.swap(that.future_);
1277 // functions to check state, and wait for ready
1278 state get_state(boost::unique_lock<boost::mutex>& lk) const
1282 return future_state::uninitialized;
1284 return future_->get_state(lk);
1286 state get_state() const
1290 return future_state::uninitialized;
1292 return future_->get_state();
1295 bool is_ready() const
1297 return get_state()==future_state::ready;
1300 bool is_ready(boost::unique_lock<boost::mutex>& lk) const
1302 return get_state(lk)==future_state::ready;
1304 bool has_exception() const
1306 return future_ && future_->has_exception();
1309 bool has_value() const
1311 return future_ && future_->has_value();
1314 launch launch_policy(boost::unique_lock<boost::mutex>& lk) const
1316 if ( future_ ) return future_->launch_policy(lk);
1317 else return launch(launch::none);
1320 launch launch_policy() const
1323 boost::unique_lock<boost::mutex> lk(this->future_->mutex);
1324 return future_->launch_policy(lk);
1326 else return launch(launch::none);
1329 exception_ptr get_exception_ptr()
1332 ? future_->get_exception_ptr()
1336 bool valid() const BOOST_NOEXCEPT
1338 return future_ != 0 && future_->valid();
1345 boost::throw_exception(future_uninitialized());
1347 future_->wait(false);
1350 typedef detail::shared_state_base::notify_when_ready_handle notify_when_ready_handle;
1352 boost::mutex& mutex() {
1355 boost::throw_exception(future_uninitialized());
1357 return future_->mutex;
1360 notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
1364 boost::throw_exception(future_uninitialized());
1366 return future_->notify_when_ready(cv);
1369 void unnotify_when_ready(notify_when_ready_handle h)
1373 boost::throw_exception(future_uninitialized());
1375 return future_->unnotify_when_ready(h);
1378 #if defined BOOST_THREAD_USES_DATETIME
1379 template<typename Duration>
1380 bool timed_wait(Duration const& rel_time) const
1382 return timed_wait_until(boost::get_system_time()+rel_time);
1385 bool timed_wait_until(boost::system_time const& abs_time) const
1389 boost::throw_exception(future_uninitialized());
1391 return future_->timed_wait_until(abs_time);
1394 #ifdef BOOST_THREAD_USES_CHRONO
1395 template <class Rep, class Period>
1397 wait_for(const chrono::duration<Rep, Period>& rel_time) const
1399 return wait_until(chrono::steady_clock::now() + rel_time);
1402 template <class Clock, class Duration>
1404 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
1408 boost::throw_exception(future_uninitialized());
1410 return future_->wait_until(abs_time);
1417 BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END
1421 #if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005
1422 template <class Rp, class Fp>
1423 BOOST_THREAD_FUTURE<Rp>
1424 make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1426 template <class Rp, class Fp>
1427 BOOST_THREAD_FUTURE<Rp>
1428 make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1429 #endif // #if (!defined _MSC_VER || _MSC_VER >= 1400)
1430 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1431 template<typename F, typename Rp, typename Fp>
1432 struct future_deferred_continuation_shared_state;
1433 template<typename F, typename Rp, typename Fp>
1434 struct future_async_continuation_shared_state;
1436 template <class F, class Rp, class Fp>
1437 BOOST_THREAD_FUTURE<Rp>
1438 make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1440 template <class F, class Rp, class Fp>
1441 BOOST_THREAD_FUTURE<Rp>
1442 make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1444 template <class F, class Rp, class Fp>
1445 BOOST_THREAD_FUTURE<Rp>
1446 make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1448 template<typename F, typename Rp, typename Fp>
1449 BOOST_THREAD_FUTURE<Rp>
1450 make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1452 template<typename F, typename Rp, typename Fp>
1453 BOOST_THREAD_FUTURE<Rp>
1454 make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1456 template<typename F, typename Rp, typename Fp>
1457 BOOST_THREAD_FUTURE<Rp>
1458 make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1461 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1462 template<typename Ex, typename F, typename Rp, typename Fp>
1463 BOOST_THREAD_FUTURE<Rp>
1464 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);
1466 template<typename Ex, typename F, typename Rp, typename Fp>
1467 BOOST_THREAD_FUTURE<Rp>
1468 make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1470 template <class Rp, class Fp, class Executor>
1471 BOOST_THREAD_FUTURE<Rp>
1472 make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1475 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1476 template<typename F, typename Rp>
1477 struct future_unwrap_shared_state;
1478 template <class F, class Rp>
1479 inline BOOST_THREAD_FUTURE<Rp>
1480 make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1483 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1484 template< typename InputIterator>
1485 typename boost::disable_if<is_future_type<InputIterator>,
1486 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1488 when_all(InputIterator first, InputIterator last);
1490 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1492 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1493 template< typename T0, typename ...T>
1494 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1495 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1498 template< typename InputIterator>
1499 typename boost::disable_if<is_future_type<InputIterator>,
1500 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1502 when_any(InputIterator first, InputIterator last);
1504 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1506 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1507 template< typename T0, typename ...T>
1508 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1509 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1511 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1514 template <typename R>
1515 class BOOST_THREAD_FUTURE : public detail::basic_future<R>
1518 typedef detail::basic_future<R> base_type;
1519 typedef typename base_type::future_ptr future_ptr;
1521 friend class shared_future<R>;
1522 friend class promise<R>;
1523 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1524 template <typename, typename, typename>
1525 friend struct detail::future_async_continuation_shared_state;
1526 template <typename, typename, typename>
1527 friend struct detail::future_deferred_continuation_shared_state;
1529 template <class F, class Rp, class Fp>
1530 friend BOOST_THREAD_FUTURE<Rp>
1531 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);
1533 template <class F, class Rp, class Fp>
1534 friend BOOST_THREAD_FUTURE<Rp>
1535 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);
1537 template <class F, class Rp, class Fp>
1538 friend BOOST_THREAD_FUTURE<Rp>
1539 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);
1541 template<typename F, typename Rp, typename Fp>
1542 friend BOOST_THREAD_FUTURE<Rp>
1543 detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1545 template<typename F, typename Rp, typename Fp>
1546 friend BOOST_THREAD_FUTURE<Rp>
1547 detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1549 template<typename F, typename Rp, typename Fp>
1550 friend BOOST_THREAD_FUTURE<Rp>
1551 detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1553 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1554 template<typename Ex, typename F, typename Rp, typename Fp>
1555 friend BOOST_THREAD_FUTURE<Rp>
1556 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);
1558 template<typename Ex, typename F, typename Rp, typename Fp>
1559 friend BOOST_THREAD_FUTURE<Rp>
1560 detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1562 template <class Rp, class Fp, class Executor>
1563 friend BOOST_THREAD_FUTURE<Rp>
1564 detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1567 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1568 template<typename F, typename Rp>
1569 friend struct detail::future_unwrap_shared_state;
1570 template <class F, class Rp>
1571 friend BOOST_THREAD_FUTURE<Rp>
1572 detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1574 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1575 template< typename InputIterator>
1576 friend typename boost::disable_if<is_future_type<InputIterator>,
1577 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1579 when_all(InputIterator first, InputIterator last);
1581 //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1583 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1584 template< typename T0, typename ...T>
1585 friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1586 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1589 template< typename InputIterator>
1590 friend typename boost::disable_if<is_future_type<InputIterator>,
1591 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1593 when_any(InputIterator first, InputIterator last);
1595 //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1597 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1598 template< typename T0, typename ...T>
1599 friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1600 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1602 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1603 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1604 template <class> friend class packaged_task; // todo check if this works in windows
1606 friend class packaged_task<R>;
1608 friend class detail::future_waiter;
1610 template <class Rp, class Fp>
1611 friend BOOST_THREAD_FUTURE<Rp>
1612 detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1614 template <class Rp, class Fp>
1615 friend BOOST_THREAD_FUTURE<Rp>
1616 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1618 typedef typename base_type::move_dest_type move_dest_type;
1620 BOOST_THREAD_FUTURE(future_ptr a_future):
1626 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1627 typedef future_state::state state;
1628 typedef R value_type; // EXTENSION
1630 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1632 BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1635 ~BOOST_THREAD_FUTURE() {
1638 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1639 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1642 inline explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
1644 explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(shared_future<R>) other) :
1645 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1648 BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
1650 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1654 shared_future<R> share()
1656 return shared_future<R>(::boost::move(*this));
1659 void swap(BOOST_THREAD_FUTURE& other)
1661 static_cast<base_type*>(this)->swap(other);
1664 // todo this function must be private and friendship provided to the internal users.
1667 this->future_->set_async();
1669 // todo this function must be private and friendship provided to the internal users.
1672 this->future_->set_deferred();
1674 bool run_if_is_deferred() {
1675 return this->future_->run_if_is_deferred();
1677 bool run_if_is_deferred_or_ready() {
1678 return this->future_->run_if_is_deferred_or_ready();
1680 // retrieving the value
1681 move_dest_type get()
1683 if (this->future_ == 0)
1685 boost::throw_exception(future_uninitialized());
1687 unique_lock<boost::mutex> lk(this->future_->mutex);
1688 if (! this->future_->valid(lk))
1690 boost::throw_exception(future_uninitialized());
1692 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1693 this->future_->invalidate(lk);
1695 return this->future_->get(lk);
1698 template <typename R2>
1699 typename boost::disable_if< is_void<R2>, move_dest_type>::type
1700 get_or(BOOST_THREAD_RV_REF(R2) v)
1703 if (this->future_ == 0)
1705 boost::throw_exception(future_uninitialized());
1707 unique_lock<boost::mutex> lk(this->future_->mutex);
1708 if (! this->future_->valid(lk))
1710 boost::throw_exception(future_uninitialized());
1712 this->future_->wait(lk, false);
1713 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1714 this->future_->invalidate(lk);
1717 if (this->future_->has_value(lk)) {
1718 return this->future_->get(lk);
1721 return boost::move(v);
1725 template <typename R2>
1726 typename boost::disable_if< is_void<R2>, move_dest_type>::type
1727 get_or(R2 const& v) // EXTENSION
1729 if (this->future_ == 0)
1731 boost::throw_exception(future_uninitialized());
1733 unique_lock<boost::mutex> lk(this->future_->mutex);
1734 if (! this->future_->valid(lk))
1736 boost::throw_exception(future_uninitialized());
1738 this->future_->wait(lk, false);
1739 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1740 this->future_->invalidate(lk);
1742 if (this->future_->has_value(lk)) {
1743 return this->future_->get(lk);
1750 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1751 template<typename F>
1752 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1753 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1754 template<typename F>
1755 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1756 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1757 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1758 template<typename Ex, typename F>
1759 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1760 then(Ex& ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1763 template <typename R2>
1764 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1765 fallback_to(BOOST_THREAD_RV_REF(R2) v); // EXTENSION
1766 template <typename R2>
1767 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1768 fallback_to(R2 const& v); // EXTENSION
1774 BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
1776 template <typename R2>
1777 class BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> > : public detail::basic_future<BOOST_THREAD_FUTURE<R2> >
1779 typedef BOOST_THREAD_FUTURE<R2> R;
1782 typedef detail::basic_future<R> base_type;
1783 typedef typename base_type::future_ptr future_ptr;
1785 friend class shared_future<R>;
1786 friend class promise<R>;
1787 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1788 template <typename, typename, typename>
1789 friend struct detail::future_async_continuation_shared_state;
1790 template <typename, typename, typename>
1791 friend struct detail::future_deferred_continuation_shared_state;
1793 template <class F, class Rp, class Fp>
1794 friend BOOST_THREAD_FUTURE<Rp>
1795 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);
1797 template <class F, class Rp, class Fp>
1798 friend BOOST_THREAD_FUTURE<Rp>
1799 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);
1801 template <class F, class Rp, class Fp>
1802 friend BOOST_THREAD_FUTURE<Rp>
1803 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);
1805 template<typename F, typename Rp, typename Fp>
1806 friend BOOST_THREAD_FUTURE<Rp>
1807 detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1809 template<typename F, typename Rp, typename Fp>
1810 friend BOOST_THREAD_FUTURE<Rp>
1811 detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1813 template<typename F, typename Rp, typename Fp>
1814 friend BOOST_THREAD_FUTURE<Rp>
1815 detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1817 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1818 template<typename Ex, typename F, typename Rp, typename Fp>
1819 friend BOOST_THREAD_FUTURE<Rp>
1820 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);
1822 template<typename Ex, typename F, typename Rp, typename Fp>
1823 friend BOOST_THREAD_FUTURE<Rp>
1824 detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
1826 template <class Rp, class Fp, class Executor>
1827 friend BOOST_THREAD_FUTURE<Rp>
1828 detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
1832 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1833 template<typename F, typename Rp>
1834 friend struct detail::future_unwrap_shared_state;
1835 template <class F, class Rp>
1836 friend BOOST_THREAD_FUTURE<Rp>
1837 detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1839 #if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
1840 template< typename InputIterator>
1841 friend typename boost::disable_if<is_future_type<InputIterator>,
1842 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1844 when_all(InputIterator first, InputIterator last);
1846 friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
1848 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1849 template< typename T0, typename ...T>
1850 friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1851 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1854 template< typename InputIterator>
1855 friend typename boost::disable_if<is_future_type<InputIterator>,
1856 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
1858 when_any(InputIterator first, InputIterator last);
1860 friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
1862 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1863 template< typename T0, typename ...T>
1864 friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
1865 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
1867 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
1869 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1870 template <class> friend class packaged_task; // todo check if this works in windows
1872 friend class packaged_task<R>;
1874 friend class detail::future_waiter;
1876 template <class Rp, class Fp>
1877 friend BOOST_THREAD_FUTURE<Rp>
1878 detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1880 template <class Rp, class Fp>
1881 friend BOOST_THREAD_FUTURE<Rp>
1882 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1884 typedef typename base_type::move_dest_type move_dest_type;
1886 BOOST_THREAD_FUTURE(future_ptr a_future):
1892 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1893 typedef future_state::state state;
1894 typedef R value_type; // EXTENSION
1896 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1898 BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1901 ~BOOST_THREAD_FUTURE() {
1904 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1905 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1909 BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
1911 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1915 shared_future<R> share()
1917 return shared_future<R>(::boost::move(*this));
1920 void swap(BOOST_THREAD_FUTURE& other)
1922 static_cast<base_type*>(this)->swap(other);
1925 // todo this function must be private and friendship provided to the internal users.
1928 this->future_->set_async();
1930 // todo this function must be private and friendship provided to the internal users.
1933 this->future_->set_deferred();
1935 bool run_if_is_deferred() {
1936 return this->future_->run_if_is_deferred();
1938 bool run_if_is_deferred_or_ready() {
1939 return this->future_->run_if_is_deferred_or_ready();
1941 // retrieving the value
1942 move_dest_type get()
1944 if (this->future_ == 0)
1946 boost::throw_exception(future_uninitialized());
1948 unique_lock<boost::mutex> lk(this->future_->mutex);
1949 if (! this->future_->valid(lk))
1951 boost::throw_exception(future_uninitialized());
1953 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1954 this->future_->invalidate(lk);
1956 return this->future_->get(lk);
1958 move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
1960 if (this->future_ == 0)
1962 boost::throw_exception(future_uninitialized());
1964 unique_lock<boost::mutex> lk(this->future_->mutex);
1965 if (! this->future_->valid(lk))
1967 boost::throw_exception(future_uninitialized());
1969 this->future_->wait(lk, false);
1970 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1971 this->future_->invalidate(lk);
1973 if (this->future_->has_value(lk)) return this->future_->get(lk);
1974 else return boost::move(v);
1977 move_dest_type get_or(R const& v) // EXTENSION
1979 if (this->future_ == 0)
1981 boost::throw_exception(future_uninitialized());
1983 unique_lock<boost::mutex> lk(this->future_->mutex);
1984 if (! this->future_->valid(lk))
1986 boost::throw_exception(future_uninitialized());
1988 this->future_->wait(lk, false);
1989 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1990 this->future_->invalidate(lk);
1992 if (this->future_->has_value(lk)) return this->future_->get(lk);
1997 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1998 template<typename F>
1999 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2000 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2001 template<typename F>
2002 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2003 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2004 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2005 template<typename Ex, typename F>
2006 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
2007 then(Ex &ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
2011 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
2013 BOOST_THREAD_FUTURE<R2>
2014 unwrap(); // EXTENSION
2019 template <typename R>
2020 class shared_future : public detail::basic_future<R>
2022 typedef detail::basic_future<R> base_type;
2023 typedef typename base_type::future_ptr future_ptr;
2025 friend class detail::future_waiter;
2026 friend class promise<R>;
2028 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2029 template <typename, typename, typename>
2030 friend struct detail::future_async_continuation_shared_state;
2031 template <typename, typename, typename>
2032 friend struct detail::future_deferred_continuation_shared_state;
2034 template <class F, class Rp, class Fp>
2035 friend BOOST_THREAD_FUTURE<Rp>
2036 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);
2038 template <class F, class Rp, class Fp>
2039 friend BOOST_THREAD_FUTURE<Rp>
2040 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);
2042 template <class F, class Rp, class Fp>
2043 friend BOOST_THREAD_FUTURE<Rp>
2044 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);
2046 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2047 template <class> friend class packaged_task;// todo check if this works in windows
2049 friend class packaged_task<R>;
2051 shared_future(future_ptr a_future):
2056 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_future)
2057 typedef R value_type; // EXTENSION
2059 shared_future(shared_future const& other):
2060 base_type(other.future_)
2063 typedef future_state::state state;
2065 BOOST_CONSTEXPR shared_future()
2068 shared_future(exceptional_ptr const& ex):
2073 shared_future& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_future) other)
2075 this->future_ = other.future_;
2079 shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
2080 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2083 shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT :
2084 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
2088 shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
2090 base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2093 shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT
2095 base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
2099 void swap(shared_future& other) BOOST_NOEXCEPT
2101 static_cast<base_type*>(this)->swap(other);
2103 bool run_if_is_deferred() {
2104 return this->future_->run_if_is_deferred();
2106 bool run_if_is_deferred_or_ready() {
2107 return this->future_->run_if_is_deferred_or_ready();
2109 // retrieving the value
2110 typename detail::shared_state<R>::shared_future_get_result_type get() const
2114 boost::throw_exception(future_uninitialized());
2116 return this->future_->get_sh();
2119 template <typename R2>
2120 typename boost::disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type
2121 get_or(BOOST_THREAD_RV_REF(R2) v) const // EXTENSION
2125 boost::throw_exception(future_uninitialized());
2127 this->future_->wait();
2128 if (this->future_->has_value()) return this->future_->get_sh();
2129 else return boost::move(v);
2132 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
2133 template<typename F>
2134 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2135 then(BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2136 template<typename F>
2137 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2138 then(launch policy, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2139 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2140 template<typename Ex, typename F>
2141 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
2142 then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
2148 BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
2150 template <typename R>
2153 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
2155 typedef typename detail::shared_state<R>::source_reference_type source_reference_type;
2156 typedef typename detail::shared_state<R>::rvalue_source_type rvalue_source_type;
2157 typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
2158 typedef typename detail::shared_state<R>::shared_future_get_result_type shared_future_get_result_type;
2161 bool future_obtained;
2165 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2166 #include <boost/detail/atomic_undef_macros.hpp>
2167 if(!atomic_load(&future_))
2170 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R>));
2172 #include <boost/detail/atomic_redef_macros.hpp>
2177 BOOST_THREAD_MOVABLE_ONLY(promise)
2178 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2179 template <class Allocator>
2180 promise(boost::allocator_arg_t, Allocator a)
2182 typedef typename Allocator::template rebind<detail::shared_state<R> >::other A2;
2184 typedef thread_detail::allocator_destructor<A2> D;
2186 future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R>(), D(a2, 1) );
2187 future_obtained = false;
2191 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2194 future_(new detail::shared_state<R>()),
2196 future_obtained(false)
2203 boost::unique_lock<boost::mutex> lock(future_->mutex);
2205 if(!future_->done && !future_->is_constructed)
2207 future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2213 promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2214 future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2216 BOOST_THREAD_RV(rhs).future_.reset();
2217 BOOST_THREAD_RV(rhs).future_obtained=false;
2219 promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2221 future_=BOOST_THREAD_RV(rhs).future_;
2222 future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2223 BOOST_THREAD_RV(rhs).future_.reset();
2224 BOOST_THREAD_RV(rhs).future_obtained=false;
2228 void swap(promise& other)
2230 future_.swap(other.future_);
2231 std::swap(future_obtained,other.future_obtained);
2234 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
2235 void set_executor(executor_ptr_type aex)
2238 if (future_.get()==0)
2240 boost::throw_exception(promise_moved());
2242 boost::lock_guard<boost::mutex> lk(future_->mutex);
2243 future_->set_executor_policy(aex, lk);
2247 BOOST_THREAD_FUTURE<R> get_future()
2250 if (future_.get()==0)
2252 boost::throw_exception(promise_moved());
2254 if (future_obtained)
2256 boost::throw_exception(future_already_retrieved());
2258 future_obtained=true;
2259 return BOOST_THREAD_FUTURE<R>(future_);
2262 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
2264 typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type set_value(TR const & r)
2267 boost::unique_lock<boost::mutex> lock(future_->mutex);
2270 boost::throw_exception(promise_already_satisfied());
2272 future_->mark_finished_with_result_internal(r, lock);
2275 void set_value(source_reference_type r)
2278 boost::unique_lock<boost::mutex> lock(future_->mutex);
2281 boost::throw_exception(promise_already_satisfied());
2283 future_->mark_finished_with_result_internal(r, lock);
2287 void set_value(rvalue_source_type r)
2290 boost::unique_lock<boost::mutex> lock(future_->mutex);
2293 boost::throw_exception(promise_already_satisfied());
2295 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
2296 future_->mark_finished_with_result_internal(boost::move(r), lock);
2298 future_->mark_finished_with_result_internal(static_cast<rvalue_source_type>(r), lock);
2302 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
2303 template <class ...Args>
2304 void emplace(BOOST_THREAD_FWD_REF(Args) ...args)
2307 boost::unique_lock<boost::mutex> lock(future_->mutex);
2310 boost::throw_exception(promise_already_satisfied());
2312 future_->mark_finished_with_result_internal(lock, boost::forward<Args>(args)...);
2317 void set_exception(boost::exception_ptr p)
2320 boost::unique_lock<boost::mutex> lock(future_->mutex);
2323 boost::throw_exception(promise_already_satisfied());
2325 future_->mark_exceptional_finish_internal(p, lock);
2327 template <typename E>
2328 void set_exception(E ex)
2330 set_exception(boost::copy_exception(ex));
2332 // setting the result with deferred notification
2333 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
2335 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)
2337 if (future_.get()==0)
2339 boost::throw_exception(promise_moved());
2341 future_->set_value_at_thread_exit(r);
2344 void set_value_at_thread_exit(source_reference_type r)
2346 if (future_.get()==0)
2348 boost::throw_exception(promise_moved());
2350 future_->set_value_at_thread_exit(r);
2353 void set_value_at_thread_exit(BOOST_THREAD_RV_REF(R) r)
2355 if (future_.get()==0)
2357 boost::throw_exception(promise_moved());
2359 future_->set_value_at_thread_exit(boost::move(r));
2361 void set_exception_at_thread_exit(exception_ptr e)
2363 if (future_.get()==0)
2365 boost::throw_exception(promise_moved());
2367 future_->set_exception_at_thread_exit(e);
2369 template <typename E>
2370 void set_exception_at_thread_exit(E ex)
2372 set_exception_at_thread_exit(boost::copy_exception(ex));
2375 template<typename F>
2376 void set_wait_callback(F f)
2379 future_->set_wait_callback(f,this);
2384 template <typename R>
2387 typedef boost::shared_ptr<detail::shared_state<R&> > future_ptr;
2390 bool future_obtained;
2394 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2395 #include <boost/detail/atomic_undef_macros.hpp>
2396 if(!atomic_load(&future_))
2399 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
2401 #include <boost/detail/atomic_redef_macros.hpp>
2406 BOOST_THREAD_MOVABLE_ONLY(promise)
2407 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2408 template <class Allocator>
2409 promise(boost::allocator_arg_t, Allocator a)
2411 typedef typename Allocator::template rebind<detail::shared_state<R&> >::other A2;
2413 typedef thread_detail::allocator_destructor<A2> D;
2415 future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R&>(), D(a2, 1) );
2416 future_obtained = false;
2420 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2423 future_(new detail::shared_state<R&>()),
2425 future_obtained(false)
2432 boost::unique_lock<boost::mutex> lock(future_->mutex);
2434 if(!future_->done && !future_->is_constructed)
2436 future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2442 promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2443 future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2445 BOOST_THREAD_RV(rhs).future_.reset();
2446 BOOST_THREAD_RV(rhs).future_obtained=false;
2448 promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2450 future_=BOOST_THREAD_RV(rhs).future_;
2451 future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2452 BOOST_THREAD_RV(rhs).future_.reset();
2453 BOOST_THREAD_RV(rhs).future_obtained=false;
2457 void swap(promise& other)
2459 future_.swap(other.future_);
2460 std::swap(future_obtained,other.future_obtained);
2464 BOOST_THREAD_FUTURE<R&> get_future()
2467 if (future_.get()==0)
2469 boost::throw_exception(promise_moved());
2471 if (future_obtained)
2473 boost::throw_exception(future_already_retrieved());
2475 future_obtained=true;
2476 return BOOST_THREAD_FUTURE<R&>(future_);
2479 void set_value(R& r)
2482 boost::unique_lock<boost::mutex> lock(future_->mutex);
2485 boost::throw_exception(promise_already_satisfied());
2487 future_->mark_finished_with_result_internal(r, lock);
2490 void set_exception(boost::exception_ptr p)
2493 boost::unique_lock<boost::mutex> lock(future_->mutex);
2496 boost::throw_exception(promise_already_satisfied());
2498 future_->mark_exceptional_finish_internal(p, lock);
2500 template <typename E>
2501 void set_exception(E ex)
2503 set_exception(boost::copy_exception(ex));
2506 // setting the result with deferred notification
2507 void set_value_at_thread_exit(R& r)
2509 if (future_.get()==0)
2511 boost::throw_exception(promise_moved());
2513 future_->set_value_at_thread_exit(r);
2516 void set_exception_at_thread_exit(exception_ptr e)
2518 if (future_.get()==0)
2520 boost::throw_exception(promise_moved());
2522 future_->set_exception_at_thread_exit(e);
2524 template <typename E>
2525 void set_exception_at_thread_exit(E ex)
2527 set_exception_at_thread_exit(boost::copy_exception(ex));
2530 template<typename F>
2531 void set_wait_callback(F f)
2534 future_->set_wait_callback(f,this);
2541 typedef boost::shared_ptr<detail::shared_state<void> > future_ptr;
2544 bool future_obtained;
2548 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2549 if(!atomic_load(&future_))
2552 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<void>));
2557 BOOST_THREAD_MOVABLE_ONLY(promise)
2559 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2560 template <class Allocator>
2561 promise(boost::allocator_arg_t, Allocator a)
2563 typedef typename Allocator::template rebind<detail::shared_state<void> >::other A2;
2565 typedef thread_detail::allocator_destructor<A2> D;
2567 future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<void>(), D(a2, 1) );
2568 future_obtained = false;
2572 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2575 future_(new detail::shared_state<void>),
2577 future_obtained(false)
2584 boost::unique_lock<boost::mutex> lock(future_->mutex);
2586 if(!future_->done && !future_->is_constructed)
2588 future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2594 promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2595 future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2597 // we need to release the future as shared_ptr doesn't implements move semantics
2598 BOOST_THREAD_RV(rhs).future_.reset();
2599 BOOST_THREAD_RV(rhs).future_obtained=false;
2602 promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2604 future_=BOOST_THREAD_RV(rhs).future_;
2605 future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2606 BOOST_THREAD_RV(rhs).future_.reset();
2607 BOOST_THREAD_RV(rhs).future_obtained=false;
2611 void swap(promise& other)
2613 future_.swap(other.future_);
2614 std::swap(future_obtained,other.future_obtained);
2618 BOOST_THREAD_FUTURE<void> get_future()
2622 if (future_.get()==0)
2624 boost::throw_exception(promise_moved());
2628 boost::throw_exception(future_already_retrieved());
2630 future_obtained=true;
2631 //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<void>(future_));
2632 return BOOST_THREAD_FUTURE<void>(future_);
2638 boost::unique_lock<boost::mutex> lock(future_->mutex);
2641 boost::throw_exception(promise_already_satisfied());
2643 future_->mark_finished_with_result_internal(lock);
2646 void set_exception(boost::exception_ptr p)
2649 boost::unique_lock<boost::mutex> lock(future_->mutex);
2652 boost::throw_exception(promise_already_satisfied());
2654 future_->mark_exceptional_finish_internal(p,lock);
2656 template <typename E>
2657 void set_exception(E ex)
2659 set_exception(boost::copy_exception(ex));
2662 // setting the result with deferred notification
2663 void set_value_at_thread_exit()
2665 if (future_.get()==0)
2667 boost::throw_exception(promise_moved());
2669 future_->set_value_at_thread_exit();
2672 void set_exception_at_thread_exit(exception_ptr e)
2674 if (future_.get()==0)
2676 boost::throw_exception(promise_moved());
2678 future_->set_exception_at_thread_exit(e);
2680 template <typename E>
2681 void set_exception_at_thread_exit(E ex)
2683 set_exception_at_thread_exit(boost::copy_exception(ex));
2686 template<typename F>
2687 void set_wait_callback(F f)
2690 future_->set_wait_callback(f,this);
2695 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2696 namespace boost { namespace container {
2697 template <class R, class Alloc>
2698 struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2702 #if ! defined BOOST_NO_CXX11_ALLOCATOR
2704 template <class R, class Alloc>
2705 struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2715 BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
2719 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2720 template<typename R>
2721 struct task_base_shared_state;
2722 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2723 template<typename R, typename ...ArgTypes>
2724 struct task_base_shared_state<R(ArgTypes...)>:
2726 template<typename R>
2727 struct task_base_shared_state<R()>:
2730 template<typename R>
2731 struct task_base_shared_state:
2733 detail::shared_state<R>
2737 task_base_shared_state():
2743 // todo The packaged_task::reset must be as if an assignemnt froma new packaged_task with the same function
2744 // the reset function is an optimization that avoids reallocating a new task.
2748 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2749 virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
2750 void run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2752 virtual void do_run()=0;
2757 boost::lock_guard<boost::mutex> lk(this->mutex);
2760 boost::throw_exception(task_already_started());
2764 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2765 do_run(boost::move(args)...);
2771 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2772 virtual void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
2773 void apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2775 virtual void do_apply()=0;
2780 boost::lock_guard<boost::mutex> lk(this->mutex);
2783 boost::throw_exception(task_already_started());
2787 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2788 do_apply(boost::move(args)...);
2794 void owner_destroyed()
2796 boost::unique_lock<boost::mutex> lk(this->mutex);
2800 this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk);
2805 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2806 template<typename F, typename R>
2807 struct task_shared_state;
2808 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2809 template<typename F, typename R, typename ...ArgTypes>
2810 struct task_shared_state<F, R(ArgTypes...)>:
2811 task_base_shared_state<R(ArgTypes...)>
2813 template<typename F, typename R>
2814 struct task_shared_state<F, R()>:
2815 task_base_shared_state<R()>
2818 template<typename F, typename R>
2819 struct task_shared_state:
2820 task_base_shared_state<R>
2824 task_shared_state(task_shared_state&);
2827 task_shared_state(F const& f_):
2830 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
2836 return boost::move(f);
2839 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2840 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2844 this->set_value_at_thread_exit(f(boost::move(args)...));
2851 this->set_value_at_thread_exit(f());
2856 this->set_exception_at_thread_exit(current_exception());
2860 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2861 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2865 this->mark_finished_with_result(f(boost::move(args)...));
2872 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
2874 this->mark_finished_with_result(boost::move(res));
2876 this->mark_finished_with_result(f());
2882 this->mark_exceptional_finish();
2887 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2888 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2889 template<typename F, typename R, typename ...ArgTypes>
2890 struct task_shared_state<F, R&(ArgTypes...)>:
2891 task_base_shared_state<R&(ArgTypes...)>
2893 template<typename F, typename R>
2894 struct task_shared_state<F, R&()>:
2895 task_base_shared_state<R&()>
2898 template<typename F, typename R>
2899 struct task_shared_state<F,R&>:
2900 task_base_shared_state<R&>
2904 task_shared_state(task_shared_state&);
2907 task_shared_state(F const& f_):
2910 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
2919 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2920 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2924 this->set_value_at_thread_exit(f(boost::move(args)...));
2931 this->set_value_at_thread_exit(f());
2936 this->set_exception_at_thread_exit(current_exception());
2940 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2941 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2945 this->mark_finished_with_result(f(boost::move(args)...));
2953 this->mark_finished_with_result(res);
2958 this->mark_exceptional_finish();
2963 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
2965 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2966 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2967 template<typename R, typename ...ArgTypes>
2968 struct task_shared_state<R (*)(ArgTypes...), R(ArgTypes...)>:
2969 task_base_shared_state<R(ArgTypes...)>
2971 template<typename R>
2972 struct task_shared_state<R (*)(), R()>:
2973 task_base_shared_state<R()>
2976 template<typename R>
2977 struct task_shared_state<R (*)(), R> :
2978 task_base_shared_state<R>
2982 task_shared_state(task_shared_state&);
2983 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2984 typedef R (*CallableType)(ArgTypes ... );
2986 typedef R (*CallableType)();
2990 task_shared_state(CallableType f_):
2994 CallableType callable()
2999 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3000 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3004 this->set_value_at_thread_exit(f(boost::move(args)...));
3012 this->set_value_at_thread_exit(boost::move(r));
3017 this->set_exception_at_thread_exit(current_exception());
3022 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3023 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3027 this->mark_finished_with_result(f(boost::move(args)...));
3035 this->mark_finished_with_result(boost::move(res));
3040 this->mark_exceptional_finish();
3044 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3045 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3046 template<typename R, typename ...ArgTypes>
3047 struct task_shared_state<R& (*)(ArgTypes...), R&(ArgTypes...)>:
3048 task_base_shared_state<R&(ArgTypes...)>
3050 template<typename R>
3051 struct task_shared_state<R& (*)(), R&()>:
3052 task_base_shared_state<R&()>
3055 template<typename R>
3056 struct task_shared_state<R& (*)(), R&> :
3057 task_base_shared_state<R&>
3061 task_shared_state(task_shared_state&);
3063 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3064 typedef R& (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes) ... );
3066 typedef R& (*CallableType)();
3069 task_shared_state(CallableType f_):
3073 CallableType callable()
3075 return boost::move(f);
3078 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3079 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3083 this->set_value_at_thread_exit(f(boost::move(args)...));
3090 this->set_value_at_thread_exit(f());
3095 this->set_exception_at_thread_exit(current_exception());
3100 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3101 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3105 this->mark_finished_with_result(f(boost::move(args)...));
3112 this->mark_finished_with_result(f());
3117 this->mark_exceptional_finish();
3122 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3123 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3124 template<typename F, typename ...ArgTypes>
3125 struct task_shared_state<F, void(ArgTypes...)>:
3126 task_base_shared_state<void(ArgTypes...)>
3128 template<typename F>
3129 struct task_shared_state<F, void()>:
3130 task_base_shared_state<void()>
3133 template<typename F>
3134 struct task_shared_state<F,void>:
3135 task_base_shared_state<void>
3139 task_shared_state(task_shared_state&);
3141 typedef F CallableType;
3143 task_shared_state(F const& f_):
3146 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
3151 return boost::move(f);
3153 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3154 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3158 f(boost::move(args)...);
3166 this->set_value_at_thread_exit();
3170 this->set_exception_at_thread_exit(current_exception());
3174 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3175 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3179 f(boost::move(args)...);
3187 this->mark_finished_with_result();
3191 this->mark_exceptional_finish();
3196 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3197 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3198 template<typename ...ArgTypes>
3199 struct task_shared_state<void (*)(ArgTypes...), void(ArgTypes...)>:
3200 task_base_shared_state<void(ArgTypes...)>
3203 struct task_shared_state<void (*)(), void()>:
3204 task_base_shared_state<void()>
3208 struct task_shared_state<void (*)(),void>:
3209 task_base_shared_state<void>
3213 task_shared_state(task_shared_state&);
3214 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3215 typedef void (*CallableType)(ArgTypes...);
3217 typedef void (*CallableType)();
3221 task_shared_state(CallableType f_):
3224 CallableType callable()
3228 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3229 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3233 f(boost::move(args)...);
3241 this->set_value_at_thread_exit();
3245 this->set_exception_at_thread_exit(current_exception());
3249 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3250 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3254 f(boost::move(args)...);
3262 this->mark_finished_with_result();
3266 this->mark_exceptional_finish();
3272 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3273 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3274 template<typename R, typename ...ArgTypes>
3275 class packaged_task<R(ArgTypes...)>
3277 typedef boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task_ptr;
3278 boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task;
3280 template<typename R>
3281 class packaged_task<R()>
3283 typedef boost::shared_ptr<detail::task_base_shared_state<R()> > task_ptr;
3284 boost::shared_ptr<detail::task_base_shared_state<R()> > task;
3287 template<typename R>
3290 typedef boost::shared_ptr<detail::task_base_shared_state<R> > task_ptr;
3291 boost::shared_ptr<detail::task_base_shared_state<R> > task;
3293 bool future_obtained;
3297 typedef R result_type;
3298 BOOST_THREAD_MOVABLE_ONLY(packaged_task)
3301 future_obtained(false)
3304 // construction and destruction
3305 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3307 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3308 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3309 explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args)
3311 typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3312 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3313 task= task_ptr(new task_shared_state_type(f, boost::move(args)...));
3314 future_obtained=false;
3317 explicit packaged_task(R(*f)())
3320 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3321 task= task_ptr(new task_shared_state_type(f));
3322 future_obtained=false;
3326 explicit packaged_task(R(*f)())
3329 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3330 task= task_ptr(new task_shared_state_type(f));
3331 future_obtained=false;
3335 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
3337 explicit packaged_task(BOOST_THREAD_FWD_REF(F) f
3338 , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3341 typedef typename decay<F>::type FR;
3342 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3343 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3344 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3346 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3349 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3351 task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
3352 future_obtained = false;
3358 explicit packaged_task(F const& f
3359 , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3362 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3363 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3364 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3366 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3369 typedef detail::task_shared_state<F,R> task_shared_state_type;
3371 task = task_ptr(new task_shared_state_type(f));
3372 future_obtained=false;
3375 explicit packaged_task(BOOST_THREAD_RV_REF(F) f)
3377 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3378 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3379 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3380 task = task_ptr(new task_shared_state_type(boost::move(f)));
3382 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3383 task = task_ptr(new task_shared_state_type(boost::move(f)));
3386 typedef detail::task_shared_state<F,R> task_shared_state_type;
3387 task = task_ptr(new task_shared_state_type(boost::move(f)));
3389 future_obtained=false;
3394 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3395 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3396 template <class Allocator>
3397 packaged_task(boost::allocator_arg_t, Allocator a, R(*f)())
3400 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3401 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3402 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3404 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3407 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3409 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3411 typedef thread_detail::allocator_destructor<A2> D;
3413 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3414 future_obtained = false;
3416 #endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3418 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3419 template <class F, class Allocator>
3420 packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
3422 typedef typename decay<F>::type FR;
3424 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3425 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3426 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3428 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3431 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3433 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3435 typedef thread_detail::allocator_destructor<A2> D;
3437 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
3438 future_obtained = false;
3440 #else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3441 template <class F, class Allocator>
3442 packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
3444 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3445 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3446 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3448 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3451 typedef detail::task_shared_state<F,R> task_shared_state_type;
3453 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3455 typedef thread_detail::allocator_destructor<A2> D;
3457 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3458 future_obtained = false;
3460 template <class F, class Allocator>
3461 packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f)
3463 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3464 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3465 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3467 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3470 typedef detail::task_shared_state<F,R> task_shared_state_type;
3472 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3474 typedef thread_detail::allocator_destructor<A2> D;
3476 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) );
3477 future_obtained = false;
3480 #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
3481 #endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3485 task->owner_destroyed();
3490 packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
3491 : future_obtained(BOOST_THREAD_RV(other).future_obtained) {
3492 task.swap(BOOST_THREAD_RV(other).task);
3493 BOOST_THREAD_RV(other).future_obtained=false;
3495 packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT {
3497 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3498 packaged_task temp(boost::move(other));
3500 packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
3506 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3507 void set_executor(executor_ptr_type aex)
3510 boost::throw_exception(task_moved());
3511 boost::lock_guard<boost::mutex> lk(task->mutex);
3512 task->set_executor_policy(aex, lk);
3517 boost::throw_exception(future_error(system::make_error_code(future_errc::no_state)));
3519 // As if *this = packaged_task(task->callable());
3522 future_obtained=false;
3525 void swap(packaged_task& other) BOOST_NOEXCEPT {
3526 task.swap(other.task);
3527 std::swap(future_obtained,other.future_obtained);
3529 bool valid() const BOOST_NOEXCEPT {
3530 return task.get()!=0;
3534 BOOST_THREAD_FUTURE<R> get_future() {
3536 boost::throw_exception(task_moved());
3537 } else if(!future_obtained) {
3538 future_obtained=true;
3539 return BOOST_THREAD_FUTURE<R>(task);
3541 boost::throw_exception(future_already_retrieved());
3546 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3547 void operator()(ArgTypes... args) {
3549 boost::throw_exception(task_moved());
3551 task->run(boost::move(args)...);
3553 void make_ready_at_thread_exit(ArgTypes... args) {
3555 boost::throw_exception(task_moved());
3557 if (task->has_value()) {
3558 boost::throw_exception(promise_already_satisfied());
3560 task->apply(boost::move(args)...);
3565 boost::throw_exception(task_moved());
3569 void make_ready_at_thread_exit() {
3571 boost::throw_exception(task_moved());
3573 if (task->has_value()) boost::throw_exception(promise_already_satisfied());
3577 template<typename F>
3578 void set_wait_callback(F f) {
3579 task->set_wait_callback(f,this);
3583 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3584 namespace boost { namespace container {
3585 template <class R, class Alloc>
3586 struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3589 #if ! defined BOOST_NO_CXX11_ALLOCATOR
3591 template <class R, class Alloc>
3592 struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3600 BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
3604 ////////////////////////////////
3605 // make_future_deferred_shared_state
3606 ////////////////////////////////
3607 template <class Rp, class Fp>
3608 BOOST_THREAD_FUTURE<Rp>
3609 make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3610 shared_ptr<future_deferred_shared_state<Rp, Fp> >
3611 h(new future_deferred_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
3612 return BOOST_THREAD_FUTURE<Rp>(h);
3615 ////////////////////////////////
3616 // make_future_async_shared_state
3617 ////////////////////////////////
3618 template <class Rp, class Fp>
3619 BOOST_THREAD_FUTURE<Rp>
3620 make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3621 shared_ptr<future_async_shared_state<Rp, Fp> >
3622 h(new future_async_shared_state<Rp, Fp>());
3623 h->init(boost::forward<Fp>(f));
3624 return BOOST_THREAD_FUTURE<Rp>(h);
3628 ////////////////////////////////
3629 // template <class F, class... ArgTypes>
3630 // future<R> async(launch policy, F&&, ArgTypes&&...);
3631 ////////////////////////////////
3633 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3635 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3636 template <class R, class... ArgTypes>
3637 BOOST_THREAD_FUTURE<R>
3638 async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3639 typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3640 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3641 typedef typename BF::result_type Rp;
3643 if (underlying_cast<int>(policy) & int(launch::async)) {
3644 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3647 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3650 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3651 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3654 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3659 //BOOST_THREAD_FUTURE<R> ret;
3660 //return ::boost::move(ret);
3664 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3667 BOOST_THREAD_FUTURE<R>
3668 async(launch policy, R(*f)()) {
3669 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3670 typedef packaged_task<R()> packaged_task_type;
3672 typedef packaged_task<R> packaged_task_type;
3675 if (underlying_cast<int>(policy) & int(launch::async)) {
3676 packaged_task_type pt( f );
3677 BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
3679 boost::thread( boost::move(pt) ).detach();
3680 return ::boost::move(ret);
3681 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3683 //BOOST_THREAD_FUTURE<R> ret;
3684 //return ::boost::move(ret);
3687 //BOOST_THREAD_FUTURE<R> ret;
3688 //return ::boost::move(ret);
3692 #endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3694 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3696 template <class F, class ...ArgTypes>
3697 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3698 typename decay<ArgTypes>::type...
3700 async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3701 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3702 typedef typename BF::result_type Rp;
3704 if (underlying_cast<int>(policy) & int(launch::async)) {
3705 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3707 thread_detail::decay_copy(boost::forward<F>(f))
3708 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3711 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3712 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3714 thread_detail::decay_copy(boost::forward<F>(f))
3715 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3720 //BOOST_THREAD_FUTURE<R> ret;
3721 //return ::boost::move(ret);
3725 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3728 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3729 async(launch policy, BOOST_THREAD_FWD_REF(F) f) {
3730 typedef typename boost::result_of<typename decay<F>::type()>::type R;
3731 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3732 typedef packaged_task<R()> packaged_task_type;
3733 #else // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3734 typedef packaged_task<R> packaged_task_type;
3735 #endif // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3737 if (underlying_cast<int>(policy) & int(launch::async)) {
3738 packaged_task_type pt( boost::forward<F>(f) );
3739 BOOST_THREAD_FUTURE<R> ret = pt.get_future();
3741 boost::thread( boost::move(pt) ).detach();
3742 return ::boost::move(ret);
3743 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3745 //BOOST_THREAD_FUTURE<R> ret;
3746 //return ::boost::move(ret);
3747 // return boost::detail::make_future_deferred_shared_state<Rp>(
3749 // thread_detail::decay_copy(boost::forward<F>(f))
3754 //BOOST_THREAD_FUTURE<R> ret;
3755 //return ::boost::move(ret);
3758 #endif // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3760 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3763 /////////////////////////
3764 /// shared_state_nullary_task
3765 /////////////////////////
3766 template<typename Rp, typename Fp>
3767 struct shared_state_nullary_task
3770 typedef shared_ptr<shared_state_base > storage_type;
3775 shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
3776 : that(st), f_(boost::move(f))
3779 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
3780 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
3781 shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
3782 : that(x.that), f_(x.f_)
3784 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3793 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3794 : that(x.that), f_(boost::move(x.f_))
3798 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3802 f_=boost::move(x.f_);
3809 shared_ptr<shared_state<Rp> > that_ = static_pointer_cast<shared_state<Rp> >(that);
3811 that_->mark_finished_with_result(f_());
3813 that_->mark_exceptional_finish();
3816 ~shared_state_nullary_task()
3821 template<typename Fp>
3822 struct shared_state_nullary_task<void, Fp>
3824 typedef shared_ptr<shared_state_base > storage_type;
3828 shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
3829 : that(st), f_(boost::move(f))
3832 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
3833 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
3834 shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
3835 : that(x.that), f_(x.f_)
3837 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3846 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
3847 : that(x.that), f_(boost::move(x.f_))
3851 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
3854 f_=boost::move(x.f_);
3861 shared_ptr<shared_state<void> > that_ = static_pointer_cast<shared_state<void> >(that);
3864 that_->mark_finished_with_result();
3866 that_->mark_exceptional_finish();
3872 BOOST_THREAD_DCL_MOVABLE_BEG2(R,F) detail::shared_state_nullary_task<R,F> BOOST_THREAD_DCL_MOVABLE_END
3875 /////////////////////////
3876 /// future_executor_shared_state_base
3877 /////////////////////////
3878 template<typename Rp>
3879 struct future_executor_shared_state: shared_state<Rp>
3881 typedef shared_state<Rp> base_type;
3884 future_executor_shared_state() {
3887 template <class Fp, class Executor>
3888 void init(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f)
3890 typedef typename decay<Fp>::type Cont;
3891 this->set_executor_policy(executor_ptr_type(new executor_ref<Executor>(ex)));
3892 shared_state_nullary_task<Rp,Cont> t(this->shared_from_this(), boost::forward<Fp>(f));
3893 ex.submit(boost::move(t));
3896 ~future_executor_shared_state() {}
3899 ////////////////////////////////
3900 // make_future_executor_shared_state
3901 ////////////////////////////////
3902 template <class Rp, class Fp, class Executor>
3903 BOOST_THREAD_FUTURE<Rp>
3904 make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
3905 shared_ptr<future_executor_shared_state<Rp> >
3906 h(new future_executor_shared_state<Rp>());
3907 h->init(ex, boost::forward<Fp>(f));
3908 return BOOST_THREAD_FUTURE<Rp>(h);
3913 ////////////////////////////////
3914 // template <class Executor, class F, class... ArgTypes>
3915 // future<R> async(Executor& ex, F&&, ArgTypes&&...);
3916 ////////////////////////////////
3918 //#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3919 #if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
3921 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3923 template <class Executor, class R, class... ArgTypes>
3924 BOOST_THREAD_FUTURE<R>
3925 async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3926 typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3927 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3928 typedef typename BF::result_type Rp;
3930 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3933 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3937 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3939 template <class Executor, class F, class ...ArgTypes>
3940 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3941 typename decay<ArgTypes>::type...
3943 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3944 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3945 typedef typename BF::result_type Rp;
3947 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3949 thread_detail::decay_copy(boost::forward<F>(f))
3950 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3955 #else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3956 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3958 template <class Executor, class R>
3959 BOOST_THREAD_FUTURE<R>
3960 async(Executor& ex, R(*f)()) {
3962 typedef detail::invoker<F> BF;
3963 typedef typename BF::result_type Rp;
3965 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3972 template <class Executor, class R, class A1>
3973 BOOST_THREAD_FUTURE<R>
3974 async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1) {
3975 typedef R(*F)(BOOST_THREAD_FWD_REF(A1));
3976 typedef detail::invoker<F, typename decay<A1>::type> BF;
3977 typedef typename BF::result_type Rp;
3979 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3982 , thread_detail::decay_copy(boost::forward<A1>(a1))
3986 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3988 template <class Executor, class F>
3989 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3990 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f) {
3991 typedef detail::invoker<typename decay<F>::type> BF;
3992 typedef typename BF::result_type Rp;
3994 return boost::detail::make_future_executor_shared_state<Rp>(ex,
3996 thread_detail::decay_copy(boost::forward<F>(f))
4001 template <class Executor, class F, class A1>
4002 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4003 typename decay<A1>::type
4005 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) {
4006 typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type> BF;
4007 typedef typename BF::result_type Rp;
4009 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4011 thread_detail::decay_copy(boost::forward<F>(f))
4012 , thread_detail::decay_copy(boost::forward<A1>(a1))
4017 template <class Executor, class F, class A1, class A2>
4018 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4019 typename decay<A1>::type, typename decay<A2>::type
4021 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) {
4022 typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type, typename decay<A2>::type> BF;
4023 typedef typename BF::result_type Rp;
4025 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
4027 thread_detail::decay_copy(boost::forward<F>(f))
4028 , thread_detail::decay_copy(boost::forward<A1>(a1))
4029 , thread_detail::decay_copy(boost::forward<A2>(a2))
4034 #endif //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4037 ////////////////////////////////
4038 // template <class F, class... ArgTypes>
4039 // future<R> async(F&&, ArgTypes&&...);
4040 ////////////////////////////////
4042 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
4043 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
4044 template <class R, class... ArgTypes>
4045 BOOST_THREAD_FUTURE<R>
4046 async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4047 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
4051 BOOST_THREAD_FUTURE<R>
4053 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
4058 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
4059 template <class F, class ...ArgTypes>
4060 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
4061 typename decay<ArgTypes>::type...
4063 async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
4064 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
4068 BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
4069 async(BOOST_THREAD_FWD_REF(F) f) {
4070 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
4074 ////////////////////////////////
4075 // make_future deprecated
4076 ////////////////////////////////
4077 template <typename T>
4078 BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value) {
4079 typedef typename decay<T>::type future_value_type;
4080 promise<future_value_type> p;
4081 p.set_value(boost::forward<future_value_type>(value));
4082 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4085 #if defined BOOST_THREAD_USES_MOVE
4086 inline BOOST_THREAD_FUTURE<void> make_future() {
4089 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4093 ////////////////////////////////
4094 // make_ready_future
4095 ////////////////////////////////
4098 struct deduced_type_impl
4104 struct deduced_type_impl<reference_wrapper<T> const>
4109 struct deduced_type_impl<reference_wrapper<T> >
4113 #if __cplusplus > 201103L
4115 struct deduced_type_impl<std::reference_wrapper<T> >
4123 typedef typename detail::deduced_type_impl<typename decay<T>::type>::type type;
4129 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4130 template <int = 0, int..., class T>
4134 BOOST_THREAD_FUTURE<typename detail::deduced_type<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
4135 typedef typename detail::deduced_type<T>::type future_value_type;
4136 promise<future_value_type> p;
4137 p.set_value(boost::forward<T>(value));
4138 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4141 // explicit overloads
4143 BOOST_THREAD_FUTURE<T> make_ready_future(typename remove_reference<T>::type & x)
4147 return p.get_future();
4151 BOOST_THREAD_FUTURE<T> make_ready_future(BOOST_THREAD_FWD_REF(typename remove_reference<T>::type) x)
4154 p.set_value(forward<typename remove_reference<T>::type>(x));
4155 return p.get_future();
4158 // variadic overload
4159 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4160 template <class T, class ...Args>
4161 BOOST_THREAD_FUTURE<T> make_ready_future(Args&&... args)
4164 p.emplace(forward<Args>(args)...);
4165 return p.get_future();
4170 template <typename T, typename T1>
4171 BOOST_THREAD_FUTURE<T> make_ready_no_decay_future(T1 value) {
4172 typedef T future_value_type;
4173 promise<future_value_type> p;
4175 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4178 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
4179 inline BOOST_THREAD_FUTURE<void> make_ready_future() {
4182 return p.get_future();
4187 template <typename T>
4188 BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
4190 p.set_exception(ex);
4191 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4194 template <typename T, typename E>
4195 BOOST_THREAD_FUTURE<T> make_exceptional_future(E ex) {
4197 p.set_exception(boost::copy_exception(ex));
4198 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4201 template <typename T>
4202 BOOST_THREAD_FUTURE<T> make_exceptional_future() {
4204 p.set_exception(boost::current_exception());
4205 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4207 template <typename T>
4208 BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex) {
4209 return make_exceptional_future<T>(ex);
4213 template<typename CLOSURE>
4214 make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE<decltype(closure())> {
4215 typedef decltype(closure()) T;
4218 p.set_value(closure());
4220 p.set_exception(std::current_exception());
4222 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4226 ////////////////////////////////
4227 // make_shared_future deprecated
4228 ////////////////////////////////
4229 template <typename T>
4230 shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value) {
4231 typedef typename decay<T>::type future_type;
4232 promise<future_type> p;
4233 p.set_value(boost::forward<T>(value));
4234 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4237 inline shared_future<void> make_shared_future() {
4239 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4242 ////////////////////////////////
4243 // detail::future_async_continuation_shared_state
4244 ////////////////////////////////
4245 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
4249 //////////////////////
4250 // detail::continuation_shared_state
4251 //////////////////////
4252 template<typename F, typename Rp, typename Fp, class ShSt=shared_state<Rp> >
4253 struct continuation_shared_state: ShSt
4259 continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4260 : parent(boost::move(f)),
4261 continuation(boost::move(c))
4265 void init(boost::unique_lock<boost::mutex> &lock)
4267 parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
4272 this->mark_finished_with_result(this->continuation(boost::move(this->parent)));
4274 this->mark_exceptional_finish();
4276 // make sure parent is really cleared to prevent memory "leaks"
4280 void call(boost::unique_lock<boost::mutex>& lck) {
4282 relocker relock(lck);
4284 // neither continuation nor parent are protected by the lock - call() must only
4285 // be called once, and no one else must modify it.
4286 Rp res = this->continuation(boost::move(this->parent));
4288 // make sure parent is really cleared to prevent memory "leaks"
4293 this->mark_finished_with_result_internal(boost::move(res), lck);
4295 this->mark_exceptional_finish_internal(current_exception(), lck);
4297 // make sure parent is really cleared to prevent memory "leaks"
4298 relocker relock(lck);
4303 static void run(shared_ptr<boost::detail::shared_state_base> that_)
4305 continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
4309 ~continuation_shared_state() {}
4312 template<typename F, typename Fp, class ShSt>
4313 struct continuation_shared_state<F, void, Fp, ShSt>: ShSt
4319 continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4320 : parent(boost::move(f)),
4321 continuation(boost::move(c))
4325 void init(boost::unique_lock<boost::mutex> &lock)
4327 parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
4333 this->continuation(boost::move(this->parent));
4334 this->mark_finished_with_result();
4336 this->mark_exceptional_finish();
4338 // make sure parent is really cleared to prevent memory "leaks"
4342 void call(boost::unique_lock<boost::mutex>& lck) {
4345 relocker relock(lck);
4346 // neither continuation nor parent are protected by the lock - call() must only
4347 // be called once, and no one else must modify it.
4348 this->continuation(boost::move(this->parent));
4350 // make sure parent is really cleared to prevent memory "leaks"
4353 this->mark_finished_with_result_internal(lck);
4355 this->mark_exceptional_finish_internal(current_exception(), lck);
4357 // make sure parent is really cleared to prevent memory "leaks"
4358 relocker relock(lck);
4363 static void run(shared_ptr<boost::detail::shared_state_base> that_)
4365 continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
4369 ~continuation_shared_state() {}
4371 /////////////////////////
4372 /// future_async_continuation_shared_state
4373 /////////////////////////
4375 template<typename F, typename Rp, typename Fp>
4376 struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
4378 typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
4380 future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4381 : base_type(boost::move(f), boost::forward<Fp>(c))
4384 void launch_continuation() {
4385 #if defined BOOST_THREAD_FUTURE_BLOCKING
4386 boost::lock_guard<boost::mutex> lk(this->mutex);
4387 this->thr_ = boost::thread(&future_async_continuation_shared_state::run, static_shared_from_this(this));
4389 boost::thread(&base_type::run, static_shared_from_this(this)).detach();
4394 /////////////////////////
4395 /// future_sync_continuation_shared_state
4396 /////////////////////////
4398 template<typename F, typename Rp, typename Fp>
4399 struct future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
4401 typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
4403 future_sync_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4404 : base_type(boost::move(f), boost::forward<Fp>(c))
4407 void launch_continuation() {
4413 /////////////////////////
4414 /// future_executor_continuation_shared_state
4415 /////////////////////////
4416 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4418 template <typename FutureExecutorContinuationSharedState>
4420 shared_ptr<FutureExecutorContinuationSharedState> that_;
4422 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
4423 BOOST_THREAD_COPYABLE_AND_MOVABLE(run_it)
4424 run_it(run_it const& x) //BOOST_NOEXCEPT
4427 run_it& operator=(BOOST_THREAD_COPY_ASSIGN_REF(run_it) x) //BOOST_NOEXCEPT
4435 run_it(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT
4440 run_it& operator=(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT {
4448 run_it(shared_ptr<FutureExecutorContinuationSharedState> that) : that_ (that) {}
4457 BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::run_it<F> BOOST_THREAD_DCL_MOVABLE_END
4461 template<typename F, typename Rp, typename Fp>
4462 struct future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4464 typedef continuation_shared_state<F,Rp,Fp> base_type;
4467 future_executor_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4468 : base_type(boost::move(f), boost::forward<Fp>(c))
4473 void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
4475 this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
4476 this->base_type::init(lk);
4479 void launch_continuation() {
4480 run_it<base_type> fct(static_shared_from_this(this));
4481 this->get_executor()->submit(boost::move(fct));
4484 ~future_executor_continuation_shared_state() {}
4488 /////////////////////////
4489 /// shared_future_async_continuation_shared_state
4490 /////////////////////////
4492 template<typename F, typename Rp, typename Fp>
4493 struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
4495 typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
4498 shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4499 : base_type(boost::move(f), boost::forward<Fp>(c))
4503 void launch_continuation() {
4504 #if defined BOOST_THREAD_FUTURE_BLOCKING
4505 boost::lock_guard<boost::mutex> lk(this->mutex);
4506 this->thr_ = boost::thread(&base_type::run, static_shared_from_this(this));
4508 boost::thread(&base_type::run, static_shared_from_this(this)).detach();
4513 /////////////////////////
4514 /// shared_future_async_continuation_shared_state
4515 /////////////////////////
4517 template<typename F, typename Rp, typename Fp>
4518 struct shared_future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
4520 typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
4523 shared_future_sync_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4524 : base_type(boost::move(f), boost::forward<Fp>(c))
4528 void launch_continuation() {
4534 /////////////////////////
4535 /// shared_future_executor_continuation_shared_state
4536 /////////////////////////
4537 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4539 template<typename F, typename Rp, typename Fp>
4540 struct shared_future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4542 typedef continuation_shared_state<F,Rp,Fp> base_type;
4546 shared_future_executor_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4547 : base_type(boost::move(f), boost::forward<Fp>(c))
4552 void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
4554 this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
4555 this->base_type::init(lk);
4558 void launch_continuation() {
4559 run_it<base_type> fct(static_shared_from_this(this));
4560 this->get_executor()->submit(boost::move(fct));
4563 ~shared_future_executor_continuation_shared_state() {}
4567 //////////////////////////
4568 /// future_deferred_continuation_shared_state
4569 //////////////////////////
4570 template<typename F, typename Rp, typename Fp>
4571 struct future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4573 typedef continuation_shared_state<F,Rp,Fp> base_type;
4575 future_deferred_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))
4578 this->set_deferred();
4581 virtual void execute(boost::unique_lock<boost::mutex>& lk) {
4582 this->parent.wait();
4586 virtual void launch_continuation() { }
4589 //////////////////////////
4590 /// shared_future_deferred_continuation_shared_state
4591 //////////////////////////
4592 template<typename F, typename Rp, typename Fp>
4593 struct shared_future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
4595 typedef continuation_shared_state<F,Rp,Fp> base_type;
4598 shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4599 : base_type(boost::move(f), boost::forward<Fp>(c))
4601 this->set_deferred();
4604 virtual void execute(boost::unique_lock<boost::mutex>& lk) {
4605 this->parent.wait();
4609 virtual void launch_continuation() { }
4612 ////////////////////////////////
4613 // make_future_deferred_continuation_shared_state
4614 ////////////////////////////////
4615 template<typename F, typename Rp, typename Fp>
4616 BOOST_THREAD_FUTURE<Rp>
4617 make_future_deferred_continuation_shared_state(
4618 boost::unique_lock<boost::mutex> &lock,
4619 BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c) {
4620 typedef typename decay<Fp>::type Cont;
4621 shared_ptr<future_deferred_continuation_shared_state<F, Rp, Cont> >
4622 h(new future_deferred_continuation_shared_state<F, Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4624 return BOOST_THREAD_FUTURE<Rp>(h);
4627 ////////////////////////////////
4628 // make_future_async_continuation_shared_state
4629 ////////////////////////////////
4630 template<typename F, typename Rp, typename Fp>
4631 BOOST_THREAD_FUTURE<Rp>
4632 make_future_async_continuation_shared_state(
4633 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4634 BOOST_THREAD_FWD_REF(Fp) c) {
4635 typedef typename decay<Fp>::type Cont;
4636 shared_ptr<future_async_continuation_shared_state<F,Rp, Cont> >
4637 h(new future_async_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4640 return BOOST_THREAD_FUTURE<Rp>(h);
4642 ////////////////////////////////
4643 // make_future_sync_continuation_shared_state
4644 ////////////////////////////////
4645 template<typename F, typename Rp, typename Fp>
4646 BOOST_THREAD_FUTURE<Rp>
4647 make_future_sync_continuation_shared_state(
4648 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4649 BOOST_THREAD_FWD_REF(Fp) c) {
4650 typedef typename decay<Fp>::type Cont;
4651 shared_ptr<future_sync_continuation_shared_state<F,Rp, Cont> >
4652 h(new future_sync_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4655 return BOOST_THREAD_FUTURE<Rp>(h);
4658 ////////////////////////////////
4659 // make_future_executor_continuation_shared_state
4660 ////////////////////////////////
4661 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4663 template<typename Ex, typename F, typename Rp, typename Fp>
4664 BOOST_THREAD_FUTURE<Rp>
4665 make_future_executor_continuation_shared_state(Ex& ex,
4666 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4667 BOOST_THREAD_FWD_REF(Fp) c) {
4668 typedef typename decay<Fp>::type Cont;
4669 shared_ptr<future_executor_continuation_shared_state<F,Rp, Cont> >
4670 h(new future_executor_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
4673 return BOOST_THREAD_FUTURE<Rp>(h);
4677 ////////////////////////////////
4678 // make_shared_future_deferred_continuation_shared_state
4679 ////////////////////////////////
4680 template<typename F, typename Rp, typename Fp>
4681 BOOST_THREAD_FUTURE<Rp>
4682 make_shared_future_deferred_continuation_shared_state(
4683 boost::unique_lock<boost::mutex> &lock,
4684 F f, BOOST_THREAD_FWD_REF(Fp) c) {
4685 typedef typename decay<Fp>::type Cont;
4686 shared_ptr<shared_future_deferred_continuation_shared_state<F, Rp, Cont> >
4687 h(new shared_future_deferred_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
4690 return BOOST_THREAD_FUTURE<Rp>(h);
4692 ////////////////////////////////
4693 // make_shared_future_async_continuation_shared_state
4694 ////////////////////////////////
4695 template<typename F, typename Rp, typename Fp>
4696 BOOST_THREAD_FUTURE<Rp>
4697 make_shared_future_async_continuation_shared_state(
4698 boost::unique_lock<boost::mutex> &lock, F f,
4699 BOOST_THREAD_FWD_REF(Fp) c) {
4700 typedef typename decay<Fp>::type Cont;
4701 shared_ptr<shared_future_async_continuation_shared_state<F,Rp, Cont> >
4702 h(new shared_future_async_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
4705 return BOOST_THREAD_FUTURE<Rp>(h);
4707 ////////////////////////////////
4708 // make_shared_future_sync_continuation_shared_state
4709 ////////////////////////////////
4710 template<typename F, typename Rp, typename Fp>
4711 BOOST_THREAD_FUTURE<Rp>
4712 make_shared_future_sync_continuation_shared_state(
4713 boost::unique_lock<boost::mutex> &lock, F f,
4714 BOOST_THREAD_FWD_REF(Fp) c) {
4715 typedef typename decay<Fp>::type Cont;
4716 shared_ptr<shared_future_sync_continuation_shared_state<F,Rp, Cont> >
4717 h(new shared_future_sync_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
4720 return BOOST_THREAD_FUTURE<Rp>(h);
4722 ////////////////////////////////
4723 // make_shared_future_executor_continuation_shared_state
4724 ////////////////////////////////
4725 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4726 template<typename Ex, typename F, typename Rp, typename Fp>
4727 BOOST_THREAD_FUTURE<Rp>
4728 make_shared_future_executor_continuation_shared_state(Ex& ex,
4729 boost::unique_lock<boost::mutex> &lock, F f,
4730 BOOST_THREAD_FWD_REF(Fp) c) {
4731 typedef typename decay<Fp>::type Cont;
4732 shared_ptr<shared_future_executor_continuation_shared_state<F, Rp, Cont> >
4733 h(new shared_future_executor_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
4736 return BOOST_THREAD_FUTURE<Rp>(h);
4741 ////////////////////////////////
4742 // template<typename F>
4743 // auto future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4744 ////////////////////////////////
4745 template <typename R>
4746 template <typename F>
4747 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4748 BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
4749 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4750 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4752 // keep state alive as we move ourself but hold the lock
4753 shared_ptr<detail::shared_state_base> sentinel(this->future_);
4754 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
4756 if (underlying_cast<int>(policy) & int(launch::async)) {
4757 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4758 lock, boost::move(*this), boost::forward<F>(func)
4760 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
4761 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4762 lock, boost::move(*this), boost::forward<F>(func)
4764 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4765 } else if (underlying_cast<int>(policy) & int(launch::executor)) {
4766 assert(this->future_->get_executor());
4767 typedef executor Ex;
4768 Ex& ex = *(this->future_->get_executor());
4769 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
4770 lock, boost::move(*this), boost::forward<F>(func)
4773 } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
4775 launch policy_ = this->launch_policy(lock);
4776 if (underlying_cast<int>(policy_) & int(launch::async)) {
4777 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4778 lock, boost::move(*this), boost::forward<F>(func)
4780 } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
4781 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4782 lock, boost::move(*this), boost::forward<F>(func)
4784 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4785 } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
4786 assert(this->future_->get_executor());
4787 typedef executor Ex;
4788 Ex& ex = *(this->future_->get_executor());
4789 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
4790 lock, boost::move(*this), boost::forward<F>(func)
4794 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4795 lock, boost::move(*this), boost::forward<F>(func)
4799 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4800 lock, boost::move(*this), boost::forward<F>(func)
4804 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4805 ////////////////////////////////
4806 // template<typename Ex, typename F>
4807 // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4808 ////////////////////////////////
4809 template <typename R>
4810 template <typename Ex, typename F>
4811 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4812 BOOST_THREAD_FUTURE<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
4813 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4814 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4816 // keep state alive as we move ourself but hold the lock
4817 shared_ptr<detail::shared_state_base> sentinel(this->future_);
4818 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
4820 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
4821 lock, boost::move(*this), boost::forward<F>(func)
4825 ////////////////////////////////
4826 // template<typename F>
4827 // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4828 ////////////////////////////////
4829 template <typename R>
4830 template <typename F>
4831 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4832 BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func) {
4834 #ifndef BOOST_THREAD_CONTINUATION_SYNC
4835 return this->then(this->launch_policy(), boost::forward<F>(func));
4837 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4838 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4840 // keep state alive as we move ourself but hold the lock
4841 shared_ptr<detail::shared_state_base> sentinel(this->future_);
4842 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
4844 launch policy = this->launch_policy(lock);
4845 if (underlying_cast<int>(policy) & int(launch::deferred)) {
4846 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4847 lock, boost::move(*this), boost::forward<F>(func)
4850 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4851 lock, boost::move(*this), boost::forward<F>(func)
4858 ////////////////////////////////
4859 // template<typename F>
4860 // auto future<future<R2> >::then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4861 ////////////////////////////////
4862 template <typename R2>
4863 template <typename F>
4864 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
4865 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
4866 typedef BOOST_THREAD_FUTURE<R2> R;
4867 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4868 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4870 // keep state alive as we move ourself but hold the lock
4871 shared_ptr<detail::shared_state_base> sentinel(this->future_);
4872 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
4874 if (underlying_cast<int>(policy) & int(launch::async)) {
4875 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4876 lock, boost::move(*this), boost::forward<F>(func)
4878 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
4879 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4880 lock, boost::move(*this), boost::forward<F>(func)
4882 } else if (underlying_cast<int>(policy) & int(launch::sync)) {
4883 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4884 lock, boost::move(*this), boost::forward<F>(func)
4886 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4887 } else if (underlying_cast<int>(policy) & int(launch::executor)) {
4888 assert(this->future_->get_executor());
4889 typedef executor Ex;
4890 Ex& ex = *(this->future_->get_executor());
4891 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
4892 lock, boost::move(*this), boost::forward<F>(func)
4895 } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
4896 launch policy_ = this->launch_policy(lock);
4898 if (underlying_cast<int>(policy_) & int(launch::async)) {
4899 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4900 lock, boost::move(*this), boost::forward<F>(func)
4902 } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
4903 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4904 lock, boost::move(*this), boost::forward<F>(func)
4906 } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
4907 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4908 lock, boost::move(*this), boost::forward<F>(func)
4910 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4911 } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
4912 assert(this->future_->get_executor());
4913 typedef executor Ex;
4914 Ex& ex = *(this->future_->get_executor());
4915 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
4916 lock, boost::move(*this), boost::forward<F>(func)
4920 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4921 lock, boost::move(*this), boost::forward<F>(func)
4925 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4926 lock, boost::move(*this), boost::forward<F>(func)
4931 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4932 ////////////////////////////////
4933 // template<typename Ex, typename F>
4934 // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4935 ////////////////////////////////
4936 template <typename R2>
4937 template <typename Ex, typename F>
4938 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
4939 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
4940 typedef BOOST_THREAD_FUTURE<R2> R;
4941 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4942 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4944 // keep state alive as we move ourself but hold the lock
4945 shared_ptr<detail::shared_state_base> sentinel(this->future_);
4946 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
4948 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
4949 lock, boost::move(*this), boost::forward<F>(func)
4954 ////////////////////////////////
4955 // template<typename F>
4956 // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4957 ////////////////////////////////
4958 template <typename R2>
4959 template <typename F>
4960 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
4961 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(BOOST_THREAD_FWD_REF(F) func) {
4963 #ifndef BOOST_THREAD_CONTINUATION_SYNC
4964 return this->then(this->launch_policy(), boost::forward<F>(func));
4966 typedef BOOST_THREAD_FUTURE<R2> R;
4967 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4968 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4970 // keep state alive as we move ourself but hold the lock
4971 shared_ptr<detail::shared_state_base> sentinel(this->future_);
4972 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
4974 launch policy = this->launch_policy(lock);
4976 if (underlying_cast<int>(policy) & int(launch::deferred)) {
4977 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4978 lock, boost::move(*this), boost::forward<F>(func)
4981 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
4982 lock, boost::move(*this), boost::forward<F>(func)
4988 ////////////////////////////////
4989 // template<typename F>
4990 // auto shared_future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4991 ////////////////////////////////
4992 template <typename R>
4993 template <typename F>
4994 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
4995 shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) const
4997 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
4998 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
5000 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5001 if (underlying_cast<int>(policy) & int(launch::async)) {
5002 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5003 lock, *this, boost::forward<F>(func)
5005 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
5006 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5007 lock, *this, boost::forward<F>(func)
5009 } else if (underlying_cast<int>(policy) & int(launch::sync)) {
5010 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5011 lock, *this, boost::forward<F>(func)
5013 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5014 } else if (underlying_cast<int>(policy) & int(launch::executor)) {
5015 typedef executor Ex;
5016 Ex& ex = *(this->future_->get_executor());
5017 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5018 lock, *this, boost::forward<F>(func)
5021 } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
5023 launch policy_ = this->launch_policy(lock);
5024 if (underlying_cast<int>(policy_) & int(launch::async)) {
5025 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5026 lock, *this, boost::forward<F>(func)
5028 } else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
5029 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5030 lock, *this, boost::forward<F>(func)
5032 } else if (underlying_cast<int>(policy_) & int(launch::sync)) {
5033 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5034 lock, *this, boost::forward<F>(func)
5036 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5037 } else if (underlying_cast<int>(policy_) & int(launch::executor)) {
5038 typedef executor Ex;
5039 Ex& ex = *(this->future_->get_executor());
5040 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5041 lock, *this, boost::forward<F>(func)
5045 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5046 lock, *this, boost::forward<F>(func)
5051 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
5052 lock, *this, boost::forward<F>(func)
5056 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
5057 ////////////////////////////////
5058 // template<typename Ex, typename F>
5059 // auto shared_future<R>::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5060 ////////////////////////////////
5061 template <typename R>
5062 template <typename Ex, typename F>
5063 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5064 shared_future<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const
5066 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5067 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
5069 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5070 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
5071 lock, *this, boost::forward<F>(func)
5076 ////////////////////////////////
5077 // template<typename F>
5078 // auto shared_future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
5079 ////////////////////////////////
5080 template <typename R>
5081 template <typename F>
5082 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
5083 shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func) const {
5084 #ifndef BOOST_THREAD_CONTINUATION_SYNC
5085 return this->then(this->launch_policy(), boost::forward<F>(func));
5087 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
5088 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
5090 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
5091 launch policy = this->launch_policy(lock);
5092 if (underlying_cast<int>(policy) & int(launch::deferred)) {
5093 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
5094 lock, *this, boost::forward<F>(func)
5097 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
5098 lock, *this, boost::forward<F>(func)
5106 template <typename T>
5107 struct mfallbacker_to
5110 typedef T result_type;
5111 mfallbacker_to(BOOST_THREAD_RV_REF(T) v)
5112 : value_(boost::move(v))
5115 T operator()(BOOST_THREAD_FUTURE<T> fut) {
5116 return fut.get_or(boost::move(value_));
5119 template <typename T>
5120 struct cfallbacker_to
5123 typedef T result_type;
5124 cfallbacker_to(T const& v)
5128 T operator()(BOOST_THREAD_FUTURE<T> fut) const {
5129 return fut.get_or(value_);
5134 ////////////////////////////////
5135 // future<R> future<R>::fallback_to(R&& v);
5136 ////////////////////////////////
5138 template <typename R>
5139 template <typename R2>
5140 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
5141 BOOST_THREAD_FUTURE<R>::fallback_to(BOOST_THREAD_RV_REF(R2) v) {
5142 return then(detail::mfallbacker_to<R>(boost::move(v)));
5145 template <typename R>
5146 template <typename R2>
5147 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
5148 BOOST_THREAD_FUTURE<R>::fallback_to(R2 const& v) {
5149 return then(detail::cfallbacker_to<R>(v));
5154 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
5157 /////////////////////////
5158 /// future_unwrap_shared_state
5159 /////////////////////////
5161 template<typename F, typename Rp>
5162 struct future_unwrap_shared_state: shared_state<Rp>
5165 typename F::value_type unwrapped;
5167 explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
5168 : wrapped(boost::move(f)) {
5171 void launch_continuation()
5173 boost::unique_lock<boost::mutex> lk(this->mutex);
5174 // assert(wrapped.is_ready());
5175 if (! unwrapped.valid() )
5177 if (wrapped.has_exception()) {
5178 this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
5180 unwrapped = wrapped.get();
5181 if (unwrapped.valid())
5184 boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
5185 unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
5187 this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
5191 // assert(unwrapped.is_ready());
5192 if (unwrapped.has_exception()) {
5193 this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
5195 this->mark_finished_with_result_internal(unwrapped.get(), lk);
5201 template<typename F>
5202 struct future_unwrap_shared_state<F,void>: shared_state<void>
5205 typename F::value_type unwrapped;
5207 explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
5208 : wrapped(boost::move(f)) {
5211 void launch_continuation()
5213 boost::unique_lock<boost::mutex> lk(this->mutex);
5214 // assert(wrapped.is_ready());
5215 if (! unwrapped.valid() )
5217 if (wrapped.has_exception()) {
5218 this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
5220 unwrapped = wrapped.get();
5221 if (unwrapped.valid())
5224 boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
5225 unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
5227 this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
5231 // assert(unwrapped.is_ready());
5232 if (unwrapped.has_exception()) {
5233 this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
5235 this->mark_finished_with_result_internal(lk);
5241 template <class F, class Rp>
5242 BOOST_THREAD_FUTURE<Rp>
5243 make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f) {
5244 shared_ptr<future_unwrap_shared_state<F, Rp> >
5245 h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
5246 h->wrapped.future_->set_continuation_ptr(h, lock);
5248 return BOOST_THREAD_FUTURE<Rp>(h);
5252 template <typename R>
5253 inline BOOST_THREAD_FUTURE<R>::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other)
5254 : base_type(other.unwrap()) {}
5256 template <typename R2>
5257 BOOST_THREAD_FUTURE<R2>
5258 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
5260 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
5262 // keep state alive as we move ourself but hold the lock
5263 shared_ptr<detail::shared_state_base> sentinel(this->future_);
5264 boost::unique_lock<boost::mutex> lock(sentinel->mutex);
5266 return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
5270 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
5273 struct input_iterator_tag {};
5274 struct vector_tag {};
5275 struct values_tag {};
5276 template <typename T>
5277 struct alias_t { typedef T type; };
5279 BOOST_CONSTEXPR_OR_CONST input_iterator_tag input_iterator_tag_value = {};
5280 BOOST_CONSTEXPR_OR_CONST vector_tag vector_tag_value = {};
5281 BOOST_CONSTEXPR_OR_CONST values_tag values_tag_value = {};
5282 ////////////////////////////////
5283 // detail::future_async_when_all_shared_state
5284 ////////////////////////////////
5285 template<typename F>
5286 struct future_when_all_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
5288 typedef csbl::vector<F> vector_type;
5289 typedef typename F::value_type value_type;
5292 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
5293 future_when_all_vector_shared_state* that = static_cast<future_when_all_vector_shared_state*>(that_.get());
5295 boost::wait_for_all(that->vec_.begin(), that->vec_.end());
5296 that->mark_finished_with_result(boost::move(that->vec_));
5298 that->mark_exceptional_finish();
5301 bool run_deferred() {
5304 for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
5305 if (! it->run_if_is_deferred())
5313 if (! run_deferred())
5315 future_when_all_vector_shared_state::run(this->shared_from_this());
5318 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5319 this->thr_ = boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this());
5321 boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this()).detach();
5326 template< typename InputIterator>
5327 future_when_all_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
5328 : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
5332 future_when_all_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
5333 : vec_(boost::move(v))
5337 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5338 template< typename T0, typename ...T>
5339 future_when_all_vector_shared_state(values_tag, BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5340 vec_.push_back(boost::forward<T0>(f));
5341 typename alias_t<char[]>::type{
5342 ( //first part of magic unpacker
5343 vec_.push_back(boost::forward<T>(futures)),'0'
5345 }; //second part of magic unpacker
5349 ~future_when_all_vector_shared_state() {}
5352 ////////////////////////////////
5353 // detail::future_async_when_any_shared_state
5354 ////////////////////////////////
5355 template<typename F>
5356 struct future_when_any_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
5358 typedef csbl::vector<F> vector_type;
5359 typedef typename F::value_type value_type;
5362 static void run(shared_ptr<boost::detail::shared_state_base> that_)
5364 future_when_any_vector_shared_state* that = static_cast<future_when_any_vector_shared_state*>(that_.get());
5366 boost::wait_for_any(that->vec_.begin(), that->vec_.end());
5367 that->mark_finished_with_result(boost::move(that->vec_));
5369 that->mark_exceptional_finish();
5372 bool run_deferred() {
5374 for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
5375 if (it->run_if_is_deferred_or_ready())
5385 future_when_any_vector_shared_state::run(this->shared_from_this());
5389 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5390 this->thr_ = boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this());
5392 boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this()).detach();
5397 template< typename InputIterator>
5398 future_when_any_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
5399 : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
5403 future_when_any_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
5404 : vec_(boost::move(v))
5408 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5409 template< typename T0, typename ...T>
5410 future_when_any_vector_shared_state(values_tag,
5411 BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures
5413 vec_.push_back(boost::forward<T0>(f));
5414 typename alias_t<char[]>::type{
5415 ( //first part of magic unpacker
5416 vec_.push_back(boost::forward<T>(futures))
5420 }; //second part of magic unpacker
5424 ~future_when_any_vector_shared_state() {}
5427 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5428 struct wait_for_all_fctr {
5429 template <class ...T>
5430 void operator()(T&&... v) {
5431 boost::wait_for_all(boost::forward<T>(v)...);
5435 struct wait_for_any_fctr {
5436 template <class ...T>
5437 void operator()(T&&... v) {
5438 boost::wait_for_any(boost::forward<T>(v)...);
5443 template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5444 struct accumulate_run_if_is_deferred {
5445 bool operator ()(Tuple& t)
5447 return (! csbl::get<i-1>(t).run_if_is_deferred()) || accumulate_run_if_is_deferred<Tuple,i-1>()(t);
5450 template <class Tuple>
5451 struct accumulate_run_if_is_deferred<Tuple, 0> {
5452 bool operator ()(Tuple& )
5459 template< typename Tuple, typename T0, typename ...T>
5460 struct future_when_all_tuple_shared_state: future_async_shared_state_base<Tuple>
5463 typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5465 static void run(shared_ptr<boost::detail::shared_state_base> that_) {
5466 future_when_all_tuple_shared_state* that = static_cast<future_when_all_tuple_shared_state*>(that_.get());
5468 // TODO make use of apply(that->tup_, boost::detail::wait_for_all_fctor());
5469 that->wait_for_all(Index());
5471 that->mark_finished_with_result(boost::move(that->tup_));
5473 that->mark_exceptional_finish();
5477 template <size_t ...Indices>
5478 void wait_for_all(tuple_indices<Indices...>) {
5479 #if defined BOOST_THREAD_PROVIDES_INVOKE
5480 return invoke<void>(wait_for_all_fctr(), csbl::get<Indices>(tup_)...);
5482 return wait_for_all_fctr()(csbl::get<Indices>(tup_)...);
5486 bool run_deferred() {
5488 return accumulate_run_if_is_deferred<Tuple>()(tup_);
5491 if (! run_deferred())
5493 future_when_all_tuple_shared_state::run(this->shared_from_this());
5496 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5497 this->thr_ = boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this());
5499 boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this()).detach();
5504 template< typename F, typename ...Fs>
5505 future_when_all_tuple_shared_state(values_tag, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures) :
5506 tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5510 ~future_when_all_tuple_shared_state() {}
5515 template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5516 struct apply_any_run_if_is_deferred_or_ready {
5517 bool operator ()(Tuple& t)
5519 if (csbl::get<i-1>(t).run_if_is_deferred_or_ready()) return true;
5520 return apply_any_run_if_is_deferred_or_ready<Tuple,i-1>()(t);
5523 template <class Tuple>
5524 struct apply_any_run_if_is_deferred_or_ready<Tuple, 0> {
5525 bool operator ()(Tuple& )
5531 template< typename Tuple, typename T0, typename ...T >
5532 struct future_when_any_tuple_shared_state: future_async_shared_state_base<Tuple>
5535 typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5537 static void run(shared_ptr<boost::detail::shared_state_base> that_)
5539 future_when_any_tuple_shared_state* that = static_cast<future_when_any_tuple_shared_state*>(that_.get());
5541 // TODO make use of apply(that->tup_, wait_for_any_fctr);
5542 that->wait_for_any(Index());
5544 that->mark_finished_with_result(boost::move(that->tup_));
5546 that->mark_exceptional_finish();
5549 template <size_t ...Indices>
5550 void wait_for_any(tuple_indices<Indices...>) {
5551 #if defined BOOST_THREAD_PROVIDES_INVOKE
5552 return invoke<void>(wait_for_any_fctr(), csbl::get<Indices>(tup_)...);
5554 return wait_for_any_fctr()(csbl::get<Indices>(tup_)...);
5557 bool run_deferred() {
5558 return apply_any_run_if_is_deferred_or_ready<Tuple>()(tup_);
5563 future_when_any_tuple_shared_state::run(this->shared_from_this());
5567 #ifdef BOOST_THREAD_FUTURE_BLOCKING
5568 this->thr_ = boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this());
5570 boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this()).detach();
5575 template< typename F, typename ...Fs>
5576 future_when_any_tuple_shared_state(values_tag,
5577 BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures
5579 tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5583 ~future_when_any_tuple_shared_state() {}
5589 template< typename InputIterator>
5590 typename boost::disable_if<is_future_type<InputIterator>,
5591 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
5593 when_all(InputIterator first, InputIterator last) {
5594 typedef typename InputIterator::value_type value_type;
5595 typedef csbl::vector<value_type> container_type;
5596 typedef detail::future_when_all_vector_shared_state<value_type> factory_type;
5598 if (first==last) return make_ready_future(container_type());
5599 shared_ptr<factory_type >
5600 h(new factory_type(detail::input_iterator_tag_value, first,last));
5602 return BOOST_THREAD_FUTURE<container_type>(h);
5605 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all() {
5606 return make_ready_future(csbl::tuple<>());
5609 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5610 template< typename T0, typename ...T>
5611 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5612 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5613 typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5614 typedef detail::future_when_all_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5616 shared_ptr<factory_type>
5617 h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5619 return BOOST_THREAD_FUTURE<container_type>(h);
5623 template< typename InputIterator>
5624 typename boost::disable_if<is_future_type<InputIterator>,
5625 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
5627 when_any(InputIterator first, InputIterator last) {
5628 typedef typename InputIterator::value_type value_type;
5629 typedef csbl::vector<value_type> container_type;
5630 typedef detail::future_when_any_vector_shared_state<value_type> factory_type;
5632 if (first==last) return make_ready_future(container_type());
5633 shared_ptr<factory_type >
5634 h(new factory_type(detail::input_iterator_tag_value, first,last));
5636 return BOOST_THREAD_FUTURE<container_type>(h);
5639 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any() {
5640 return make_ready_future(csbl::tuple<>());
5643 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5644 template< typename T0, typename ...T>
5645 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5646 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5647 typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5648 typedef detail::future_when_any_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5650 shared_ptr<factory_type>
5651 h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5653 return BOOST_THREAD_FUTURE<container_type>(h);
5656 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
5659 #endif // BOOST_NO_EXCEPTION