1 // (C) Copyright 2008-10 Anthony Williams
2 // (C) Copyright 2011-2014 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 #ifndef BOOST_NO_EXCEPTIONS
18 #include <boost/core/scoped_enum.hpp>
21 #include <boost/thread/exceptional_ptr.hpp>
22 #include <boost/thread/detail/move.hpp>
23 #include <boost/thread/detail/invoker.hpp>
24 #include <boost/thread/detail/invoke.hpp>
25 #include <boost/thread/thread_time.hpp>
26 #include <boost/thread/mutex.hpp>
27 #include <boost/thread/condition_variable.hpp>
28 #include <boost/thread/lock_algorithms.hpp>
29 #include <boost/thread/lock_types.hpp>
30 #include <boost/exception_ptr.hpp>
31 #include <boost/shared_ptr.hpp>
32 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
33 #include <boost/optional.hpp>
35 #include <boost/thread/csbl/memory/unique_ptr.hpp>
36 //#include <boost/move/make_unique.hpp>
38 #include <boost/type_traits/is_fundamental.hpp>
39 #include <boost/thread/detail/is_convertible.hpp>
40 #include <boost/type_traits/decay.hpp>
41 #include <boost/type_traits/is_void.hpp>
42 #include <boost/type_traits/conditional.hpp>
43 #include <boost/config.hpp>
44 #include <boost/throw_exception.hpp>
46 #include <boost/function.hpp>
47 #include <boost/bind.hpp>
48 #include <boost/core/ref.hpp>
49 #include <boost/scoped_array.hpp>
50 #include <boost/enable_shared_from_this.hpp>
51 #include <boost/core/enable_if.hpp>
54 #include <boost/next_prior.hpp>
57 #include <boost/thread/future_error_code.hpp>
58 #ifdef BOOST_THREAD_USES_CHRONO
59 #include <boost/chrono/system_clocks.hpp>
62 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
63 #include <boost/thread/detail/memory.hpp>
64 #include <boost/container/scoped_allocator.hpp>
65 #if ! defined BOOST_NO_CXX11_ALLOCATOR
70 #include <boost/utility/result_of.hpp>
71 #include <boost/thread/thread_only.hpp>
73 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
74 #include <boost/thread/csbl/tuple.hpp>
75 #include <boost/thread/csbl/vector.hpp>
78 #if defined BOOST_THREAD_PROVIDES_FUTURE
79 #define BOOST_THREAD_FUTURE future
81 #define BOOST_THREAD_FUTURE unique_future
88 BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
93 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
96 any = async | deferred
98 BOOST_SCOPED_ENUM_DECLARE_END(launch)
100 //enum class future_status
101 BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
107 BOOST_SCOPED_ENUM_DECLARE_END(future_status)
109 class BOOST_SYMBOL_VISIBLE future_error
110 : public std::logic_error
112 system::error_code ec_;
114 future_error(system::error_code ec)
115 : logic_error(ec.message()),
120 const system::error_code& code() const BOOST_NOEXCEPT
126 class BOOST_SYMBOL_VISIBLE future_uninitialized:
130 future_uninitialized() :
131 future_error(system::make_error_code(future_errc::no_state))
134 class BOOST_SYMBOL_VISIBLE broken_promise:
139 future_error(system::make_error_code(future_errc::broken_promise))
142 class BOOST_SYMBOL_VISIBLE future_already_retrieved:
146 future_already_retrieved():
147 future_error(system::make_error_code(future_errc::future_already_retrieved))
150 class BOOST_SYMBOL_VISIBLE promise_already_satisfied:
154 promise_already_satisfied():
155 future_error(system::make_error_code(future_errc::promise_already_satisfied))
159 class BOOST_SYMBOL_VISIBLE task_already_started:
163 task_already_started():
164 future_error(system::make_error_code(future_errc::promise_already_satisfied))
168 class BOOST_SYMBOL_VISIBLE task_moved:
173 future_error(system::make_error_code(future_errc::no_state))
182 future_error(system::make_error_code(future_errc::no_state))
186 namespace future_state
188 enum state { uninitialized, waiting, ready, moved, deferred };
195 boost::unique_lock<boost::mutex>& lock_;
198 relocker(boost::unique_lock<boost::mutex>& lk):
217 relocker& operator=(relocker const&);
220 struct shared_state_base : enable_shared_from_this<shared_state_base>
222 typedef std::list<boost::condition_variable_any*> waiter_list;
223 // This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
224 typedef shared_ptr<shared_state_base> continuation_ptr_type;
226 boost::exception_ptr exception;
231 mutable boost::mutex mutex;
232 boost::condition_variable waiters;
233 waiter_list external_waiters;
234 boost::function<void()> callback;
235 // This declaration should be only included conditionally, but is included to maintain the same layout.
236 continuation_ptr_type continuation_ptr;
238 // This declaration should be only included conditionally, but is included to maintain the same layout.
239 virtual void launch_continuation(boost::unique_lock<boost::mutex>&)
246 policy_(launch::none),
247 is_constructed(false),
250 virtual ~shared_state_base()
256 policy_ = launch::deferred;
260 is_deferred_ = false;
261 policy_ = launch::async;
263 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
266 is_deferred_ = false;
267 policy_ = launch::executor;
270 waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
272 boost::unique_lock<boost::mutex> lock(this->mutex);
274 return external_waiters.insert(external_waiters.end(),&cv);
277 void remove_external_waiter(waiter_list::iterator it)
279 boost::lock_guard<boost::mutex> lock(this->mutex);
280 external_waiters.erase(it);
283 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
284 void do_continuation(boost::unique_lock<boost::mutex>& lock)
286 if (continuation_ptr) {
287 continuation_ptr_type this_continuation_ptr = continuation_ptr;
288 continuation_ptr.reset();
289 this_continuation_ptr->launch_continuation(lock);
293 void do_continuation(boost::unique_lock<boost::mutex>&)
297 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
298 void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
300 continuation_ptr= continuation;
302 do_continuation(lock);
306 void mark_finished_internal(boost::unique_lock<boost::mutex>& lock)
309 waiters.notify_all();
310 for(waiter_list::const_iterator it=external_waiters.begin(),
311 end=external_waiters.end();it!=end;++it)
315 do_continuation(lock);
319 boost::unique_lock<boost::mutex> lock(this->mutex);
320 mark_finished_internal(lock);
323 void do_callback(boost::unique_lock<boost::mutex>& lock)
325 if(callback && !done)
327 boost::function<void()> local_callback=callback;
328 relocker relock(lock);
333 virtual bool run_if_is_deferred()
335 boost::unique_lock<boost::mutex> lk(this->mutex);
345 virtual bool run_if_is_deferred_or_ready()
347 boost::unique_lock<boost::mutex> lk(this->mutex);
358 void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true)
370 if(rethrow && exception)
372 boost::rethrow_exception(exception);
376 virtual void wait(bool rethrow=true)
378 boost::unique_lock<boost::mutex> lock(this->mutex);
379 wait_internal(lock, rethrow);
382 #if defined BOOST_THREAD_USES_DATETIME
383 bool timed_wait_until(boost::system_time const& target_time)
385 boost::unique_lock<boost::mutex> lock(this->mutex);
392 bool const success=waiters.timed_wait(lock,target_time);
393 if(!success && !done)
401 #ifdef BOOST_THREAD_USES_CHRONO
403 template <class Clock, class Duration>
405 wait_until(const chrono::time_point<Clock, Duration>& abs_time)
407 boost::unique_lock<boost::mutex> lock(this->mutex);
409 return future_status::deferred;
413 cv_status const st=waiters.wait_until(lock,abs_time);
414 if(st==cv_status::timeout && !done)
416 return future_status::timeout;
419 return future_status::ready;
422 void mark_exceptional_finish_internal(boost::exception_ptr const& e, boost::unique_lock<boost::mutex>& lock)
425 mark_finished_internal(lock);
428 void mark_exceptional_finish()
430 boost::unique_lock<boost::mutex> lock(this->mutex);
431 mark_exceptional_finish_internal(boost::current_exception(), lock);
434 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
435 void mark_interrupted_finish()
437 boost::unique_lock<boost::mutex> lock(this->mutex);
438 exception = boost::copy_exception(boost::thread_interrupted());
439 mark_finished_internal(lock);
442 void set_interrupted_at_thread_exit()
444 unique_lock<boost::mutex> lk(this->mutex);
447 throw_exception(promise_already_satisfied());
449 exception = boost::copy_exception(boost::thread_interrupted());
450 this->is_constructed = true;
451 detail::make_ready_at_thread_exit(shared_from_this());
455 void set_exception_at_thread_exit(exception_ptr e)
457 unique_lock<boost::mutex> lk(this->mutex);
460 throw_exception(promise_already_satisfied());
463 this->is_constructed = true;
464 detail::make_ready_at_thread_exit(shared_from_this());
467 bool has_value() const
469 boost::lock_guard<boost::mutex> lock(this->mutex);
470 return done && ! exception;
473 bool has_value(unique_lock<boost::mutex>& ) const
475 return done && ! exception;
478 bool has_exception() const
480 boost::lock_guard<boost::mutex> lock(this->mutex);
481 return done && exception;
484 bool has_exception(unique_lock<boost::mutex>&) const
486 return done && exception;
489 bool is_deferred(boost::lock_guard<boost::mutex>&) const {
493 launch launch_policy(boost::unique_lock<boost::mutex>&) const
498 future_state::state get_state() const
500 boost::lock_guard<boost::mutex> guard(this->mutex);
503 return future_state::waiting;
507 return future_state::ready;
511 exception_ptr get_exception_ptr()
513 boost::unique_lock<boost::mutex> lock(this->mutex);
514 return get_exception_ptr(lock);
516 exception_ptr get_exception_ptr(boost::unique_lock<boost::mutex>& lock)
518 wait_internal(lock, false);
522 template<typename F,typename U>
523 void set_wait_callback(F f,U* u)
525 boost::lock_guard<boost::mutex> lock(this->mutex);
526 callback=boost::bind(f,boost::ref(*u));
529 virtual void execute(boost::unique_lock<boost::mutex>&) {}
532 shared_state_base(shared_state_base const&);
533 shared_state_base& operator=(shared_state_base const&);
536 // Used to create stand-alone futures
539 detail::shared_state_base
541 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
542 typedef boost::optional<T> storage_type;
544 typedef boost::csbl::unique_ptr<T> storage_type;
546 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
547 typedef T const& source_reference_type;
548 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
549 typedef T move_dest_type;
550 #elif defined BOOST_THREAD_USES_MOVE
551 typedef typename conditional<boost::is_fundamental<T>::value,T,T const&>::type source_reference_type;
552 typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
553 typedef T move_dest_type;
555 typedef T& source_reference_type;
556 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;
557 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;
560 typedef const T& shared_future_get_result_type;
571 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
573 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
576 result.reset(new T(result_));
578 this->mark_finished_internal(lock);
581 void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
583 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
584 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
585 result = boost::move(result_);
587 result.reset(new T(boost::move(result_)));
590 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
591 result = boost::move(result_);
593 result.reset(new T(static_cast<rvalue_source_type>(result_)));
596 this->mark_finished_internal(lock);
599 void mark_finished_with_result(source_reference_type result_)
601 boost::unique_lock<boost::mutex> lock(this->mutex);
602 this->mark_finished_with_result_internal(result_, lock);
605 void mark_finished_with_result(rvalue_source_type result_)
607 boost::unique_lock<boost::mutex> lock(this->mutex);
609 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
610 mark_finished_with_result_internal(boost::move(result_), lock);
612 mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
616 storage_type& get_storage(boost::unique_lock<boost::mutex>& lock)
621 virtual move_dest_type get()
623 boost::unique_lock<boost::mutex> lock(this->mutex);
624 return boost::move(*get_storage(lock));
627 virtual shared_future_get_result_type get_sh()
629 boost::unique_lock<boost::mutex> lock(this->mutex);
630 return *get_storage(lock);
633 void set_value_at_thread_exit(source_reference_type result_)
635 unique_lock<boost::mutex> lk(this->mutex);
636 if (this->has_value(lk))
638 throw_exception(promise_already_satisfied());
640 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
643 result.reset(new T(result_));
646 this->is_constructed = true;
647 detail::make_ready_at_thread_exit(shared_from_this());
649 void set_value_at_thread_exit(rvalue_source_type result_)
651 unique_lock<boost::mutex> lk(this->mutex);
652 if (this->has_value(lk))
653 throw_exception(promise_already_satisfied());
655 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
656 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
657 result = boost::move(result_);
659 result.reset(new T(boost::move(result_)));
662 #if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
663 result = boost::move(result_);
665 result.reset(new T(static_cast<rvalue_source_type>(result_)));
668 this->is_constructed = true;
669 detail::make_ready_at_thread_exit(shared_from_this());
673 shared_state(shared_state const&);
674 shared_state& operator=(shared_state const&);
678 struct shared_state<T&>:
679 detail::shared_state_base
681 typedef T* storage_type;
682 typedef T& source_reference_type;
683 typedef T& move_dest_type;
684 typedef T& shared_future_get_result_type;
696 void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
699 mark_finished_internal(lock);
702 void mark_finished_with_result(source_reference_type result_)
704 boost::unique_lock<boost::mutex> lock(this->mutex);
705 mark_finished_with_result_internal(result_, lock);
710 boost::unique_lock<boost::mutex> lock(this->mutex);
717 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 void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
749 mark_finished_internal(lock);
752 void mark_finished_with_result()
754 boost::unique_lock<boost::mutex> lock(this->mutex);
755 mark_finished_with_result_internal(lock);
760 boost::unique_lock<boost::mutex> lock(this->mutex);
761 this->wait_internal(lock);
764 virtual void get_sh()
766 boost::unique_lock<boost::mutex> lock(this->mutex);
767 this->wait_internal(lock);
770 void set_value_at_thread_exit()
772 unique_lock<boost::mutex> lk(this->mutex);
773 if (this->has_value(lk))
775 throw_exception(promise_already_satisfied());
777 this->is_constructed = true;
778 detail::make_ready_at_thread_exit(shared_from_this());
781 shared_state(shared_state const&);
782 shared_state& operator=(shared_state const&);
785 /////////////////////////
786 /// future_async_shared_state_base
787 /////////////////////////
788 template<typename Rp>
789 struct future_async_shared_state_base: shared_state<Rp>
791 typedef shared_state<Rp> base_type;
796 if (thr_.joinable()) thr_.join();
799 future_async_shared_state_base()
804 ~future_async_shared_state_base()
809 virtual void wait(bool rethrow)
812 this->base_type::wait(rethrow);
816 /////////////////////////
817 /// future_async_shared_state
818 /////////////////////////
819 template<typename Rp, typename Fp>
820 struct future_async_shared_state: future_async_shared_state_base<Rp>
822 explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
824 this->thr_ = thread(&future_async_shared_state::run, this, boost::forward<Fp>(f));
827 static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f)
831 that->mark_finished_with_result(f());
833 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
834 catch(thread_interrupted& )
836 that->mark_interrupted_finish();
841 that->mark_exceptional_finish();
846 template<typename Fp>
847 struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void>
849 explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
851 this->thr_ = thread(&future_async_shared_state::run, this, boost::move(f));
854 static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f)
859 that->mark_finished_with_result();
861 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
862 catch(thread_interrupted& )
864 that->mark_interrupted_finish();
869 that->mark_exceptional_finish();
874 template<typename Rp, typename Fp>
875 struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&>
877 explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
879 this->thr_ = thread(&future_async_shared_state::run, this, boost::move(f));
882 static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f)
886 that->mark_finished_with_result(f());
888 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
889 catch(thread_interrupted& )
891 that->mark_interrupted_finish();
896 that->mark_exceptional_finish();
901 //////////////////////////
902 /// future_deferred_shared_state
903 //////////////////////////
904 template<typename Rp, typename Fp>
905 struct future_deferred_shared_state: shared_state<Rp>
907 typedef shared_state<Rp> base_type;
911 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
912 : func_(boost::move(f))
914 this->set_deferred();
917 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
920 Fp local_fuct=boost::move(func_);
921 relocker relock(lck);
922 Rp res = local_fuct();
924 this->mark_finished_with_result_internal(boost::move(res), lck);
928 this->mark_exceptional_finish_internal(current_exception(), lck);
932 template<typename Rp, typename Fp>
933 struct future_deferred_shared_state<Rp&,Fp>: shared_state<Rp&>
935 typedef shared_state<Rp&> base_type;
939 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
940 : func_(boost::move(f))
942 this->set_deferred();
945 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
948 this->mark_finished_with_result_internal(func_(), lck);
952 this->mark_exceptional_finish_internal(current_exception(), lck);
957 template<typename Fp>
958 struct future_deferred_shared_state<void,Fp>: shared_state<void>
960 typedef shared_state<void> base_type;
964 explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
965 : func_(boost::move(f))
967 this->set_deferred();
970 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
973 Fp local_fuct=boost::move(func_);
974 relocker relock(lck);
977 this->mark_finished_with_result_internal(lck);
981 this->mark_exceptional_finish_internal(current_exception(), lck);
988 struct registered_waiter;
989 typedef std::vector<int>::size_type count_type;
991 struct registered_waiter
993 boost::shared_ptr<detail::shared_state_base> future_;
994 detail::shared_state_base::waiter_list::iterator wait_iterator;
997 registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
998 detail::shared_state_base::waiter_list::iterator wait_iterator_,
1000 future_(a_future),wait_iterator(wait_iterator_),index(index_)
1004 struct all_futures_lock
1007 typedef std::ptrdiff_t count_type_portable;
1009 typedef count_type count_type_portable;
1011 count_type_portable count;
1012 boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
1014 all_futures_lock(std::vector<registered_waiter>& futures):
1015 count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
1017 for(count_type_portable i=0;i<count;++i)
1019 locks[i]=BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(futures[i].future_->mutex));
1025 boost::lock(locks.get(),locks.get()+count);
1030 for(count_type_portable i=0;i<count;++i)
1037 boost::condition_variable_any cv;
1038 std::vector<registered_waiter> futures;
1039 count_type future_count;
1046 template<typename F>
1051 registered_waiter waiter(f.future_,f.future_->register_external_waiter(cv),future_count);
1053 futures.push_back(waiter);
1055 f.future_->remove_external_waiter(waiter.wait_iterator);
1062 #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1063 template<typename F1, typename... Fs>
1064 void add(F1& f1, Fs&... fs)
1066 add(f1); add(fs...);
1072 all_futures_lock lk(futures);
1075 for(count_type i=0;i<futures.size();++i)
1077 if(futures[i].future_->done)
1079 return futures[i].index;
1088 for(count_type i=0;i<futures.size();++i)
1090 futures[i].future_->remove_external_waiter(futures[i].wait_iterator);
1097 template <typename R>
1098 class BOOST_THREAD_FUTURE;
1100 template <typename R>
1101 class shared_future;
1103 template<typename T>
1104 struct is_future_type
1106 BOOST_STATIC_CONSTANT(bool, value=false);
1110 template<typename T>
1111 struct is_future_type<BOOST_THREAD_FUTURE<T> >
1113 BOOST_STATIC_CONSTANT(bool, value=true);
1117 template<typename T>
1118 struct is_future_type<shared_future<T> >
1120 BOOST_STATIC_CONSTANT(bool, value=true);
1124 template<typename Iterator>
1125 typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end)
1127 for(Iterator current=begin;current!=end;++current)
1133 #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1134 template<typename F1,typename F2>
1135 typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)
1141 template<typename F1,typename F2,typename F3>
1142 void wait_for_all(F1& f1,F2& f2,F3& f3)
1149 template<typename F1,typename F2,typename F3,typename F4>
1150 void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)
1158 template<typename F1,typename F2,typename F3,typename F4,typename F5>
1159 void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
1168 template<typename F1, typename... Fs>
1169 void wait_for_all(F1& f1, Fs&... fs)
1171 bool dummy[] = { (f1.wait(), true), (fs.wait(), true)... };
1173 // prevent unused parameter warning
1176 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1178 template<typename Iterator>
1179 typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
1184 detail::future_waiter waiter;
1185 for(Iterator current=begin;current!=end;++current)
1187 waiter.add(*current);
1189 return boost::next(begin,waiter.wait());
1192 #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
1193 template<typename F1,typename F2>
1194 typename boost::enable_if<is_future_type<F1>,unsigned>::type wait_for_any(F1& f1,F2& f2)
1196 detail::future_waiter waiter;
1199 return waiter.wait();
1202 template<typename F1,typename F2,typename F3>
1203 unsigned wait_for_any(F1& f1,F2& f2,F3& f3)
1205 detail::future_waiter waiter;
1209 return waiter.wait();
1212 template<typename F1,typename F2,typename F3,typename F4>
1213 unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
1215 detail::future_waiter waiter;
1220 return waiter.wait();
1223 template<typename F1,typename F2,typename F3,typename F4,typename F5>
1224 unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
1226 detail::future_waiter waiter;
1232 return waiter.wait();
1235 template<typename F1, typename... Fs>
1236 typename boost::enable_if<is_future_type<F1>, unsigned>::type wait_for_any(F1& f1, Fs&... fs)
1238 detail::future_waiter waiter;
1239 waiter.add(f1, fs...);
1240 return waiter.wait();
1242 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1244 template <typename R>
1247 template <typename R>
1248 class packaged_task;
1252 /// Common implementation for all the futures independently of the return type
1256 /// Common implementation for future and shared_future.
1257 template <typename R>
1258 class basic_future : public base_future
1263 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
1264 typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
1266 static //BOOST_CONSTEXPR
1267 future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
1269 p.set_exception(ex.ptr_);
1270 return p.get_future().future_;
1273 void set_exceptional_if_invalid() {
1274 if (valid()) return;
1276 p.set_exception(future_uninitialized());
1277 future_ = p.get_future().future_;
1283 basic_future(future_ptr a_future):
1287 // Copy construction from a shared_future
1288 explicit basic_future(const shared_future<R>&) BOOST_NOEXCEPT;
1291 typedef future_state::state state;
1293 BOOST_THREAD_MOVABLE_ONLY(basic_future)
1294 basic_future(): future_() {}
1298 basic_future(exceptional_ptr const& ex)
1299 : future_(make_exceptional_future_ptr(ex))
1305 basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
1306 future_(BOOST_THREAD_RV(other).future_)
1308 BOOST_THREAD_RV(other).future_.reset();
1310 basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
1312 future_=BOOST_THREAD_RV(other).future_;
1313 BOOST_THREAD_RV(other).future_.reset();
1316 void swap(basic_future& that) BOOST_NOEXCEPT
1318 future_.swap(that.future_);
1320 // functions to check state, and wait for ready
1321 state get_state() const
1325 return future_state::uninitialized;
1327 return future_->get_state();
1330 bool is_ready() const
1332 return get_state()==future_state::ready;
1335 bool has_exception() const
1337 return future_ && future_->has_exception();
1340 bool has_value() const
1342 return future_ && future_->has_value();
1345 launch launch_policy(boost::unique_lock<boost::mutex>& lk) const
1347 if ( future_ ) return future_->launch_policy(lk);
1348 else return launch(launch::none);
1351 exception_ptr get_exception_ptr()
1354 ? future_->get_exception_ptr()
1358 bool valid() const BOOST_NOEXCEPT
1360 return future_ != 0;
1367 boost::throw_exception(future_uninitialized());
1369 future_->wait(false);
1372 #if defined BOOST_THREAD_USES_DATETIME
1373 template<typename Duration>
1374 bool timed_wait(Duration const& rel_time) const
1376 return timed_wait_until(boost::get_system_time()+rel_time);
1379 bool timed_wait_until(boost::system_time const& abs_time) const
1383 boost::throw_exception(future_uninitialized());
1385 return future_->timed_wait_until(abs_time);
1388 #ifdef BOOST_THREAD_USES_CHRONO
1389 template <class Rep, class Period>
1391 wait_for(const chrono::duration<Rep, Period>& rel_time) const
1393 return wait_until(chrono::steady_clock::now() + rel_time);
1396 template <class Clock, class Duration>
1398 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
1402 boost::throw_exception(future_uninitialized());
1404 return future_->wait_until(abs_time);
1411 BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END
1415 #if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005
1416 template <class Rp, class Fp>
1417 BOOST_THREAD_FUTURE<Rp>
1418 make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1420 template <class Rp, class Fp>
1421 BOOST_THREAD_FUTURE<Rp>
1422 make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1423 #endif // #if (!defined _MSC_VER || _MSC_VER >= 1400)
1424 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1425 template<typename F, typename Rp, typename Fp>
1426 struct future_deferred_continuation_shared_state;
1427 template<typename F, typename Rp, typename Fp>
1428 struct future_async_continuation_shared_state;
1430 template <class F, class Rp, class Fp>
1431 BOOST_THREAD_FUTURE<Rp>
1432 make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1434 template <class F, class Rp, class Fp>
1435 BOOST_THREAD_FUTURE<Rp>
1436 make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
1438 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1439 template<typename F, typename Rp>
1440 struct future_unwrap_shared_state;
1441 template <class F, class Rp>
1442 inline BOOST_THREAD_FUTURE<Rp>
1443 make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1447 template <typename R>
1448 class BOOST_THREAD_FUTURE : public detail::basic_future<R>
1451 typedef detail::basic_future<R> base_type;
1452 typedef typename base_type::future_ptr future_ptr;
1454 friend class shared_future<R>;
1455 friend class promise<R>;
1456 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1457 template <typename, typename, typename>
1458 friend struct detail::future_async_continuation_shared_state;
1459 template <typename, typename, typename>
1460 friend struct detail::future_deferred_continuation_shared_state;
1462 template <class F, class Rp, class Fp>
1463 friend BOOST_THREAD_FUTURE<Rp>
1464 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);
1466 template <class F, class Rp, class Fp>
1467 friend BOOST_THREAD_FUTURE<Rp>
1468 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);
1470 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1471 template<typename F, typename Rp>
1472 friend struct detail::future_unwrap_shared_state;
1473 template <class F, class Rp>
1474 friend BOOST_THREAD_FUTURE<Rp>
1475 detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1477 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1478 template <class> friend class packaged_task; // todo check if this works in windows
1480 friend class packaged_task<R>;
1482 friend class detail::future_waiter;
1484 template <class Rp, class Fp>
1485 friend BOOST_THREAD_FUTURE<Rp>
1486 detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1488 template <class Rp, class Fp>
1489 friend BOOST_THREAD_FUTURE<Rp>
1490 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1493 typedef typename base_type::move_dest_type move_dest_type;
1496 BOOST_THREAD_FUTURE(future_ptr a_future):
1502 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1503 typedef future_state::state state;
1504 typedef R value_type; // EXTENSION
1506 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1508 BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1511 ~BOOST_THREAD_FUTURE() {}
1513 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1514 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1517 inline BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
1519 BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
1521 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1525 shared_future<R> share()
1527 return shared_future<R>(::boost::move(*this));
1530 void swap(BOOST_THREAD_FUTURE& other)
1532 static_cast<base_type*>(this)->swap(other);
1535 // todo this function must be private and friendship provided to the internal users.
1538 this->future_->set_async();
1540 // todo this function must be private and friendship provided to the internal users.
1543 this->future_->set_deferred();
1545 bool run_if_is_deferred() {
1546 return this->future_->run_if_is_deferred();
1548 bool run_if_is_deferred_or_ready() {
1549 return this->future_->run_if_is_deferred_or_ready();
1551 // retrieving the value
1552 move_dest_type get()
1556 boost::throw_exception(future_uninitialized());
1558 future_ptr fut_=this->future_;
1559 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1560 this->future_.reset();
1565 template <typename R2>
1566 typename boost::disable_if< is_void<R2>, move_dest_type>::type
1567 get_or(BOOST_THREAD_RV_REF(R2) v)
1571 boost::throw_exception(future_uninitialized());
1573 this->future_->wait(false);
1574 future_ptr fut_=this->future_;
1575 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1576 this->future_.reset();
1578 if (fut_->has_value()) {
1582 return boost::move(v);
1586 template <typename R2>
1587 typename boost::disable_if< is_void<R2>, move_dest_type>::type
1588 get_or(R2 const& v) // EXTENSION
1592 boost::throw_exception(future_uninitialized());
1594 this->future_->wait(false);
1595 future_ptr fut_=this->future_;
1596 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1597 this->future_.reset();
1599 if (fut_->has_value()) {
1607 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1608 template<typename F>
1609 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1610 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1611 template<typename F>
1612 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1613 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1614 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1615 template<typename Ex, typename F>
1616 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1617 then(Ex& ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1620 template <typename R2>
1621 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1622 fallback_to(BOOST_THREAD_RV_REF(R2) v); // EXTENSION
1623 template <typename R2>
1624 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
1625 fallback_to(R2 const& v); // EXTENSION
1631 BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
1633 template <typename R2>
1634 class BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> > : public detail::basic_future<BOOST_THREAD_FUTURE<R2> >
1636 typedef BOOST_THREAD_FUTURE<R2> R;
1639 typedef detail::basic_future<R> base_type;
1640 typedef typename base_type::future_ptr future_ptr;
1642 friend class shared_future<R>;
1643 friend class promise<R>;
1644 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1645 template <typename, typename, typename>
1646 friend struct detail::future_async_continuation_shared_state;
1647 template <typename, typename, typename>
1648 friend struct detail::future_deferred_continuation_shared_state;
1650 template <class F, class Rp, class Fp>
1651 friend BOOST_THREAD_FUTURE<Rp>
1652 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);
1654 template <class F, class Rp, class Fp>
1655 friend BOOST_THREAD_FUTURE<Rp>
1656 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);
1658 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1659 template<typename F, typename Rp>
1660 friend struct detail::future_unwrap_shared_state;
1661 template <class F, class Rp>
1662 friend BOOST_THREAD_FUTURE<Rp>
1663 detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
1665 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1666 template <class> friend class packaged_task; // todo check if this works in windows
1668 friend class packaged_task<R>;
1670 friend class detail::future_waiter;
1672 template <class Rp, class Fp>
1673 friend BOOST_THREAD_FUTURE<Rp>
1674 detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1676 template <class Rp, class Fp>
1677 friend BOOST_THREAD_FUTURE<Rp>
1678 detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
1680 typedef typename base_type::move_dest_type move_dest_type;
1682 BOOST_THREAD_FUTURE(future_ptr a_future):
1688 BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
1689 typedef future_state::state state;
1690 typedef R value_type; // EXTENSION
1692 BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
1694 BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
1697 ~BOOST_THREAD_FUTURE() {}
1699 BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
1700 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1704 BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
1706 this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1710 shared_future<R> share()
1712 return shared_future<R>(::boost::move(*this));
1715 void swap(BOOST_THREAD_FUTURE& other)
1717 static_cast<base_type*>(this)->swap(other);
1720 // todo this function must be private and friendship provided to the internal users.
1723 this->future_->set_async();
1725 // todo this function must be private and friendship provided to the internal users.
1728 this->future_->set_deferred();
1730 bool run_if_is_deferred() {
1731 return this->future_->run_if_is_deferred();
1733 bool run_if_is_deferred_or_ready() {
1734 return this->future_->run_if_is_deferred_or_ready();
1736 // retrieving the value
1737 move_dest_type get()
1741 boost::throw_exception(future_uninitialized());
1743 future_ptr fut_=this->future_;
1744 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1745 this->future_.reset();
1749 move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
1753 boost::throw_exception(future_uninitialized());
1755 this->future_->wait(false);
1756 future_ptr fut_=this->future_;
1757 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1758 this->future_.reset();
1760 if (fut_->has_value()) return fut_->get();
1761 else return boost::move(v);
1764 move_dest_type get_or(R const& v) // EXTENSION
1768 boost::throw_exception(future_uninitialized());
1770 this->future_->wait(false);
1771 future_ptr fut_=this->future_;
1772 #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
1773 this->future_.reset();
1775 if (fut_->has_value()) return fut_->get();
1780 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1781 template<typename F>
1782 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1783 then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1784 template<typename F>
1785 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1786 then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1787 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1788 template<typename Ex, typename F>
1789 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
1790 then(Ex &ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
1794 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
1796 BOOST_THREAD_FUTURE<R2>
1797 unwrap(); // EXTENSION
1802 template <typename R>
1803 class shared_future : public detail::basic_future<R>
1805 typedef detail::basic_future<R> base_type;
1806 typedef typename base_type::future_ptr future_ptr;
1808 friend class detail::future_waiter;
1809 friend class promise<R>;
1811 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1812 template <typename, typename, typename>
1813 friend struct detail::future_async_continuation_shared_state;
1814 template <typename, typename, typename>
1815 friend struct detail::future_deferred_continuation_shared_state;
1817 template <class F, class Rp, class Fp>
1818 friend BOOST_THREAD_FUTURE<Rp>
1819 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);
1821 template <class F, class Rp, class Fp>
1822 friend BOOST_THREAD_FUTURE<Rp>
1823 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);
1825 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
1826 template <class> friend class packaged_task;// todo check if this works in windows
1828 friend class packaged_task<R>;
1830 shared_future(future_ptr a_future):
1835 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_future)
1836 typedef R value_type; // EXTENSION
1838 shared_future(shared_future const& other):
1842 typedef future_state::state state;
1844 BOOST_CONSTEXPR shared_future()
1847 shared_future(exceptional_ptr const& ex):
1852 shared_future& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_future) other)
1854 shared_future(other).swap(*this);
1858 shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
1859 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1861 BOOST_THREAD_RV(other).future_.reset();
1863 shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT :
1864 base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
1868 shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
1870 base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1873 shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT
1875 base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
1879 void swap(shared_future& other) BOOST_NOEXCEPT
1881 static_cast<base_type*>(this)->swap(other);
1883 bool run_if_is_deferred() {
1884 return this->future_->run_if_is_deferred();
1886 bool run_if_is_deferred_or_ready() {
1887 return this->future_->run_if_is_deferred_or_ready();
1889 // retrieving the value
1890 typename detail::shared_state<R>::shared_future_get_result_type get()
1894 boost::throw_exception(future_uninitialized());
1896 return this->future_->get_sh();
1899 template <typename R2>
1900 typename boost::disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type
1901 get_or(BOOST_THREAD_RV_REF(R2) v) // EXTENSION
1905 boost::throw_exception(future_uninitialized());
1907 future_ptr fut_=this->future_;
1909 if (fut_->has_value()) return fut_->get_sh();
1910 else return boost::move(v);
1913 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
1914 template<typename F>
1915 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
1916 then(BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
1917 template<typename F>
1918 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
1919 then(launch policy, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
1920 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
1921 template<typename Ex, typename F>
1922 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
1923 then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
1929 BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
1933 /// Copy construction from a shared_future
1934 template <typename R>
1935 inline basic_future<R>::basic_future(const shared_future<R>& other) BOOST_NOEXCEPT
1936 : future_(other.future_)
1941 template <typename R>
1944 typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
1946 typedef typename detail::shared_state<R>::source_reference_type source_reference_type;
1947 typedef typename detail::shared_state<R>::rvalue_source_type rvalue_source_type;
1948 typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
1949 typedef typename detail::shared_state<R>::shared_future_get_result_type shared_future_get_result_type;
1952 bool future_obtained;
1956 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
1957 #include <boost/detail/atomic_undef_macros.hpp>
1958 if(!atomic_load(&future_))
1961 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R>));
1963 #include <boost/detail/atomic_redef_macros.hpp>
1968 BOOST_THREAD_MOVABLE_ONLY(promise)
1969 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
1970 template <class Allocator>
1971 promise(boost::allocator_arg_t, Allocator a)
1973 typedef typename Allocator::template rebind<detail::shared_state<R> >::other A2;
1975 typedef thread_detail::allocator_destructor<A2> D;
1977 future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R>(), D(a2, 1) );
1978 future_obtained = false;
1982 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
1985 future_(new detail::shared_state<R>()),
1987 future_obtained(false)
1994 boost::unique_lock<boost::mutex> lock(future_->mutex);
1996 if(!future_->done && !future_->is_constructed)
1998 future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2004 promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2005 future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2007 BOOST_THREAD_RV(rhs).future_.reset();
2008 BOOST_THREAD_RV(rhs).future_obtained=false;
2010 promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2012 future_=BOOST_THREAD_RV(rhs).future_;
2013 future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2014 BOOST_THREAD_RV(rhs).future_.reset();
2015 BOOST_THREAD_RV(rhs).future_obtained=false;
2019 void swap(promise& other)
2021 future_.swap(other.future_);
2022 std::swap(future_obtained,other.future_obtained);
2026 BOOST_THREAD_FUTURE<R> get_future()
2029 if (future_.get()==0)
2031 boost::throw_exception(promise_moved());
2033 if (future_obtained)
2035 boost::throw_exception(future_already_retrieved());
2037 future_obtained=true;
2038 return BOOST_THREAD_FUTURE<R>(future_);
2041 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
2043 typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type set_value(TR const & r)
2046 boost::unique_lock<boost::mutex> lock(future_->mutex);
2049 boost::throw_exception(promise_already_satisfied());
2051 future_->mark_finished_with_result_internal(r, lock);
2054 void set_value(source_reference_type r)
2057 boost::unique_lock<boost::mutex> lock(future_->mutex);
2060 boost::throw_exception(promise_already_satisfied());
2062 future_->mark_finished_with_result_internal(r, lock);
2066 void set_value(rvalue_source_type r)
2069 boost::unique_lock<boost::mutex> lock(future_->mutex);
2072 boost::throw_exception(promise_already_satisfied());
2074 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
2075 future_->mark_finished_with_result_internal(boost::move(r), lock);
2077 future_->mark_finished_with_result_internal(static_cast<rvalue_source_type>(r), lock);
2080 void set_exception(boost::exception_ptr p)
2083 boost::unique_lock<boost::mutex> lock(future_->mutex);
2086 boost::throw_exception(promise_already_satisfied());
2088 future_->mark_exceptional_finish_internal(p, lock);
2090 template <typename E>
2091 void set_exception(E ex)
2093 set_exception(boost::copy_exception(ex));
2095 // setting the result with deferred notification
2096 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
2098 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)
2100 if (future_.get()==0)
2102 boost::throw_exception(promise_moved());
2104 future_->set_value_at_thread_exit(r);
2107 void set_value_at_thread_exit(source_reference_type r)
2109 if (future_.get()==0)
2111 boost::throw_exception(promise_moved());
2113 future_->set_value_at_thread_exit(r);
2116 void set_value_at_thread_exit(BOOST_THREAD_RV_REF(R) r)
2118 if (future_.get()==0)
2120 boost::throw_exception(promise_moved());
2122 future_->set_value_at_thread_exit(boost::move(r));
2124 void set_exception_at_thread_exit(exception_ptr e)
2126 if (future_.get()==0)
2128 boost::throw_exception(promise_moved());
2130 future_->set_exception_at_thread_exit(e);
2132 template <typename E>
2133 void set_exception_at_thread_exit(E ex)
2135 set_exception_at_thread_exit(boost::copy_exception(ex));
2138 template<typename F>
2139 void set_wait_callback(F f)
2142 future_->set_wait_callback(f,this);
2147 template <typename R>
2150 typedef boost::shared_ptr<detail::shared_state<R&> > future_ptr;
2153 bool future_obtained;
2157 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2158 #include <boost/detail/atomic_undef_macros.hpp>
2159 if(!atomic_load(&future_))
2162 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
2164 #include <boost/detail/atomic_redef_macros.hpp>
2169 BOOST_THREAD_MOVABLE_ONLY(promise)
2170 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2171 template <class Allocator>
2172 promise(boost::allocator_arg_t, Allocator a)
2174 typedef typename Allocator::template rebind<detail::shared_state<R&> >::other A2;
2176 typedef thread_detail::allocator_destructor<A2> D;
2178 future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R&>(), D(a2, 1) );
2179 future_obtained = false;
2183 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2186 future_(new detail::shared_state<R&>()),
2188 future_obtained(false)
2195 boost::unique_lock<boost::mutex> lock(future_->mutex);
2197 if(!future_->done && !future_->is_constructed)
2199 future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2205 promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2206 future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2208 BOOST_THREAD_RV(rhs).future_.reset();
2209 BOOST_THREAD_RV(rhs).future_obtained=false;
2211 promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2213 future_=BOOST_THREAD_RV(rhs).future_;
2214 future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2215 BOOST_THREAD_RV(rhs).future_.reset();
2216 BOOST_THREAD_RV(rhs).future_obtained=false;
2220 void swap(promise& other)
2222 future_.swap(other.future_);
2223 std::swap(future_obtained,other.future_obtained);
2227 BOOST_THREAD_FUTURE<R&> get_future()
2230 if (future_.get()==0)
2232 boost::throw_exception(promise_moved());
2234 if (future_obtained)
2236 boost::throw_exception(future_already_retrieved());
2238 future_obtained=true;
2239 return BOOST_THREAD_FUTURE<R&>(future_);
2242 void set_value(R& r)
2245 boost::unique_lock<boost::mutex> lock(future_->mutex);
2248 boost::throw_exception(promise_already_satisfied());
2250 future_->mark_finished_with_result_internal(r, lock);
2253 void set_exception(boost::exception_ptr p)
2256 boost::unique_lock<boost::mutex> lock(future_->mutex);
2259 boost::throw_exception(promise_already_satisfied());
2261 future_->mark_exceptional_finish_internal(p, lock);
2263 template <typename E>
2264 void set_exception(E ex)
2266 set_exception(boost::copy_exception(ex));
2269 // setting the result with deferred notification
2270 void set_value_at_thread_exit(R& r)
2272 if (future_.get()==0)
2274 boost::throw_exception(promise_moved());
2276 future_->set_value_at_thread_exit(r);
2279 void set_exception_at_thread_exit(exception_ptr e)
2281 if (future_.get()==0)
2283 boost::throw_exception(promise_moved());
2285 future_->set_exception_at_thread_exit(e);
2287 template <typename E>
2288 void set_exception_at_thread_exit(E ex)
2290 set_exception_at_thread_exit(boost::copy_exception(ex));
2293 template<typename F>
2294 void set_wait_callback(F f)
2297 future_->set_wait_callback(f,this);
2304 typedef boost::shared_ptr<detail::shared_state<void> > future_ptr;
2307 bool future_obtained;
2311 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2312 if(!atomic_load(&future_))
2315 atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<void>));
2320 BOOST_THREAD_MOVABLE_ONLY(promise)
2322 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2323 template <class Allocator>
2324 promise(boost::allocator_arg_t, Allocator a)
2326 typedef typename Allocator::template rebind<detail::shared_state<void> >::other A2;
2328 typedef thread_detail::allocator_destructor<A2> D;
2330 future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<void>(), D(a2, 1) );
2331 future_obtained = false;
2335 #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
2338 future_(new detail::shared_state<void>),
2340 future_obtained(false)
2347 boost::unique_lock<boost::mutex> lock(future_->mutex);
2349 if(!future_->done && !future_->is_constructed)
2351 future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
2357 promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
2358 future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
2360 // we need to release the future as shared_ptr doesn't implements move semantics
2361 BOOST_THREAD_RV(rhs).future_.reset();
2362 BOOST_THREAD_RV(rhs).future_obtained=false;
2365 promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
2367 future_=BOOST_THREAD_RV(rhs).future_;
2368 future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
2369 BOOST_THREAD_RV(rhs).future_.reset();
2370 BOOST_THREAD_RV(rhs).future_obtained=false;
2374 void swap(promise& other)
2376 future_.swap(other.future_);
2377 std::swap(future_obtained,other.future_obtained);
2381 BOOST_THREAD_FUTURE<void> get_future()
2385 if (future_.get()==0)
2387 boost::throw_exception(promise_moved());
2391 boost::throw_exception(future_already_retrieved());
2393 future_obtained=true;
2394 //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<void>(future_));
2395 return BOOST_THREAD_FUTURE<void>(future_);
2401 boost::unique_lock<boost::mutex> lock(future_->mutex);
2404 boost::throw_exception(promise_already_satisfied());
2406 future_->mark_finished_with_result_internal(lock);
2409 void set_exception(boost::exception_ptr p)
2412 boost::unique_lock<boost::mutex> lock(future_->mutex);
2415 boost::throw_exception(promise_already_satisfied());
2417 future_->mark_exceptional_finish_internal(p,lock);
2419 template <typename E>
2420 void set_exception(E ex)
2422 set_exception(boost::copy_exception(ex));
2425 // setting the result with deferred notification
2426 void set_value_at_thread_exit()
2428 if (future_.get()==0)
2430 boost::throw_exception(promise_moved());
2432 future_->set_value_at_thread_exit();
2435 void set_exception_at_thread_exit(exception_ptr e)
2437 if (future_.get()==0)
2439 boost::throw_exception(promise_moved());
2441 future_->set_exception_at_thread_exit(e);
2443 template <typename E>
2444 void set_exception_at_thread_exit(E ex)
2446 set_exception_at_thread_exit(boost::copy_exception(ex));
2449 template<typename F>
2450 void set_wait_callback(F f)
2453 future_->set_wait_callback(f,this);
2458 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
2459 namespace boost { namespace container {
2460 template <class R, class Alloc>
2461 struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2465 #if ! defined BOOST_NO_CXX11_ALLOCATOR
2467 template <class R, class Alloc>
2468 struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
2478 BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
2482 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2483 template<typename R>
2484 struct task_base_shared_state;
2485 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2486 template<typename R, typename ...ArgTypes>
2487 struct task_base_shared_state<R(ArgTypes...)>:
2489 template<typename R>
2490 struct task_base_shared_state<R()>:
2493 template<typename R>
2494 struct task_base_shared_state:
2496 detail::shared_state<R>
2500 task_base_shared_state():
2508 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2509 virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
2510 void run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2512 virtual void do_run()=0;
2517 boost::lock_guard<boost::mutex> lk(this->mutex);
2520 boost::throw_exception(task_already_started());
2524 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2525 do_run(boost::move(args)...);
2531 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2532 virtual void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
2533 void apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2535 virtual void do_apply()=0;
2540 boost::lock_guard<boost::mutex> lk(this->mutex);
2543 boost::throw_exception(task_already_started());
2547 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2548 do_apply(boost::move(args)...);
2554 void owner_destroyed()
2556 boost::unique_lock<boost::mutex> lk(this->mutex);
2560 this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk);
2565 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2566 template<typename F, typename R>
2567 struct task_shared_state;
2568 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2569 template<typename F, typename R, typename ...ArgTypes>
2570 struct task_shared_state<F, R(ArgTypes...)>:
2571 task_base_shared_state<R(ArgTypes...)>
2573 template<typename F, typename R>
2574 struct task_shared_state<F, R()>:
2575 task_base_shared_state<R()>
2578 template<typename F, typename R>
2579 struct task_shared_state:
2580 task_base_shared_state<R>
2584 task_shared_state(task_shared_state&);
2587 task_shared_state(F const& f_):
2590 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
2594 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2595 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2599 this->set_value_at_thread_exit(f(boost::move(args)...));
2606 this->set_value_at_thread_exit(f());
2609 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2610 catch(thread_interrupted& )
2612 this->set_interrupted_at_thread_exit();
2617 this->set_exception_at_thread_exit(current_exception());
2621 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2622 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2626 this->mark_finished_with_result(f(boost::move(args)...));
2633 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
2635 this->mark_finished_with_result(boost::move(res));
2637 this->mark_finished_with_result(f());
2641 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2642 catch(thread_interrupted& )
2644 this->mark_interrupted_finish();
2649 this->mark_exceptional_finish();
2654 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2655 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2656 template<typename F, typename R, typename ...ArgTypes>
2657 struct task_shared_state<F, R&(ArgTypes...)>:
2658 task_base_shared_state<R&(ArgTypes...)>
2660 template<typename F, typename R>
2661 struct task_shared_state<F, R&()>:
2662 task_base_shared_state<R&()>
2665 template<typename F, typename R>
2666 struct task_shared_state<F,R&>:
2667 task_base_shared_state<R&>
2671 task_shared_state(task_shared_state&);
2674 task_shared_state(F const& f_):
2677 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
2681 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2682 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2686 this->set_value_at_thread_exit(f(boost::move(args)...));
2693 this->set_value_at_thread_exit(f());
2696 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2697 catch(thread_interrupted& )
2699 this->set_interrupted_at_thread_exit();
2704 this->set_exception_at_thread_exit(current_exception());
2708 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2709 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2713 this->mark_finished_with_result(f(boost::move(args)...));
2721 this->mark_finished_with_result(res);
2724 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2725 catch(thread_interrupted& )
2727 this->mark_interrupted_finish();
2732 this->mark_exceptional_finish();
2737 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
2739 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2740 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2741 template<typename R, typename ...ArgTypes>
2742 struct task_shared_state<R (*)(ArgTypes...), R(ArgTypes...)>:
2743 task_base_shared_state<R(ArgTypes...)>
2745 template<typename R>
2746 struct task_shared_state<R (*)(), R()>:
2747 task_base_shared_state<R()>
2750 template<typename R>
2751 struct task_shared_state<R (*)(), R> :
2752 task_base_shared_state<R>
2756 task_shared_state(task_shared_state&);
2758 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2759 R (*f)(BOOST_THREAD_RV_REF(ArgTypes) ... );
2760 task_shared_state(R (*f_)(BOOST_THREAD_RV_REF(ArgTypes) ... )):
2765 task_shared_state(R (*f_)()):
2770 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2771 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2775 this->set_value_at_thread_exit(f(boost::move(args)...));
2783 this->set_value_at_thread_exit(boost::move(r));
2786 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2787 catch(thread_interrupted& )
2789 this->set_interrupted_at_thread_exit();
2794 this->set_exception_at_thread_exit(current_exception());
2799 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2800 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2804 this->mark_finished_with_result(f(boost::move(args)...));
2812 this->mark_finished_with_result(boost::move(res));
2815 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2816 catch(thread_interrupted& )
2818 this->mark_interrupted_finish();
2823 this->mark_exceptional_finish();
2827 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2828 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2829 template<typename R, typename ...ArgTypes>
2830 struct task_shared_state<R& (*)(ArgTypes...), R&(ArgTypes...)>:
2831 task_base_shared_state<R&(ArgTypes...)>
2833 template<typename R>
2834 struct task_shared_state<R& (*)(), R&()>:
2835 task_base_shared_state<R&()>
2838 template<typename R>
2839 struct task_shared_state<R& (*)(), R&> :
2840 task_base_shared_state<R&>
2844 task_shared_state(task_shared_state&);
2846 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2847 R& (*f)(BOOST_THREAD_RV_REF(ArgTypes) ... );
2848 task_shared_state(R& (*f_)(BOOST_THREAD_RV_REF(ArgTypes) ... )):
2853 task_shared_state(R& (*f_)()):
2858 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2859 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2863 this->set_value_at_thread_exit(f(boost::move(args)...));
2870 this->set_value_at_thread_exit(f());
2873 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2874 catch(thread_interrupted& )
2876 this->set_interrupted_at_thread_exit();
2881 this->set_exception_at_thread_exit(current_exception());
2886 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2887 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2891 this->mark_finished_with_result(f(boost::move(args)...));
2898 this->mark_finished_with_result(f());
2901 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2902 catch(thread_interrupted& )
2904 this->mark_interrupted_finish();
2909 this->mark_exceptional_finish();
2914 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2915 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2916 template<typename F, typename ...ArgTypes>
2917 struct task_shared_state<F, void(ArgTypes...)>:
2918 task_base_shared_state<void(ArgTypes...)>
2920 template<typename F>
2921 struct task_shared_state<F, void()>:
2922 task_base_shared_state<void()>
2925 template<typename F>
2926 struct task_shared_state<F,void>:
2927 task_base_shared_state<void>
2931 task_shared_state(task_shared_state&);
2934 task_shared_state(F const& f_):
2937 task_shared_state(BOOST_THREAD_RV_REF(F) f_):
2941 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2942 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2946 f(boost::move(args)...);
2954 this->set_value_at_thread_exit();
2956 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2957 catch(thread_interrupted& )
2959 this->set_interrupted_at_thread_exit();
2964 this->set_exception_at_thread_exit(current_exception());
2968 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2969 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
2973 f(boost::move(args)...);
2981 this->mark_finished_with_result();
2983 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2984 catch(thread_interrupted& )
2986 this->mark_interrupted_finish();
2991 this->mark_exceptional_finish();
2996 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
2997 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2998 template<typename ...ArgTypes>
2999 struct task_shared_state<void (*)(ArgTypes...), void(ArgTypes...)>:
3000 task_base_shared_state<void(ArgTypes...)>
3003 struct task_shared_state<void (*)(), void()>:
3004 task_base_shared_state<void()>
3008 struct task_shared_state<void (*)(),void>:
3009 task_base_shared_state<void>
3013 task_shared_state(task_shared_state&);
3016 task_shared_state(void (*f_)()):
3020 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3021 void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3025 f(boost::move(args)...);
3033 this->set_value_at_thread_exit();
3035 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3036 catch(thread_interrupted& )
3038 this->set_interrupted_at_thread_exit();
3043 this->set_exception_at_thread_exit(current_exception());
3047 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3048 void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
3052 f(boost::move(args)...);
3060 this->mark_finished_with_result();
3062 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3063 catch(thread_interrupted& )
3065 this->mark_interrupted_finish();
3070 this->mark_exceptional_finish();
3076 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3077 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3078 template<typename R, typename ...ArgTypes>
3079 class packaged_task<R(ArgTypes...)>
3081 typedef boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task_ptr;
3082 boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task;
3084 template<typename R>
3085 class packaged_task<R()>
3087 typedef boost::shared_ptr<detail::task_base_shared_state<R()> > task_ptr;
3088 boost::shared_ptr<detail::task_base_shared_state<R()> > task;
3091 template<typename R>
3094 typedef boost::shared_ptr<detail::task_base_shared_state<R> > task_ptr;
3095 boost::shared_ptr<detail::task_base_shared_state<R> > task;
3097 bool future_obtained;
3101 typedef R result_type;
3102 BOOST_THREAD_MOVABLE_ONLY(packaged_task)
3105 future_obtained(false)
3108 // construction and destruction
3109 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3111 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3112 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3113 explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args)
3115 typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3116 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3117 task= task_ptr(new task_shared_state_type(f, boost::move(args)...));
3118 future_obtained=false;
3121 explicit packaged_task(R(*f)())
3124 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3125 task= task_ptr(new task_shared_state_type(f));
3126 future_obtained=false;
3130 explicit packaged_task(R(*f)())
3133 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3134 task= task_ptr(new task_shared_state_type(f));
3135 future_obtained=false;
3139 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
3141 explicit packaged_task(BOOST_THREAD_FWD_REF(F) f
3142 , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3145 typedef typename decay<F>::type FR;
3146 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3147 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3148 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3150 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3153 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3155 task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
3156 future_obtained = false;
3162 explicit packaged_task(F const& f
3163 , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
3166 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3167 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3168 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3170 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3173 typedef detail::task_shared_state<F,R> task_shared_state_type;
3175 task = task_ptr(new task_shared_state_type(f));
3176 future_obtained=false;
3179 explicit packaged_task(BOOST_THREAD_RV_REF(F) f)
3181 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3182 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3183 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3184 task = task_ptr(new task_shared_state_type(boost::move(f)));
3186 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3187 task = task_ptr(new task_shared_state_type(boost::move(f)));
3190 typedef detail::task_shared_state<F,R> task_shared_state_type;
3191 task = task_ptr(new task_shared_state_type(boost::move(f)));
3193 future_obtained=false;
3198 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3199 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3200 template <class Allocator>
3201 packaged_task(boost::allocator_arg_t, Allocator a, R(*f)())
3204 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3205 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3206 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3208 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3211 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3213 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3215 typedef thread_detail::allocator_destructor<A2> D;
3217 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3218 future_obtained = false;
3220 #endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3222 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3223 template <class F, class Allocator>
3224 packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
3226 typedef typename decay<F>::type FR;
3228 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3229 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3230 typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
3232 typedef detail::task_shared_state<FR,R()> task_shared_state_type;
3235 typedef detail::task_shared_state<FR,R> task_shared_state_type;
3237 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3239 typedef thread_detail::allocator_destructor<A2> D;
3241 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
3242 future_obtained = false;
3244 #else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3245 template <class F, class Allocator>
3246 packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
3248 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3249 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3250 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3252 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3255 typedef detail::task_shared_state<F,R> task_shared_state_type;
3257 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3259 typedef thread_detail::allocator_destructor<A2> D;
3261 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
3262 future_obtained = false;
3264 template <class F, class Allocator>
3265 packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f)
3267 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3268 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3269 typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
3271 typedef detail::task_shared_state<F,R()> task_shared_state_type;
3274 typedef detail::task_shared_state<F,R> task_shared_state_type;
3276 typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
3278 typedef thread_detail::allocator_destructor<A2> D;
3280 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3281 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) );
3283 task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) );
3285 future_obtained = false;
3288 #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
3289 #endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3293 task->owner_destroyed();
3298 packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
3299 : future_obtained(BOOST_THREAD_RV(other).future_obtained) {
3300 task.swap(BOOST_THREAD_RV(other).task);
3301 BOOST_THREAD_RV(other).future_obtained=false;
3303 packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT {
3305 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
3306 packaged_task temp(boost::move(other));
3308 packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
3316 throw future_error(system::make_error_code(future_errc::no_state));
3318 future_obtained=false;
3321 void swap(packaged_task& other) BOOST_NOEXCEPT {
3322 task.swap(other.task);
3323 std::swap(future_obtained,other.future_obtained);
3325 bool valid() const BOOST_NOEXCEPT {
3326 return task.get()!=0;
3330 BOOST_THREAD_FUTURE<R> get_future() {
3332 boost::throw_exception(task_moved());
3333 } else if(!future_obtained) {
3334 future_obtained=true;
3335 return BOOST_THREAD_FUTURE<R>(task);
3337 boost::throw_exception(future_already_retrieved());
3342 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3343 void operator()(BOOST_THREAD_RV_REF(ArgTypes)... args) {
3345 boost::throw_exception(task_moved());
3347 task->run(boost::move(args)...);
3349 void make_ready_at_thread_exit(ArgTypes... args) {
3351 boost::throw_exception(task_moved());
3353 if (task->has_value()) {
3354 boost::throw_exception(promise_already_satisfied());
3356 task->apply(boost::move(args)...);
3361 boost::throw_exception(task_moved());
3365 void make_ready_at_thread_exit() {
3367 boost::throw_exception(task_moved());
3369 if (task->has_value()) boost::throw_exception(promise_already_satisfied());
3373 template<typename F>
3374 void set_wait_callback(F f) {
3375 task->set_wait_callback(f,this);
3379 #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
3380 namespace boost { namespace container {
3381 template <class R, class Alloc>
3382 struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3385 #if ! defined BOOST_NO_CXX11_ALLOCATOR
3387 template <class R, class Alloc>
3388 struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
3396 BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
3400 ////////////////////////////////
3401 // make_future_deferred_shared_state
3402 ////////////////////////////////
3403 template <class Rp, class Fp>
3404 BOOST_THREAD_FUTURE<Rp>
3405 make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3406 shared_ptr<future_deferred_shared_state<Rp, Fp> >
3407 h(new future_deferred_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
3408 return BOOST_THREAD_FUTURE<Rp>(h);
3411 ////////////////////////////////
3412 // make_future_async_shared_state
3413 ////////////////////////////////
3414 template <class Rp, class Fp>
3415 BOOST_THREAD_FUTURE<Rp>
3416 make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
3417 shared_ptr<future_async_shared_state<Rp, Fp> >
3418 h(new future_async_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
3419 return BOOST_THREAD_FUTURE<Rp>(h);
3423 ////////////////////////////////
3424 // template <class F, class... ArgTypes>
3425 // future<R> async(launch policy, F&&, ArgTypes&&...);
3426 ////////////////////////////////
3428 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3430 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3431 template <class R, class... ArgTypes>
3432 BOOST_THREAD_FUTURE<R>
3433 async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3434 typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3435 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3436 typedef typename BF::result_type Rp;
3438 if (underlying_cast<int>(policy) & int(launch::async)) {
3439 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3442 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3445 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3446 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3449 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3454 BOOST_THREAD_FUTURE<R> ret;
3455 return ::boost::move(ret);
3459 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3462 BOOST_THREAD_FUTURE<R>
3463 async(launch policy, R(*f)()) {
3464 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3465 typedef packaged_task<R()> packaged_task_type;
3467 typedef packaged_task<R> packaged_task_type;
3470 if (underlying_cast<int>(policy) & int(launch::async)) {
3471 packaged_task_type pt( f );
3472 BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
3474 boost::thread( boost::move(pt) ).detach();
3475 return ::boost::move(ret);
3476 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3478 BOOST_THREAD_FUTURE<R> ret;
3479 return ::boost::move(ret);
3482 BOOST_THREAD_FUTURE<R> ret;
3483 return ::boost::move(ret);
3487 #endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
3489 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3491 template <class F, class ...ArgTypes>
3492 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3493 typename decay<ArgTypes>::type...
3495 async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3496 typedef typename boost::result_of<typename decay<F>::type(
3497 typename decay<ArgTypes>::type...
3499 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3500 typedef typename BF::result_type Rp;
3502 if (underlying_cast<int>(policy) & int(launch::async)) {
3503 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
3505 thread_detail::decay_copy(boost::forward<F>(f))
3506 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3509 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3510 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
3512 thread_detail::decay_copy(boost::forward<F>(f))
3513 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3518 BOOST_THREAD_FUTURE<R> ret;
3519 return ::boost::move(ret);
3523 #else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3526 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3527 async(launch policy, BOOST_THREAD_FWD_REF(F) f) {
3528 typedef typename boost::result_of<typename decay<F>::type()>::type R;
3529 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3530 typedef packaged_task<R()> packaged_task_type;
3531 #else // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3532 typedef packaged_task<R> packaged_task_type;
3533 #endif // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
3535 if (underlying_cast<int>(policy) & int(launch::async)) {
3536 packaged_task_type pt( boost::forward<F>(f) );
3537 BOOST_THREAD_FUTURE<R> ret = pt.get_future();
3539 boost::thread( boost::move(pt) ).detach();
3540 return ::boost::move(ret);
3541 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
3543 BOOST_THREAD_FUTURE<R> ret;
3544 return ::boost::move(ret);
3545 // return boost::detail::make_future_deferred_shared_state<Rp>(
3547 // thread_detail::decay_copy(boost::forward<F>(f))
3552 BOOST_THREAD_FUTURE<R> ret;
3553 return ::boost::move(ret);
3556 #endif // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3558 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
3560 /////////////////////////
3561 /// shared_state_nullary_task
3562 /////////////////////////
3563 template<typename Rp, typename Fp>
3564 struct shared_state_nullary_task
3566 shared_state<Rp>* that;
3570 shared_state_nullary_task(shared_state<Rp>* st, BOOST_THREAD_FWD_REF(Fp) f)
3571 : that(st), f_(boost::move(f))
3573 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
3574 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
3575 shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
3576 : that(x.that), f_(x.f_)
3578 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3587 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3588 : that(x.that), f_(boost::move(x.f_))
3592 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3596 f_=boost::move(x.f_);
3604 that->mark_finished_with_result(f_());
3605 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3606 } catch(thread_interrupted& ) {
3607 that->mark_interrupted_finish();
3608 #endif // defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3610 that->mark_exceptional_finish();
3615 template<typename Fp>
3616 struct shared_state_nullary_task<void, Fp>
3618 shared_state<void>* that;
3621 shared_state_nullary_task(shared_state<void>* st, BOOST_THREAD_FWD_REF(Fp) f)
3622 : that(st), f_(boost::move(f))
3624 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
3625 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
3626 shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
3627 : that(x.that), f_(x.f_)
3629 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
3638 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
3639 : that(x.that), f_(boost::move(x.f_))
3643 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
3646 f_=boost::move(x.f_);
3655 that->mark_finished_with_result();
3656 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3657 } catch(thread_interrupted& ) {
3658 that->mark_interrupted_finish();
3659 #endif // defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3661 that->mark_exceptional_finish();
3666 template<typename Rp, typename Fp>
3667 struct shared_state_nullary_task<Rp&, Fp>
3669 shared_state<Rp&>* that;
3672 shared_state_nullary_task(shared_state<Rp&>* st, BOOST_THREAD_FWD_REF(Fp) f)
3673 : that(st), f_(boost::move(f))
3675 #if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
3676 BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
3677 shared_state_nullary_task(shared_state_nullary_task const& x) BOOST_NOEXCEPT
3678 : that(x.that), f_(x.f_) {}
3680 shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
3688 shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
3689 : that(x.that), f_(boost::move(x.f_))
3693 shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
3696 f_=boost::move(x.f_);
3704 that->mark_finished_with_result(f_());
3705 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3706 } catch(thread_interrupted& ) {
3707 that->mark_interrupted_finish();
3708 #endif // defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
3710 that->mark_exceptional_finish();
3715 /////////////////////////
3716 /// future_executor_shared_state_base
3717 /////////////////////////
3718 template<typename Rp, typename Executor>
3719 struct future_executor_shared_state: shared_state<Rp>
3721 typedef shared_state<Rp> base_type;
3724 template<typename Fp>
3725 future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
3726 this->set_executor();
3727 shared_state_nullary_task<Rp,Fp> t(this, boost::forward<Fp>(f));
3728 ex.submit(boost::move(t));
3731 ~future_executor_shared_state() {
3736 ////////////////////////////////
3737 // make_future_executor_shared_state
3738 ////////////////////////////////
3739 template <class Rp, class Fp, class Executor>
3740 BOOST_THREAD_FUTURE<Rp>
3741 make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
3742 shared_ptr<future_executor_shared_state<Rp, Executor> >
3743 h(new future_executor_shared_state<Rp, Executor>(ex, boost::forward<Fp>(f)));
3744 return BOOST_THREAD_FUTURE<Rp>(h);
3749 ////////////////////////////////
3750 // template <class Executor, class F, class... ArgTypes>
3751 // future<R> async(Executor& ex, F&&, ArgTypes&&...);
3752 ////////////////////////////////
3754 //#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3755 #if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
3757 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3759 template <class Executor, class R, class... ArgTypes>
3760 BOOST_THREAD_FUTURE<R>
3761 async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3762 typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
3763 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3764 typedef typename BF::result_type Rp;
3766 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3769 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3773 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3775 template <class Executor, class F, class ...ArgTypes>
3776 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3777 typename decay<ArgTypes>::type...
3779 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3780 typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
3781 typedef typename BF::result_type Rp;
3783 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3785 thread_detail::decay_copy(boost::forward<F>(f))
3786 , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
3791 #else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3792 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3794 template <class Executor, class R>
3795 BOOST_THREAD_FUTURE<R>
3796 async(Executor& ex, R(*f)()) {
3798 typedef detail::invoker<F> BF;
3799 typedef typename BF::result_type Rp;
3801 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3808 template <class Executor, class R, class A1>
3809 BOOST_THREAD_FUTURE<R>
3810 async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1) {
3811 typedef R(*F)(BOOST_THREAD_FWD_REF(A1));
3812 typedef detail::invoker<F, typename decay<A1>::type> BF;
3813 typedef typename BF::result_type Rp;
3815 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3818 , thread_detail::decay_copy(boost::forward<A1>(a1))
3822 #endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3824 template <class Executor, class F>
3825 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
3826 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f) {
3827 typedef detail::invoker<typename decay<F>::type> BF;
3828 typedef typename BF::result_type Rp;
3830 return boost::detail::make_future_executor_shared_state<Rp>(ex,
3832 thread_detail::decay_copy(boost::forward<F>(f))
3837 template <class Executor, class F, class A1>
3838 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3839 typename decay<A1>::type
3841 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) {
3842 typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type> BF;
3843 typedef typename BF::result_type Rp;
3845 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3847 thread_detail::decay_copy(boost::forward<F>(f))
3848 , thread_detail::decay_copy(boost::forward<A1>(a1))
3853 template <class Executor, class F, class A1, class A2>
3854 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3855 typename decay<A1>::type, typename decay<A2>::type
3857 async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) {
3858 typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type, typename decay<A2>::type> BF;
3859 typedef typename BF::result_type Rp;
3861 return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
3863 thread_detail::decay_copy(boost::forward<F>(f))
3864 , thread_detail::decay_copy(boost::forward<A1>(a1))
3865 , thread_detail::decay_copy(boost::forward<A2>(a2))
3870 #endif //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
3873 ////////////////////////////////
3874 // template <class F, class... ArgTypes>
3875 // future<R> async(F&&, ArgTypes&&...);
3876 ////////////////////////////////
3878 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
3879 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3880 template <class R, class... ArgTypes>
3881 BOOST_THREAD_FUTURE<R>
3882 async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3883 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
3887 BOOST_THREAD_FUTURE<R>
3889 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
3894 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
3895 template <class F, class ...ArgTypes>
3896 BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
3897 typename decay<ArgTypes>::type...
3899 async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
3900 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
3904 BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
3905 async(BOOST_THREAD_FWD_REF(F) f) {
3906 return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
3910 ////////////////////////////////
3911 // make_future deprecated
3912 ////////////////////////////////
3913 template <typename T>
3914 BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value) {
3915 typedef typename decay<T>::type future_value_type;
3916 promise<future_value_type> p;
3917 p.set_value(boost::forward<future_value_type>(value));
3918 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3921 #if defined BOOST_THREAD_USES_MOVE
3922 inline BOOST_THREAD_FUTURE<void> make_future() {
3925 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3929 ////////////////////////////////
3930 // make_ready_future
3931 ////////////////////////////////
3932 template <typename T>
3933 BOOST_THREAD_FUTURE<typename decay<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
3934 typedef typename decay<T>::type future_value_type;
3935 promise<future_value_type> p;
3936 p.set_value(boost::forward<future_value_type>(value));
3937 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3940 template <typename T, typename T1>
3941 BOOST_THREAD_FUTURE<T> make_ready_no_decay_future(T1 value) {
3942 typedef T future_value_type;
3943 promise<future_value_type> p;
3945 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3948 #if defined BOOST_THREAD_USES_MOVE
3949 inline BOOST_THREAD_FUTURE<void> make_ready_future() {
3952 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3956 template <typename T>
3957 BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex) {
3959 p.set_exception(ex);
3960 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3963 template <typename T>
3964 BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
3966 p.set_exception(ex);
3967 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3970 template <typename T, typename E>
3971 BOOST_THREAD_FUTURE<T> make_exceptional_future(E ex) {
3973 p.set_exception(boost::copy_exception(ex));
3974 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3977 template <typename T>
3978 BOOST_THREAD_FUTURE<T> make_exceptional_future() {
3980 p.set_exception(boost::current_exception());
3981 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
3984 template <typename T>
3985 BOOST_THREAD_FUTURE<T> make_exceptional_future_if_invalid(BOOST_THREAD_FWD_REF(BOOST_THREAD_FUTURE<T>) fut) {
3986 fut.set_exceptional_if_invalid();
3987 return boost::move(fut);
3989 template <typename T>
3990 shared_future<T> make_exceptional_future_if_invalid(shared_future<T> fut) {
3991 fut.set_exceptional_if_invalid();
3996 template<typename CLOSURE>
3997 make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE<decltype(closure())> {
3998 typedef decltype(closure()) T;
4001 p.set_value(closure());
4003 p.set_exception(std::current_exception());
4005 return BOOST_THREAD_MAKE_RV_REF(p.get_future());
4009 ////////////////////////////////
4010 // make_shared_future deprecated
4011 ////////////////////////////////
4012 template <typename T>
4013 shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value) {
4014 typedef typename decay<T>::type future_type;
4015 promise<future_type> p;
4016 p.set_value(boost::forward<T>(value));
4017 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4020 inline shared_future<void> make_shared_future() {
4022 return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
4025 ////////////////////////////////
4026 // detail::future_async_continuation_shared_state
4027 ////////////////////////////////
4028 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
4032 /////////////////////////
4033 /// future_async_continuation_shared_state
4034 /////////////////////////
4036 template<typename F, typename Rp, typename Fp>
4037 struct future_async_continuation_shared_state: future_async_shared_state_base<Rp>
4043 future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4044 : parent(boost::move(f)),
4045 continuation(boost::move(c)) {
4048 void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4049 this->thr_ = thread(&future_async_continuation_shared_state::run, this);
4052 static void run(future_async_continuation_shared_state* that) {
4054 that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
4055 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4056 } catch(thread_interrupted& ) {
4057 that->mark_interrupted_finish();
4060 that->mark_exceptional_finish();
4064 ~future_async_continuation_shared_state() {
4069 template<typename F, typename Fp>
4070 struct future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void>
4076 future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4077 : parent(boost::move(f)),
4078 continuation(boost::move(c)) {
4081 void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4082 this->thr_ = thread(&future_async_continuation_shared_state::run, this);
4085 static void run(future_async_continuation_shared_state* that) {
4087 that->continuation(boost::move(that->parent));
4088 that->mark_finished_with_result();
4089 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4090 } catch(thread_interrupted& ) {
4091 that->mark_interrupted_finish();
4094 that->mark_exceptional_finish();
4098 ~future_async_continuation_shared_state() {
4103 /////////////////////////
4104 /// future_executor_continuation_shared_state
4105 /////////////////////////
4106 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4108 template <typename Ex>
4112 run_it(Ex* that) : that (that) {}
4113 void operator()() { that->run(that); }
4116 template<typename Ex, typename F, typename Rp, typename Fp>
4117 struct future_executor_continuation_shared_state: shared_state<Rp>
4124 future_executor_continuation_shared_state(Ex& ex, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4125 : ex(&ex), parent(boost::move(f)),
4126 continuation(boost::move(c)) {
4127 this->set_executor();
4130 void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4131 run_it<future_executor_continuation_shared_state> fct(this);
4135 static void run(future_executor_continuation_shared_state* that) {
4137 that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
4138 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4139 } catch(thread_interrupted& ) {
4140 that->mark_interrupted_finish();
4143 that->mark_exceptional_finish();
4147 ~future_executor_continuation_shared_state() {
4152 template<typename Ex, typename F, typename Fp>
4153 struct future_executor_continuation_shared_state<Ex, F, void, Fp>: public shared_state<void>
4160 future_executor_continuation_shared_state(Ex& ex, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4161 : ex(&ex), parent(boost::move(f)),
4162 continuation(boost::move(c)) {
4163 this->set_executor();
4166 void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4167 run_it<future_executor_continuation_shared_state> fct(this);
4171 static void run(future_executor_continuation_shared_state* that) {
4173 that->continuation(boost::move(that->parent));
4174 that->mark_finished_with_result();
4175 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4176 } catch(thread_interrupted& ) {
4177 that->mark_interrupted_finish();
4180 that->mark_exceptional_finish();
4184 ~future_executor_continuation_shared_state() {
4190 /////////////////////////
4191 /// shared_future_async_continuation_shared_state
4192 /////////////////////////
4194 template<typename F, typename Rp, typename Fp>
4195 struct shared_future_async_continuation_shared_state: future_async_shared_state_base<Rp>
4201 shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4203 continuation(boost::move(c)) {
4206 void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4207 this->thr_ = thread(&shared_future_async_continuation_shared_state::run, this);
4210 static void run(shared_future_async_continuation_shared_state* that) {
4212 that->mark_finished_with_result(that->continuation(that->parent));
4213 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4214 } catch(thread_interrupted& ) {
4215 that->mark_interrupted_finish();
4218 that->mark_exceptional_finish();
4222 ~shared_future_async_continuation_shared_state() {
4227 template<typename F, typename Fp>
4228 struct shared_future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void>
4234 shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4236 continuation(boost::move(c)) {
4239 void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4240 this->thr_ = thread(&shared_future_async_continuation_shared_state::run, this);
4243 static void run(shared_future_async_continuation_shared_state* that) {
4245 that->continuation(that->parent);
4246 that->mark_finished_with_result();
4247 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4248 } catch(thread_interrupted& ) {
4249 that->mark_interrupted_finish();
4252 that->mark_exceptional_finish();
4256 ~shared_future_async_continuation_shared_state() {
4261 /////////////////////////
4262 /// shared_future_executor_continuation_shared_state
4263 /////////////////////////
4264 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4266 template<typename Ex, typename F, typename Rp, typename Fp>
4267 struct shared_future_executor_continuation_shared_state: shared_state<Rp>
4274 shared_future_executor_continuation_shared_state(Ex& ex, F f, BOOST_THREAD_FWD_REF(Fp) c)
4275 : ex(&ex), parent(f),
4276 continuation(boost::move(c)) {
4277 this->set_executor();
4280 void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4281 run_it<shared_future_executor_continuation_shared_state> fct(this);
4285 static void run(shared_future_executor_continuation_shared_state* that) {
4287 that->mark_finished_with_result(that->continuation(that->parent));
4288 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4289 } catch(thread_interrupted& ) {
4290 that->mark_interrupted_finish();
4293 that->mark_exceptional_finish();
4297 ~shared_future_executor_continuation_shared_state() {
4302 template<typename Ex, typename F, typename Fp>
4303 struct shared_future_executor_continuation_shared_state<Ex, F, void, Fp>: public shared_state<void>
4310 shared_future_executor_continuation_shared_state(Ex& ex, F f, BOOST_THREAD_FWD_REF(Fp) c)
4311 : ex(&ex), parent(f),
4312 continuation(boost::move(c)) {
4315 void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4316 run_it<shared_future_executor_continuation_shared_state> fct(this);
4320 static void run(shared_future_executor_continuation_shared_state* that) {
4322 that->continuation(that->parent);
4323 that->mark_finished_with_result();
4324 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4325 } catch(thread_interrupted& ) {
4326 that->mark_interrupted_finish();
4329 that->mark_exceptional_finish();
4333 ~shared_future_executor_continuation_shared_state() {
4338 //////////////////////////
4339 /// future_deferred_continuation_shared_state
4340 //////////////////////////
4341 template<typename F, typename Rp, typename Fp>
4342 struct future_deferred_continuation_shared_state: shared_state<Rp>
4348 future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4349 : parent(boost::move(f)),
4350 continuation(boost::move(c)) {
4351 this->set_deferred();
4354 virtual void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4357 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
4359 Fp local_fuct=boost::move(continuation);
4360 F ftmp = boost::move(parent);
4361 relocker relock(lck);
4362 Rp res = local_fuct(boost::move(ftmp));
4364 this->mark_finished_with_result_internal(boost::move(res), lck);
4366 this->mark_exceptional_finish_internal(current_exception(), lck);
4371 template<typename F, typename Fp>
4372 struct future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void>
4378 future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
4379 : parent(boost::move(f)),
4380 continuation(boost::move(c)) {
4381 this->set_deferred();
4384 virtual void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4387 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
4389 Fp local_fuct=boost::move(continuation);
4390 F ftmp = boost::move(parent);
4391 relocker relock(lck);
4392 local_fuct(boost::move(ftmp));
4394 this->mark_finished_with_result_internal(lck);
4396 this->mark_exceptional_finish_internal(current_exception(), lck);
4401 //////////////////////////
4402 /// shared_future_deferred_continuation_shared_state
4403 //////////////////////////
4404 template<typename F, typename Rp, typename Fp>
4405 struct shared_future_deferred_continuation_shared_state: shared_state<Rp>
4411 shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4413 continuation(boost::move(c)) {
4414 this->set_deferred();
4417 virtual void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4420 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
4422 Fp local_fuct=boost::move(continuation);
4424 relocker relock(lck);
4425 Rp res = local_fuct(ftmp);
4427 this->mark_finished_with_result_internal(boost::move(res), lck);
4429 this->mark_exceptional_finish_internal(current_exception(), lck);
4434 template<typename F, typename Fp>
4435 struct shared_future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void>
4441 shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
4443 continuation(boost::move(c)) {
4444 this->set_deferred();
4447 virtual void launch_continuation(boost::unique_lock<boost::mutex>& ) {
4450 virtual void execute(boost::unique_lock<boost::mutex>& lck) {
4452 Fp local_fuct=boost::move(continuation);
4454 relocker relock(lck);
4457 this->mark_finished_with_result_internal(lck);
4459 this->mark_exceptional_finish_internal(current_exception(), lck);
4464 ////////////////////////////////
4465 // make_future_deferred_continuation_shared_state
4466 ////////////////////////////////
4467 template<typename F, typename Rp, typename Fp>
4468 BOOST_THREAD_FUTURE<Rp>
4469 make_future_deferred_continuation_shared_state(
4470 boost::unique_lock<boost::mutex> &lock,
4471 BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c) {
4472 shared_ptr<future_deferred_continuation_shared_state<F, Rp, Fp> >
4473 h(new future_deferred_continuation_shared_state<F, Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
4474 h->parent.future_->set_continuation_ptr(h, lock);
4475 return BOOST_THREAD_FUTURE<Rp>(h);
4478 ////////////////////////////////
4479 // make_future_async_continuation_shared_state
4480 ////////////////////////////////
4481 template<typename F, typename Rp, typename Fp>
4482 BOOST_THREAD_FUTURE<Rp>
4483 make_future_async_continuation_shared_state(
4484 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4485 BOOST_THREAD_FWD_REF(Fp) c) {
4486 shared_ptr<future_async_continuation_shared_state<F,Rp, Fp> >
4487 h(new future_async_continuation_shared_state<F,Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
4488 h->parent.future_->set_continuation_ptr(h, lock);
4490 return BOOST_THREAD_FUTURE<Rp>(h);
4493 ////////////////////////////////
4494 // make_future_executor_continuation_shared_state
4495 ////////////////////////////////
4496 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4498 template<typename Ex, typename F, typename Rp, typename Fp>
4499 BOOST_THREAD_FUTURE<Rp>
4500 make_future_executor_continuation_shared_state(Ex& ex,
4501 boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
4502 BOOST_THREAD_FWD_REF(Fp) c) {
4503 shared_ptr<future_executor_continuation_shared_state<Ex,F,Rp, Fp> >
4504 h(new future_executor_continuation_shared_state<Ex, F,Rp, Fp>(ex, boost::move(f), boost::forward<Fp>(c)));
4505 h->parent.future_->set_continuation_ptr(h, lock);
4507 return BOOST_THREAD_FUTURE<Rp>(h);
4511 ////////////////////////////////
4512 // make_shared_future_deferred_continuation_shared_state
4513 ////////////////////////////////
4514 template<typename F, typename Rp, typename Fp>
4515 BOOST_THREAD_FUTURE<Rp>
4516 make_shared_future_deferred_continuation_shared_state(
4517 boost::unique_lock<boost::mutex> &lock,
4518 F f, BOOST_THREAD_FWD_REF(Fp) c) {
4519 shared_ptr<shared_future_deferred_continuation_shared_state<F, Rp, Fp> >
4520 h(new shared_future_deferred_continuation_shared_state<F, Rp, Fp>(f, boost::forward<Fp>(c)));
4521 h->parent.future_->set_continuation_ptr(h, lock);
4522 return BOOST_THREAD_FUTURE<Rp>(h);
4524 ////////////////////////////////
4525 // make_shared_future_async_continuation_shared_state
4526 ////////////////////////////////
4527 template<typename F, typename Rp, typename Fp>
4528 BOOST_THREAD_FUTURE<Rp>
4529 make_shared_future_async_continuation_shared_state(
4530 boost::unique_lock<boost::mutex> &lock, F f,
4531 BOOST_THREAD_FWD_REF(Fp) c) {
4532 shared_ptr<shared_future_async_continuation_shared_state<F,Rp, Fp> >
4533 h(new shared_future_async_continuation_shared_state<F,Rp, Fp>(f, boost::forward<Fp>(c)));
4534 h->parent.future_->set_continuation_ptr(h, lock);
4536 return BOOST_THREAD_FUTURE<Rp>(h);
4538 ////////////////////////////////
4539 // make_shared_future_executor_continuation_shared_state
4540 ////////////////////////////////
4541 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4542 template<typename Ex, typename F, typename Rp, typename Fp>
4543 BOOST_THREAD_FUTURE<Rp>
4544 make_shared_future_executor_continuation_shared_state(Ex& ex,
4545 boost::unique_lock<boost::mutex> &lock, F f,
4546 BOOST_THREAD_FWD_REF(Fp) c) {
4547 shared_ptr<shared_future_executor_continuation_shared_state<Ex, F, Rp, Fp> >
4548 h(new shared_future_executor_continuation_shared_state<Ex, F, Rp, Fp>(ex, f, boost::forward<Fp>(c)));
4549 h->parent.future_->set_continuation_ptr(h, lock);
4551 return BOOST_THREAD_FUTURE<Rp>(h);
4556 ////////////////////////////////
4557 // template<typename F>
4558 // auto future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
4559 ////////////////////////////////
4561 template <typename R>
4562 template <typename F>
4563 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4564 BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
4565 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4566 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4568 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4569 if (underlying_cast<int>(policy) & int(launch::async)) {
4570 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4571 lock, boost::move(*this), boost::forward<F>(func)
4573 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
4574 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4575 lock, boost::move(*this), boost::forward<F>(func)
4578 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4579 lock, boost::move(*this), boost::forward<F>(func)
4583 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4584 template <typename R>
4585 template <typename Ex, typename F>
4586 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4587 BOOST_THREAD_FUTURE<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
4588 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4589 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4591 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4592 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
4593 lock, boost::move(*this), boost::forward<F>(func)
4597 template <typename R>
4598 template <typename F>
4599 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
4600 BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func) {
4601 typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
4602 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4604 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4605 if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
4606 return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4607 lock, boost::move(*this), boost::forward<F>(func)
4609 } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
4610 this->future_->wait_internal(lock);
4611 return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4612 lock, boost::move(*this), boost::forward<F>(func)
4615 return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
4616 lock, boost::move(*this), boost::forward<F>(func)
4621 template <typename R>
4622 template <typename F>
4623 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
4624 shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) const
4626 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
4627 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4629 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4631 if (underlying_cast<int>(policy) & int(launch::async)) {
4632 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
4633 lock, *this, boost::forward<F>(func)
4635 } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
4636 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
4637 lock, *this, boost::forward<F>(func)
4640 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
4641 lock, *this, boost::forward<F>(func)
4645 #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
4646 template <typename R>
4647 template <typename Ex, typename F>
4648 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
4649 shared_future<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const
4651 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
4652 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4654 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4655 return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type, F>(ex,
4656 lock, *this, boost::forward<F>(func)
4661 template <typename R>
4662 template <typename F>
4663 inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
4664 shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func) const {
4665 typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
4667 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4669 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4670 if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
4671 return boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
4672 lock, *this, boost::forward<F>(func));
4673 } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
4674 this->future_->wait_internal(lock);
4675 return boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
4676 lock, *this, boost::forward<F>(func));
4678 return boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
4679 lock, *this, boost::forward<F>(func));
4685 template <typename T>
4686 struct mfallbacker_to
4689 typedef T result_type;
4690 mfallbacker_to(BOOST_THREAD_RV_REF(T) v)
4691 : value_(boost::move(v))
4694 T operator()(BOOST_THREAD_FUTURE<T> fut) {
4695 return fut.get_or(boost::move(value_));
4698 template <typename T>
4699 struct cfallbacker_to
4702 typedef T result_type;
4703 cfallbacker_to(T const& v)
4707 T operator()(BOOST_THREAD_FUTURE<T> fut) {
4708 return fut.get_or(value_);
4713 ////////////////////////////////
4714 // future<R> future<R>::fallback_to(R&& v);
4715 ////////////////////////////////
4717 template <typename R>
4718 template <typename R2>
4719 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
4720 BOOST_THREAD_FUTURE<R>::fallback_to(BOOST_THREAD_RV_REF(R2) v) {
4721 return then(detail::mfallbacker_to<R>(boost::move(v)));
4724 template <typename R>
4725 template <typename R2>
4726 inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
4727 BOOST_THREAD_FUTURE<R>::fallback_to(R2 const& v) {
4728 return then(detail::cfallbacker_to<R>(v));
4733 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
4736 /////////////////////////
4737 /// future_unwrap_shared_state
4738 /////////////////////////
4740 template<typename F, typename Rp>
4741 struct future_unwrap_shared_state: shared_state<Rp>
4745 explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
4746 : parent(boost::move(f)) {}
4748 typename F::value_type parent_value(boost::unique_lock<boost::mutex>& ) {
4749 typename F::value_type r = parent.get();
4750 r.set_exceptional_if_invalid();
4751 return boost::move(r);
4754 virtual void wait(bool ) { // todo see if rethrow must be used
4755 boost::unique_lock<boost::mutex> lk(this->mutex);
4756 parent_value(lk).wait();
4759 boost::unique_lock<boost::mutex> lk(this->mutex);
4760 return parent_value(lk).get();
4764 template <class F, class Rp>
4765 BOOST_THREAD_FUTURE<Rp>
4766 make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f) {
4767 shared_ptr<future_unwrap_shared_state<F, Rp> >
4768 h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
4769 h->parent.future_->set_continuation_ptr(h, lock);
4770 return BOOST_THREAD_FUTURE<Rp>(h);
4774 template <typename R>
4775 inline BOOST_THREAD_FUTURE<R>::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other)
4776 : base_type(other.unwrap()) {}
4778 template <typename R2>
4779 BOOST_THREAD_FUTURE<R2>
4780 BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
4782 BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
4783 boost::unique_lock<boost::mutex> lock(this->future_->mutex);
4784 return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
4788 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
4791 struct input_iterator_tag {};
4792 struct vector_tag {};
4793 struct values_tag {};
4794 template <typename T>
4795 struct alias_t { typedef T type; };
4797 BOOST_CONSTEXPR_OR_CONST input_iterator_tag input_iterator_tag_value = {};
4798 BOOST_CONSTEXPR_OR_CONST vector_tag vector_tag_value = {};
4799 BOOST_CONSTEXPR_OR_CONST values_tag values_tag_value = {};
4800 ////////////////////////////////
4801 // detail::future_async_when_all_shared_state
4802 ////////////////////////////////
4803 template<typename F>
4804 struct future_when_all_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
4806 typedef csbl::vector<F> vector_type;
4807 typedef typename F::value_type value_type;
4810 static void run(future_when_all_vector_shared_state* that) {
4812 boost::wait_for_all(that->vec_.begin(), that->vec_.end());
4813 that->mark_finished_with_result(boost::move(that->vec_));
4814 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4815 } catch(thread_interrupted& ) {
4816 that->mark_interrupted_finish();
4819 that->mark_exceptional_finish();
4822 bool run_deferred() {
4825 for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
4826 if (! it->run_if_is_deferred())
4834 if (! run_deferred())
4836 future_when_all_vector_shared_state::run(this);
4839 this->thr_ = thread(&future_when_all_vector_shared_state::run, this);
4843 template< typename InputIterator>
4844 future_when_all_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
4845 : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
4850 future_when_all_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
4851 : vec_(boost::move(v))
4856 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4857 template< typename T0, typename ...T>
4858 future_when_all_vector_shared_state(values_tag, BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
4859 vec_.push_back(boost::forward<T0>(f));
4860 typename alias_t<char[]>::type{
4861 ( //first part of magic unpacker
4862 vec_.push_back(boost::forward<T>(futures)),'0'
4864 }; //second part of magic unpacker
4868 ~future_when_all_vector_shared_state() {
4873 ////////////////////////////////
4874 // detail::future_async_when_any_shared_state
4875 ////////////////////////////////
4876 template<typename F>
4877 struct future_when_any_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
4879 typedef csbl::vector<F> vector_type;
4880 typedef typename F::value_type value_type;
4883 static void run(future_when_any_vector_shared_state* that)
4886 boost::wait_for_any(that->vec_.begin(), that->vec_.end());
4887 that->mark_finished_with_result(boost::move(that->vec_));
4888 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4889 } catch(thread_interrupted& ) {
4890 that->mark_interrupted_finish();
4893 that->mark_exceptional_finish();
4896 bool run_deferred() {
4898 for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
4899 if (it->run_if_is_deferred_or_ready())
4909 future_when_any_vector_shared_state::run(this);
4913 this->thr_ = thread(&future_when_any_vector_shared_state::run, this);
4917 template< typename InputIterator>
4918 future_when_any_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
4919 : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
4924 future_when_any_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
4925 : vec_(boost::move(v))
4930 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4931 template< typename T0, typename ...T>
4932 future_when_any_vector_shared_state(values_tag,
4933 BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures
4935 vec_.push_back(boost::forward<T0>(f));
4936 typename alias_t<char[]>::type{
4937 ( //first part of magic unpacker
4938 vec_.push_back(boost::forward<T>(futures))
4942 }; //second part of magic unpacker
4947 ~future_when_any_vector_shared_state() {
4952 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
4953 struct wait_for_all_fctr {
4954 template <class ...T>
4955 void operator()(T&&... v) {
4956 boost::wait_for_all(boost::forward<T>(v)...);
4960 struct wait_for_any_fctr {
4961 template <class ...T>
4962 void operator()(T&&... v) {
4963 boost::wait_for_any(boost::forward<T>(v)...);
4968 template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
4969 struct accumulate_run_if_is_deferred {
4970 bool operator ()(Tuple& t)
4972 return (! csbl::get<i-1>(t).run_if_is_deferred()) || accumulate_run_if_is_deferred<Tuple,i-1>()(t);
4975 template <class Tuple>
4976 struct accumulate_run_if_is_deferred<Tuple, 0> {
4977 bool operator ()(Tuple& )
4984 template< typename Tuple, typename T0, typename ...T>
4985 struct future_when_all_tuple_shared_state: future_async_shared_state_base<Tuple>
4988 typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
4990 static void run(future_when_all_tuple_shared_state* that) {
4992 // TODO make use of apply(that->tup_, boost::detail::wait_for_all_fctor());
4993 that->wait_for_all(Index());
4995 that->mark_finished_with_result(boost::move(that->tup_));
4996 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
4997 } catch(thread_interrupted& ) {
4998 that->mark_interrupted_finish();
5001 that->mark_exceptional_finish();
5005 template <size_t ...Indices>
5006 void wait_for_all(tuple_indices<Indices...>) {
5007 #if defined BOOST_THREAD_PROVIDES_INVOKE
5008 return invoke<void>(wait_for_all_fctr(), csbl::get<Indices>(tup_)...);
5010 return wait_for_all_fctr()(csbl::get<Indices>(tup_)...);
5014 bool run_deferred() {
5016 return accumulate_run_if_is_deferred<Tuple>()(tup_);
5019 if (! run_deferred())
5021 future_when_all_tuple_shared_state::run(this);
5025 this->thr_ = thread(&future_when_all_tuple_shared_state::run, this);
5028 template< typename F, typename ...Fs>
5029 future_when_all_tuple_shared_state(values_tag, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures) :
5030 tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5034 ~future_when_all_tuple_shared_state() {
5041 template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
5042 struct apply_any_run_if_is_deferred_or_ready {
5043 bool operator ()(Tuple& t)
5045 if (csbl::get<i-1>(t).run_if_is_deferred_or_ready()) return true;
5046 return apply_any_run_if_is_deferred_or_ready<Tuple,i-1>()(t);
5049 template <class Tuple>
5050 struct apply_any_run_if_is_deferred_or_ready<Tuple, 0> {
5051 bool operator ()(Tuple& )
5057 template< typename Tuple, typename T0, typename ...T >
5058 struct future_when_any_tuple_shared_state: future_async_shared_state_base<Tuple>
5061 typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
5063 static void run(future_when_any_tuple_shared_state* that)
5066 // TODO make use of apply(that->tup_, wait_for_any_fctr);
5067 that->wait_for_any(Index());
5069 that->mark_finished_with_result(boost::move(that->tup_));
5070 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
5071 } catch(thread_interrupted& ) {
5072 that->mark_interrupted_finish();
5075 that->mark_exceptional_finish();
5078 template <size_t ...Indices>
5079 void wait_for_any(tuple_indices<Indices...>) {
5080 #if defined BOOST_THREAD_PROVIDES_INVOKE
5081 return invoke<void>(wait_for_any_fctr(), csbl::get<Indices>(tup_)...);
5083 return wait_for_any_fctr()(csbl::get<Indices>(tup_)...);
5086 bool run_deferred() {
5087 return apply_any_run_if_is_deferred_or_ready<Tuple>()(tup_);
5092 future_when_any_tuple_shared_state::run(this);
5096 this->thr_ = thread(&future_when_any_tuple_shared_state::run, this);
5100 template< typename F, typename ...Fs>
5101 future_when_any_tuple_shared_state(values_tag,
5102 BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures
5104 tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
5109 ~future_when_any_tuple_shared_state() {
5117 template< typename InputIterator>
5118 typename boost::disable_if<is_future_type<InputIterator>,
5119 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
5121 when_all(InputIterator first, InputIterator last) {
5122 typedef typename InputIterator::value_type value_type;
5123 typedef csbl::vector<value_type> container_type;
5124 typedef detail::future_when_all_vector_shared_state<value_type> factory_type;
5126 if (first==last) return make_ready_future(container_type());
5127 shared_ptr<factory_type >
5128 h(new factory_type(detail::input_iterator_tag_value, first,last));
5129 return BOOST_THREAD_FUTURE<container_type>(h);
5132 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all() {
5133 return make_ready_future(csbl::tuple<>());
5136 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5137 template< typename T0, typename ...T>
5138 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5139 when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5140 typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5141 typedef detail::future_when_all_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5143 shared_ptr<factory_type>
5144 h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5145 return BOOST_THREAD_FUTURE<container_type>(h);
5149 template< typename InputIterator>
5150 typename boost::disable_if<is_future_type<InputIterator>,
5151 BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
5153 when_any(InputIterator first, InputIterator last) {
5154 typedef typename InputIterator::value_type value_type;
5155 typedef csbl::vector<value_type> container_type;
5156 typedef detail::future_when_any_vector_shared_state<value_type> factory_type;
5158 if (first==last) return make_ready_future(container_type());
5159 shared_ptr<factory_type >
5160 h(new factory_type(detail::input_iterator_tag_value, first,last));
5161 return BOOST_THREAD_FUTURE<container_type>(h);
5164 inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any() {
5165 return make_ready_future(csbl::tuple<>());
5168 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
5169 template< typename T0, typename ...T>
5170 BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
5171 when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
5172 typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
5173 typedef detail::future_when_any_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
5175 shared_ptr<factory_type>
5176 h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
5177 return BOOST_THREAD_FUTURE<container_type>(h);
5180 #endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
5183 #endif // BOOST_NO_EXCEPTION