// -*- C++ -*- //===--------------------------- future -----------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef _LIBCPP_FUTURE #define _LIBCPP_FUTURE /* future synopsis namespace std { enum class future_errc { broken_promise, future_already_retrieved, promise_already_satisfied, no_state }; enum class launch { async = 1, deferred = 2, any = async | deferred }; enum class future_status { ready, timeout, deferred }; template <> struct is_error_code_enum : public true_type { }; error_code make_error_code(future_errc e); error_condition make_error_condition(future_errc e); const error_category& future_category(); class future_error : public logic_error { public: future_error(error_code ec); // exposition only const error_code& code() const throw(); const char* what() const throw(); }; template class promise { public: promise(); template promise(allocator_arg_t, const Allocator& a); promise(promise&& rhs); promise(const promise& rhs) = delete; ~promise(); // assignment promise& operator=(promise&& rhs); promise& operator=(const promise& rhs) = delete; void swap(promise& other); // retrieving the result future get_future(); // setting the result void set_value(const R& r); void set_value(R&& r); void set_exception(exception_ptr p); // setting the result with deferred notification void set_value_at_thread_exit(const R& r); void set_value_at_thread_exit(R&& r); void set_exception_at_thread_exit(exception_ptr p); }; template class promise { public: promise(); template promise(allocator_arg_t, const Allocator& a); promise(promise&& rhs); promise(const promise& rhs) = delete; ~promise(); // assignment promise& operator=(promise&& rhs); promise& operator=(const promise& rhs) = delete; void swap(promise& other); // retrieving the result future get_future(); // setting the result void set_value(R& r); void set_exception(exception_ptr p); // setting the result with deferred notification void set_value_at_thread_exit(R&); void set_exception_at_thread_exit(exception_ptr p); }; template <> class promise { public: promise(); template promise(allocator_arg_t, const Allocator& a); promise(promise&& rhs); promise(const promise& rhs) = delete; ~promise(); // assignment promise& operator=(promise&& rhs); promise& operator=(const promise& rhs) = delete; void swap(promise& other); // retrieving the result future get_future(); // setting the result void set_value(); void set_exception(exception_ptr p); // setting the result with deferred notification void set_value_at_thread_exit(); void set_exception_at_thread_exit(exception_ptr p); }; template void swap(promise& x, promise& y); template struct uses_allocator, Alloc> : public true_type {}; template class future { public: future(); future(future&&); future(const future& rhs) = delete; ~future(); future& operator=(const future& rhs) = delete; future& operator=(future&&); shared_future share() &&; // retrieving the value R get(); // functions to check state bool valid() const; void wait() const; template future_status wait_for(const chrono::duration& rel_time) const; template future_status wait_until(const chrono::time_point& abs_time) const; }; template class future { public: future(); future(future&&); future(const future& rhs) = delete; ~future(); future& operator=(const future& rhs) = delete; future& operator=(future&&); shared_future share() &&; // retrieving the value R& get(); // functions to check state bool valid() const; void wait() const; template future_status wait_for(const chrono::duration& rel_time) const; template future_status wait_until(const chrono::time_point& abs_time) const; }; template <> class future { public: future(); future(future&&); future(const future& rhs) = delete; ~future(); future& operator=(const future& rhs) = delete; future& operator=(future&&); shared_future share() &&; // retrieving the value void get(); // functions to check state bool valid() const; void wait() const; template future_status wait_for(const chrono::duration& rel_time) const; template future_status wait_until(const chrono::time_point& abs_time) const; }; template class shared_future { public: shared_future(); shared_future(const shared_future& rhs); shared_future(future&&); shared_future(shared_future&& rhs); ~shared_future(); shared_future& operator=(const shared_future& rhs); shared_future& operator=(shared_future&& rhs); // retrieving the value const R& get() const; // functions to check state bool valid() const; void wait() const; template future_status wait_for(const chrono::duration& rel_time) const; template future_status wait_until(const chrono::time_point& abs_time) const; }; template class shared_future { public: shared_future(); shared_future(const shared_future& rhs); shared_future(future&&); shared_future(shared_future&& rhs); ~shared_future(); shared_future& operator=(const shared_future& rhs); shared_future& operator=(shared_future&& rhs); // retrieving the value R& get() const; // functions to check state bool valid() const; void wait() const; template future_status wait_for(const chrono::duration& rel_time) const; template future_status wait_until(const chrono::time_point& abs_time) const; }; template <> class shared_future { public: shared_future(); shared_future(const shared_future& rhs); shared_future(future&&); shared_future(shared_future&& rhs); ~shared_future(); shared_future& operator=(const shared_future& rhs); shared_future& operator=(shared_future&& rhs); // retrieving the value void get() const; // functions to check state bool valid() const; void wait() const; template future_status wait_for(const chrono::duration& rel_time) const; template future_status wait_until(const chrono::time_point& abs_time) const; }; template future::type> async(F&& f, Args&&... args); template future::type> async(launch policy, F&& f, Args&&... args); template class packaged_task; // undefined template class packaged_task { public: typedef R result_type; // construction and destruction packaged_task(); template explicit packaged_task(F&& f); template explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); ~packaged_task(); // no copy packaged_task(packaged_task&) = delete; packaged_task& operator=(packaged_task&) = delete; // move support packaged_task(packaged_task&& other); packaged_task& operator=(packaged_task&& other); void swap(packaged_task& other); bool valid() const; // result retrieval future get_future(); // execution void operator()(ArgTypes... ); void make_ready_at_thread_exit(ArgTypes...); void reset(); }; template void swap(packaged_task&); template struct uses_allocator, Alloc>; } // std */ #include <__config> #include #include #include #include #include #include #pragma GCC system_header _LIBCPP_BEGIN_NAMESPACE_STD //enum class future_errc struct _LIBCPP_VISIBLE future_errc { enum _ { broken_promise, future_already_retrieved, promise_already_satisfied, no_state }; _ __v_; _LIBCPP_INLINE_VISIBILITY future_errc(_ __v) : __v_(__v) {} _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;} }; template <> struct _LIBCPP_VISIBLE is_error_code_enum : public true_type {}; //enum class launch struct _LIBCPP_VISIBLE launch { enum _ { async = 1, deferred = 2, any = async | deferred }; _ __v_; _LIBCPP_INLINE_VISIBILITY launch(_ __v) : __v_(__v) {} _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;} }; //enum class future_status struct _LIBCPP_VISIBLE future_status { enum _ { ready, timeout, deferred }; _ __v_; _LIBCPP_INLINE_VISIBILITY future_status(_ __v) : __v_(__v) {} _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;} }; _LIBCPP_VISIBLE const error_category& future_category(); inline _LIBCPP_INLINE_VISIBILITY error_code make_error_code(future_errc __e) { return error_code(static_cast(__e), future_category()); } inline _LIBCPP_INLINE_VISIBILITY error_condition make_error_condition(future_errc __e) { return error_condition(static_cast(__e), future_category()); } class _LIBCPP_EXCEPTION_ABI future_error : public logic_error { error_code __ec_; public: future_error(error_code __ec); _LIBCPP_INLINE_VISIBILITY const error_code& code() const throw() {return __ec_;} virtual ~future_error() _NOEXCEPT; }; class __assoc_sub_state : public __shared_count { protected: exception_ptr __exception_; mutable mutex __mut_; mutable condition_variable __cv_; unsigned __state_; virtual void __on_zero_shared() _NOEXCEPT; void __sub_wait(unique_lock& __lk); public: enum { __constructed = 1, __future_attached = 2, ready = 4, deferred = 8 }; _LIBCPP_INLINE_VISIBILITY __assoc_sub_state() : __state_(0) {} _LIBCPP_INLINE_VISIBILITY bool __has_value() const {return (__state_ & __constructed) || (__exception_ != nullptr);} _LIBCPP_INLINE_VISIBILITY void __set_future_attached() {__state_ |= __future_attached;} _LIBCPP_INLINE_VISIBILITY bool __has_future_attached() const {return __state_ & __future_attached;} _LIBCPP_INLINE_VISIBILITY void __set_deferred() {__state_ |= deferred;} void __make_ready(); _LIBCPP_INLINE_VISIBILITY bool __is_ready() const {return __state_ & ready;} void set_value(); void set_value_at_thread_exit(); void set_exception(exception_ptr __p); void set_exception_at_thread_exit(exception_ptr __p); void copy(); void wait(); template future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; template future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; virtual void __execute(); }; template future_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { unique_lock __lk(__mut_); if (__state_ & deferred) return future_status::deferred; while (!(__state_ & ready) && _Clock::now() < __abs_time) __cv_.wait_until(__lk, __abs_time); if (__state_ & ready) return future_status::ready; return future_status::timeout; } template inline _LIBCPP_INLINE_VISIBILITY future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { return wait_until(chrono::steady_clock::now() + __rel_time); } template class __assoc_state : public __assoc_sub_state { typedef __assoc_sub_state base; typedef typename aligned_storage::value>::type _U; protected: _U __value_; virtual void __on_zero_shared() _NOEXCEPT; public: template #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES void set_value(_Arg&& __arg); #else void set_value(_Arg& __arg); #endif template #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES void set_value_at_thread_exit(_Arg&& __arg); #else void set_value_at_thread_exit(_Arg& __arg); #endif _R move(); typename add_lvalue_reference<_R>::type copy(); }; template void __assoc_state<_R>::__on_zero_shared() _NOEXCEPT { if (this->__state_ & base::__constructed) reinterpret_cast<_R*>(&__value_)->~_R(); delete this; } template template void #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __assoc_state<_R>::set_value(_Arg&& __arg) #else __assoc_state<_R>::set_value(_Arg& __arg) #endif { unique_lock __lk(this->__mut_); #ifndef _LIBCPP_NO_EXCEPTIONS if (this->__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); #endif ::new(&__value_) _R(_VSTD::forward<_Arg>(__arg)); this->__state_ |= base::__constructed | base::ready; __lk.unlock(); __cv_.notify_all(); } template template void #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __assoc_state<_R>::set_value_at_thread_exit(_Arg&& __arg) #else __assoc_state<_R>::set_value_at_thread_exit(_Arg& __arg) #endif { unique_lock __lk(this->__mut_); #ifndef _LIBCPP_NO_EXCEPTIONS if (this->__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); #endif ::new(&__value_) _R(_VSTD::forward<_Arg>(__arg)); this->__state_ |= base::__constructed; __thread_local_data()->__make_ready_at_thread_exit(this); __lk.unlock(); } template _R __assoc_state<_R>::move() { unique_lock __lk(this->__mut_); this->__sub_wait(__lk); if (this->__exception_ != nullptr) rethrow_exception(this->__exception_); return _VSTD::move(*reinterpret_cast<_R*>(&__value_)); } template typename add_lvalue_reference<_R>::type __assoc_state<_R>::copy() { unique_lock __lk(this->__mut_); this->__sub_wait(__lk); if (this->__exception_ != nullptr) rethrow_exception(this->__exception_); return *reinterpret_cast<_R*>(&__value_); } template class __assoc_state<_R&> : public __assoc_sub_state { typedef __assoc_sub_state base; typedef _R* _U; protected: _U __value_; virtual void __on_zero_shared() _NOEXCEPT; public: void set_value(_R& __arg); void set_value_at_thread_exit(_R& __arg); _R& copy(); }; template void __assoc_state<_R&>::__on_zero_shared() _NOEXCEPT { delete this; } template void __assoc_state<_R&>::set_value(_R& __arg) { unique_lock __lk(this->__mut_); #ifndef _LIBCPP_NO_EXCEPTIONS if (this->__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); #endif __value_ = &__arg; this->__state_ |= base::__constructed | base::ready; __lk.unlock(); __cv_.notify_all(); } template void __assoc_state<_R&>::set_value_at_thread_exit(_R& __arg) { unique_lock __lk(this->__mut_); #ifndef _LIBCPP_NO_EXCEPTIONS if (this->__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); #endif __value_ = &__arg; this->__state_ |= base::__constructed; __thread_local_data()->__make_ready_at_thread_exit(this); __lk.unlock(); } template _R& __assoc_state<_R&>::copy() { unique_lock __lk(this->__mut_); this->__sub_wait(__lk); if (this->__exception_ != nullptr) rethrow_exception(this->__exception_); return *__value_; } template class __assoc_state_alloc : public __assoc_state<_R> { typedef __assoc_state<_R> base; _Alloc __alloc_; virtual void __on_zero_shared() _NOEXCEPT; public: _LIBCPP_INLINE_VISIBILITY explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {} }; template void __assoc_state_alloc<_R, _Alloc>::__on_zero_shared() _NOEXCEPT { if (this->__state_ & base::__constructed) reinterpret_cast<_R*>(&this->__value_)->~_R(); typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_); this->~__assoc_state_alloc(); __a.deallocate(this, 1); } template class __assoc_state_alloc<_R&, _Alloc> : public __assoc_state<_R&> { typedef __assoc_state<_R&> base; _Alloc __alloc_; virtual void __on_zero_shared() _NOEXCEPT; public: _LIBCPP_INLINE_VISIBILITY explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {} }; template void __assoc_state_alloc<_R&, _Alloc>::__on_zero_shared() _NOEXCEPT { typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_); this->~__assoc_state_alloc(); __a.deallocate(this, 1); } template class __assoc_sub_state_alloc : public __assoc_sub_state { typedef __assoc_sub_state base; _Alloc __alloc_; virtual void __on_zero_shared() _NOEXCEPT; public: _LIBCPP_INLINE_VISIBILITY explicit __assoc_sub_state_alloc(const _Alloc& __a) : __alloc_(__a) {} }; template void __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT { this->~base(); typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_); this->~__assoc_sub_state_alloc(); __a.deallocate(this, 1); } template class __deferred_assoc_state : public __assoc_state<_R> { typedef __assoc_state<_R> base; _F __func_; public: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES explicit __deferred_assoc_state(_F&& __f); #endif virtual void __execute(); }; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template inline _LIBCPP_INLINE_VISIBILITY __deferred_assoc_state<_R, _F>::__deferred_assoc_state(_F&& __f) : __func_(_VSTD::forward<_F>(__f)) { this->__set_deferred(); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template void __deferred_assoc_state<_R, _F>::__execute() { #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS this->set_value(__func_()); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { this->set_exception(current_exception()); } #endif // _LIBCPP_NO_EXCEPTIONS } template class __deferred_assoc_state : public __assoc_sub_state { typedef __assoc_sub_state base; _F __func_; public: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES explicit __deferred_assoc_state(_F&& __f); #endif virtual void __execute(); }; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template inline _LIBCPP_INLINE_VISIBILITY __deferred_assoc_state::__deferred_assoc_state(_F&& __f) : __func_(_VSTD::forward<_F>(__f)) { this->__set_deferred(); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template void __deferred_assoc_state::__execute() { #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS __func_(); this->set_value(); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { this->set_exception(current_exception()); } #endif // _LIBCPP_NO_EXCEPTIONS } template class __async_assoc_state : public __assoc_state<_R> { typedef __assoc_state<_R> base; _F __func_; virtual void __on_zero_shared() _NOEXCEPT; public: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES explicit __async_assoc_state(_F&& __f); #endif virtual void __execute(); }; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template inline _LIBCPP_INLINE_VISIBILITY __async_assoc_state<_R, _F>::__async_assoc_state(_F&& __f) : __func_(_VSTD::forward<_F>(__f)) { } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template void __async_assoc_state<_R, _F>::__execute() { #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS this->set_value(__func_()); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { this->set_exception(current_exception()); } #endif // _LIBCPP_NO_EXCEPTIONS } template void __async_assoc_state<_R, _F>::__on_zero_shared() _NOEXCEPT { this->wait(); base::__on_zero_shared(); } template class __async_assoc_state : public __assoc_sub_state { typedef __assoc_sub_state base; _F __func_; virtual void __on_zero_shared() _NOEXCEPT; public: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES explicit __async_assoc_state(_F&& __f); #endif virtual void __execute(); }; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template inline _LIBCPP_INLINE_VISIBILITY __async_assoc_state::__async_assoc_state(_F&& __f) : __func_(_VSTD::forward<_F>(__f)) { } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template void __async_assoc_state::__execute() { #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS __func_(); this->set_value(); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { this->set_exception(current_exception()); } #endif // _LIBCPP_NO_EXCEPTIONS } template void __async_assoc_state::__on_zero_shared() _NOEXCEPT { this->wait(); base::__on_zero_shared(); } template class promise; template class shared_future; // future template class future; template future<_R> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __make_deferred_assoc_state(_F&& __f); #else __make_deferred_assoc_state(_F __f); #endif template future<_R> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __make_async_assoc_state(_F&& __f); #else __make_async_assoc_state(_F __f); #endif template class _LIBCPP_VISIBLE future { __assoc_state<_R>* __state_; explicit future(__assoc_state<_R>* __state); template friend class promise; template friend class shared_future; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template friend future<_R1> __make_deferred_assoc_state(_F&& __f); template friend future<_R1> __make_async_assoc_state(_F&& __f); #else template friend future<_R1> __make_deferred_assoc_state(_F __f); template friend future<_R1> __make_async_assoc_state(_F __f); #endif public: _LIBCPP_INLINE_VISIBILITY future() : __state_(nullptr) {} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY future(future&& __rhs) : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} future(const future&) = delete; future& operator=(const future&) = delete; _LIBCPP_INLINE_VISIBILITY future& operator=(future&& __rhs) { future(std::move(__rhs)).swap(*this); return *this; } #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES private: future(const future&); future& operator=(const future&); public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~future(); shared_future<_R> share(); // retrieving the value _R get(); _LIBCPP_INLINE_VISIBILITY void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);} // functions to check state _LIBCPP_INLINE_VISIBILITY bool valid() const {return __state_ != nullptr;} _LIBCPP_INLINE_VISIBILITY void wait() const {__state_->wait();} template _LIBCPP_INLINE_VISIBILITY future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {return __state_->wait_for(__rel_time);} template _LIBCPP_INLINE_VISIBILITY future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {return __state_->wait_until(__abs_time);} }; template future<_R>::future(__assoc_state<_R>* __state) : __state_(__state) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_->__has_future_attached()) throw future_error(make_error_code(future_errc::future_already_retrieved)); #endif __state_->__add_shared(); __state_->__set_future_attached(); } struct __release_shared_count { void operator()(__shared_count* p) {p->__release_shared();} }; template future<_R>::~future() { if (__state_) __state_->__release_shared(); } template _R future<_R>::get() { unique_ptr<__shared_count, __release_shared_count> __(__state_); __assoc_state<_R>* __s = __state_; __state_ = nullptr; return __s->move(); } template class _LIBCPP_VISIBLE future<_R&> { __assoc_state<_R&>* __state_; explicit future(__assoc_state<_R&>* __state); template friend class promise; template friend class shared_future; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template friend future<_R1> __make_deferred_assoc_state(_F&& __f); template friend future<_R1> __make_async_assoc_state(_F&& __f); #else template friend future<_R1> __make_deferred_assoc_state(_F __f); template friend future<_R1> __make_async_assoc_state(_F __f); #endif public: _LIBCPP_INLINE_VISIBILITY future() : __state_(nullptr) {} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY future(future&& __rhs) : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} future(const future&) = delete; future& operator=(const future&) = delete; _LIBCPP_INLINE_VISIBILITY future& operator=(future&& __rhs) { future(std::move(__rhs)).swap(*this); return *this; } #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES private: future(const future&); future& operator=(const future&); public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~future(); shared_future<_R&> share(); // retrieving the value _R& get(); _LIBCPP_INLINE_VISIBILITY void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);} // functions to check state _LIBCPP_INLINE_VISIBILITY bool valid() const {return __state_ != nullptr;} _LIBCPP_INLINE_VISIBILITY void wait() const {__state_->wait();} template _LIBCPP_INLINE_VISIBILITY future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {return __state_->wait_for(__rel_time);} template _LIBCPP_INLINE_VISIBILITY future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {return __state_->wait_until(__abs_time);} }; template future<_R&>::future(__assoc_state<_R&>* __state) : __state_(__state) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_->__has_future_attached()) throw future_error(make_error_code(future_errc::future_already_retrieved)); #endif __state_->__add_shared(); __state_->__set_future_attached(); } template future<_R&>::~future() { if (__state_) __state_->__release_shared(); } template _R& future<_R&>::get() { unique_ptr<__shared_count, __release_shared_count> __(__state_); __assoc_state<_R&>* __s = __state_; __state_ = nullptr; return __s->copy(); } template <> class _LIBCPP_VISIBLE future { __assoc_sub_state* __state_; explicit future(__assoc_sub_state* __state); template friend class promise; template friend class shared_future; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template friend future<_R1> __make_deferred_assoc_state(_F&& __f); template friend future<_R1> __make_async_assoc_state(_F&& __f); #else template friend future<_R1> __make_deferred_assoc_state(_F __f); template friend future<_R1> __make_async_assoc_state(_F __f); #endif public: _LIBCPP_INLINE_VISIBILITY future() : __state_(nullptr) {} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY future(future&& __rhs) : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} future(const future&) = delete; future& operator=(const future&) = delete; _LIBCPP_INLINE_VISIBILITY future& operator=(future&& __rhs) { future(std::move(__rhs)).swap(*this); return *this; } #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES private: future(const future&); future& operator=(const future&); public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~future(); shared_future share(); // retrieving the value void get(); _LIBCPP_INLINE_VISIBILITY void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);} // functions to check state _LIBCPP_INLINE_VISIBILITY bool valid() const {return __state_ != nullptr;} _LIBCPP_INLINE_VISIBILITY void wait() const {__state_->wait();} template _LIBCPP_INLINE_VISIBILITY future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {return __state_->wait_for(__rel_time);} template _LIBCPP_INLINE_VISIBILITY future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {return __state_->wait_until(__abs_time);} }; template inline _LIBCPP_INLINE_VISIBILITY void swap(future<_R>& __x, future<_R>& __y) { __x.swap(__y); } // promise template class packaged_task; template class _LIBCPP_VISIBLE promise { __assoc_state<_R>* __state_; _LIBCPP_INLINE_VISIBILITY explicit promise(nullptr_t) : __state_(nullptr) {} template friend class packaged_task; public: promise(); template promise(allocator_arg_t, const _Alloc& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY promise(promise&& __rhs) : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} promise(const promise& __rhs) = delete; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES private: promise(const promise& __rhs); public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~promise(); // assignment #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY promise& operator=(promise&& __rhs) { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise& __rhs) = delete; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES private: promise& operator=(const promise& __rhs); public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);} // retrieving the result future<_R> get_future(); // setting the result void set_value(const _R& __r); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES void set_value(_R&& __r); #endif void set_exception(exception_ptr __p); // setting the result with deferred notification void set_value_at_thread_exit(const _R& __r); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES void set_value_at_thread_exit(_R&& __r); #endif void set_exception_at_thread_exit(exception_ptr __p); }; template promise<_R>::promise() : __state_(new __assoc_state<_R>) { } template template promise<_R>::promise(allocator_arg_t, const _Alloc& __a0) { typedef typename _Alloc::template rebind<__assoc_state_alloc<_R, _Alloc> >::other _A2; typedef __allocator_destructor<_A2> _D2; _A2 __a(__a0); unique_ptr<__assoc_state_alloc<_R, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1)); ::new(__hold.get()) __assoc_state_alloc<_R, _Alloc>(__a0); __state_ = __hold.release(); } template promise<_R>::~promise() { if (__state_) { if (!__state_->__has_value() && __state_->use_count() > 1) __state_->set_exception(make_exception_ptr( future_error(make_error_code(future_errc::broken_promise)) )); __state_->__release_shared(); } } template future<_R> promise<_R>::get_future() { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif return future<_R>(__state_); } template void promise<_R>::set_value(const _R& __r) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_value(__r); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template void promise<_R>::set_value(_R&& __r) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_value(_VSTD::move(__r)); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template void promise<_R>::set_exception(exception_ptr __p) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_exception(__p); } template void promise<_R>::set_value_at_thread_exit(const _R& __r) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_value_at_thread_exit(__r); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template void promise<_R>::set_value_at_thread_exit(_R&& __r) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_value_at_thread_exit(_VSTD::move(__r)); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template void promise<_R>::set_exception_at_thread_exit(exception_ptr __p) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_exception_at_thread_exit(__p); } // promise template class _LIBCPP_VISIBLE promise<_R&> { __assoc_state<_R&>* __state_; _LIBCPP_INLINE_VISIBILITY explicit promise(nullptr_t) : __state_(nullptr) {} template friend class packaged_task; public: promise(); template promise(allocator_arg_t, const _Allocator& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY promise(promise&& __rhs) : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} promise(const promise& __rhs) = delete; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES private: promise(const promise& __rhs); public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~promise(); // assignment #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY promise& operator=(promise&& __rhs) { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise& __rhs) = delete; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES private: promise& operator=(const promise& __rhs); public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);} // retrieving the result future<_R&> get_future(); // setting the result void set_value(_R& __r); void set_exception(exception_ptr __p); // setting the result with deferred notification void set_value_at_thread_exit(_R&); void set_exception_at_thread_exit(exception_ptr __p); }; template promise<_R&>::promise() : __state_(new __assoc_state<_R&>) { } template template promise<_R&>::promise(allocator_arg_t, const _Alloc& __a0) { typedef typename _Alloc::template rebind<__assoc_state_alloc<_R&, _Alloc> >::other _A2; typedef __allocator_destructor<_A2> _D2; _A2 __a(__a0); unique_ptr<__assoc_state_alloc<_R&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1)); ::new(__hold.get()) __assoc_state_alloc<_R&, _Alloc>(__a0); __state_ = __hold.release(); } template promise<_R&>::~promise() { if (__state_) { if (!__state_->__has_value() && __state_->use_count() > 1) __state_->set_exception(make_exception_ptr( future_error(make_error_code(future_errc::broken_promise)) )); __state_->__release_shared(); } } template future<_R&> promise<_R&>::get_future() { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif return future<_R&>(__state_); } template void promise<_R&>::set_value(_R& __r) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_value(__r); } template void promise<_R&>::set_exception(exception_ptr __p) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_exception(__p); } template void promise<_R&>::set_value_at_thread_exit(_R& __r) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_value_at_thread_exit(__r); } template void promise<_R&>::set_exception_at_thread_exit(exception_ptr __p) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); #endif __state_->set_exception_at_thread_exit(__p); } // promise template <> class _LIBCPP_VISIBLE promise { __assoc_sub_state* __state_; _LIBCPP_INLINE_VISIBILITY explicit promise(nullptr_t) : __state_(nullptr) {} template friend class packaged_task; public: promise(); template promise(allocator_arg_t, const _Allocator& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY promise(promise&& __rhs) : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} promise(const promise& __rhs) = delete; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES private: promise(const promise& __rhs); public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~promise(); // assignment #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY promise& operator=(promise&& __rhs) { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise& __rhs) = delete; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES private: promise& operator=(const promise& __rhs); public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);} // retrieving the result future get_future(); // setting the result void set_value(); void set_exception(exception_ptr __p); // setting the result with deferred notification void set_value_at_thread_exit(); void set_exception_at_thread_exit(exception_ptr __p); }; template promise::promise(allocator_arg_t, const _Alloc& __a0) { typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2; typedef __allocator_destructor<_A2> _D2; _A2 __a(__a0); unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1)); ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0); __state_ = __hold.release(); } template inline _LIBCPP_INLINE_VISIBILITY void swap(promise<_R>& __x, promise<_R>& __y) { __x.swap(__y); } template struct _LIBCPP_VISIBLE uses_allocator, _Alloc> : public true_type {}; #ifndef _LIBCPP_HAS_NO_VARIADICS // packaged_task template class __packaged_task_base; template class __packaged_task_base<_R(_ArgTypes...)> { __packaged_task_base(const __packaged_task_base&); __packaged_task_base& operator=(const __packaged_task_base&); public: _LIBCPP_INLINE_VISIBILITY __packaged_task_base() {} _LIBCPP_INLINE_VISIBILITY virtual ~__packaged_task_base() {} virtual void __move_to(__packaged_task_base*) = 0; virtual void destroy() = 0; virtual void destroy_deallocate() = 0; virtual _R operator()(_ArgTypes&& ...) = 0; }; template class __packaged_task_func; template class __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)> : public __packaged_task_base<_R(_ArgTypes...)> { __compressed_pair<_F, _Alloc> __f_; public: _LIBCPP_INLINE_VISIBILITY explicit __packaged_task_func(const _F& __f) : __f_(__f) {} _LIBCPP_INLINE_VISIBILITY explicit __packaged_task_func(_F&& __f) : __f_(_VSTD::move(__f)) {} _LIBCPP_INLINE_VISIBILITY __packaged_task_func(const _F& __f, const _Alloc& __a) : __f_(__f, __a) {} _LIBCPP_INLINE_VISIBILITY __packaged_task_func(_F&& __f, const _Alloc& __a) : __f_(_VSTD::move(__f), __a) {} virtual void __move_to(__packaged_task_base<_R(_ArgTypes...)>*); virtual void destroy(); virtual void destroy_deallocate(); virtual _R operator()(_ArgTypes&& ... __args); }; template void __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::__move_to( __packaged_task_base<_R(_ArgTypes...)>* __p) { ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second())); } template void __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy() { __f_.~__compressed_pair<_F, _Alloc>(); } template void __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy_deallocate() { typedef typename _Alloc::template rebind<__packaged_task_func>::other _A; _A __a(__f_.second()); __f_.~__compressed_pair<_F, _Alloc>(); __a.deallocate(this, 1); } template _R __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) { return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); } template class __packaged_task_function; template class __packaged_task_function<_R(_ArgTypes...)> { typedef __packaged_task_base<_R(_ArgTypes...)> __base; aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; public: typedef _R result_type; // construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY __packaged_task_function() : __f_(nullptr) {} template __packaged_task_function(_F&& __f); template __packaged_task_function(allocator_arg_t, const _Alloc& __a, _F&& __f); __packaged_task_function(__packaged_task_function&&); __packaged_task_function& operator=(__packaged_task_function&&); __packaged_task_function(const __packaged_task_function&) = delete; __packaged_task_function& operator=(const __packaged_task_function&) = delete; ~__packaged_task_function(); void swap(__packaged_task_function&); _R operator()(_ArgTypes...) const; }; template __packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) { if (__f.__f_ == nullptr) __f_ = nullptr; else if (__f.__f_ == (__base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__move_to(__f_); } else { __f_ = __f.__f_; __f.__f_ = nullptr; } } template template __packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(_F&& __f) : __f_(nullptr) { typedef typename remove_reference<_F>::type _FR; typedef __packaged_task_func<_FR, allocator<_FR>, _R(_ArgTypes...)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new (__f_) _FF(_VSTD::forward<_F>(__f)); } else { typedef allocator<_FF> _A; _A __a; typedef __allocator_destructor<_A> _D; unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1)); ::new (__hold.get()) _FF(_VSTD::forward<_F>(__f), allocator<_FR>(__a)); __f_ = __hold.release(); } } template template __packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function( allocator_arg_t, const _Alloc& __a0, _F&& __f) : __f_(nullptr) { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename remove_reference<_F>::type _FR; typedef __packaged_task_func<_FR, _Alloc, _R(_ArgTypes...)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new (__f_) _FF(_VSTD::forward<_F>(__f)); } else { typedef typename __alloc_traits::template #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES rebind_alloc<_FF> #else rebind_alloc<_FF>::other #endif _A; _A __a(__a0); typedef __allocator_destructor<_A> _D; unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1)); ::new (__hold.get()) _FF(_VSTD::forward<_F>(__f), _Alloc(__a)); __f_ = __hold.release(); } } template __packaged_task_function<_R(_ArgTypes...)>& __packaged_task_function<_R(_ArgTypes...)>::operator=(__packaged_task_function&& __f) { if (__f_ == (__base*)&__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); __f_ = nullptr; if (__f.__f_ == nullptr) __f_ = nullptr; else if (__f.__f_ == (__base*)&__f.__buf_) { __f_ = (__base*)&__buf_; __f.__f_->__move_to(__f_); } else { __f_ = __f.__f_; __f.__f_ = nullptr; } } template __packaged_task_function<_R(_ArgTypes...)>::~__packaged_task_function() { if (__f_ == (__base*)&__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); } template void __packaged_task_function<_R(_ArgTypes...)>::swap(__packaged_task_function& __f) { if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { typename aligned_storage::type __tempbuf; __base* __t = (__base*)&__tempbuf; __f_->__move_to(__t); __f_->destroy(); __f_ = nullptr; __f.__f_->__move_to((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = nullptr; __f_ = (__base*)&__buf_; __t->__move_to((__base*)&__f.__buf_); __t->destroy(); __f.__f_ = (__base*)&__f.__buf_; } else if (__f_ == (__base*)&__buf_) { __f_->__move_to((__base*)&__f.__buf_); __f_->destroy(); __f_ = __f.__f_; __f.__f_ = (__base*)&__f.__buf_; } else if (__f.__f_ == (__base*)&__f.__buf_) { __f.__f_->__move_to((__base*)&__buf_); __f.__f_->destroy(); __f.__f_ = __f_; __f_ = (__base*)&__buf_; } else _VSTD::swap(__f_, __f.__f_); } template inline _LIBCPP_INLINE_VISIBILITY _R __packaged_task_function<_R(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); } template class _LIBCPP_VISIBLE packaged_task<_R(_ArgTypes...)> { public: typedef _R result_type; private: __packaged_task_function __f_; promise __p_; public: // construction and destruction _LIBCPP_INLINE_VISIBILITY packaged_task() : __p_(nullptr) {} template _LIBCPP_INLINE_VISIBILITY explicit packaged_task(_F&& __f) : __f_(_VSTD::forward<_F>(__f)) {} template _LIBCPP_INLINE_VISIBILITY explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f) : __f_(allocator_arg, __a, _VSTD::forward<_F>(__f)), __p_(allocator_arg, __a) {} // ~packaged_task() = default; // no copy packaged_task(packaged_task&) = delete; packaged_task& operator=(packaged_task&) = delete; // move support _LIBCPP_INLINE_VISIBILITY packaged_task(packaged_task&& __other) : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} _LIBCPP_INLINE_VISIBILITY packaged_task& operator=(packaged_task&& __other) { __f_ = _VSTD::move(__other.__f_); __p_ = _VSTD::move(__other.__p_); return *this; } _LIBCPP_INLINE_VISIBILITY void swap(packaged_task& __other) { __f_.swap(__other.__f_); __p_.swap(__other.__p_); } _LIBCPP_INLINE_VISIBILITY bool valid() const {return __p_.__state_ != nullptr;} // result retrieval _LIBCPP_INLINE_VISIBILITY future get_future() {return __p_.get_future();} // execution void operator()(_ArgTypes... __args); void make_ready_at_thread_exit(_ArgTypes... __args); void reset(); }; template void packaged_task<_R(_ArgTypes...)>::operator()(_ArgTypes... __args) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__p_.__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); if (__p_.__state_->__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); try { #endif // _LIBCPP_NO_EXCEPTIONS __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { __p_.set_exception(current_exception()); } #endif // _LIBCPP_NO_EXCEPTIONS } template void packaged_task<_R(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__p_.__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); if (__p_.__state_->__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); try { #endif // _LIBCPP_NO_EXCEPTIONS __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...)); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { __p_.set_exception_at_thread_exit(current_exception()); } #endif // _LIBCPP_NO_EXCEPTIONS } template void packaged_task<_R(_ArgTypes...)>::reset() { #ifndef _LIBCPP_NO_EXCEPTIONS if (!valid()) throw future_error(make_error_code(future_errc::no_state)); #endif // _LIBCPP_NO_EXCEPTIONS __p_ = promise(); } template class _LIBCPP_VISIBLE packaged_task { public: typedef void result_type; private: __packaged_task_function __f_; promise __p_; public: // construction and destruction _LIBCPP_INLINE_VISIBILITY packaged_task() : __p_(nullptr) {} template _LIBCPP_INLINE_VISIBILITY explicit packaged_task(_F&& __f) : __f_(_VSTD::forward<_F>(__f)) {} template _LIBCPP_INLINE_VISIBILITY explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f) : __f_(allocator_arg, __a, _VSTD::forward<_F>(__f)), __p_(allocator_arg, __a) {} // ~packaged_task() = default; // no copy packaged_task(packaged_task&) = delete; packaged_task& operator=(packaged_task&) = delete; // move support _LIBCPP_INLINE_VISIBILITY packaged_task(packaged_task&& __other) : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {} _LIBCPP_INLINE_VISIBILITY packaged_task& operator=(packaged_task&& __other) { __f_ = _VSTD::move(__other.__f_); __p_ = _VSTD::move(__other.__p_); return *this; } _LIBCPP_INLINE_VISIBILITY void swap(packaged_task& __other) { __f_.swap(__other.__f_); __p_.swap(__other.__p_); } _LIBCPP_INLINE_VISIBILITY bool valid() const {return __p_.__state_ != nullptr;} // result retrieval _LIBCPP_INLINE_VISIBILITY future get_future() {return __p_.get_future();} // execution void operator()(_ArgTypes... __args); void make_ready_at_thread_exit(_ArgTypes... __args); void reset(); }; template void packaged_task::operator()(_ArgTypes... __args) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__p_.__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); if (__p_.__state_->__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); try { #endif // _LIBCPP_NO_EXCEPTIONS __f_(_VSTD::forward<_ArgTypes>(__args)...); __p_.set_value(); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { __p_.set_exception(current_exception()); } #endif // _LIBCPP_NO_EXCEPTIONS } template void packaged_task::make_ready_at_thread_exit(_ArgTypes... __args) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__p_.__state_ == nullptr) throw future_error(make_error_code(future_errc::no_state)); if (__p_.__state_->__has_value()) throw future_error(make_error_code(future_errc::promise_already_satisfied)); try { #endif // _LIBCPP_NO_EXCEPTIONS __f_(_VSTD::forward<_ArgTypes>(__args)...); __p_.set_value_at_thread_exit(); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { __p_.set_exception_at_thread_exit(current_exception()); } #endif // _LIBCPP_NO_EXCEPTIONS } template void packaged_task::reset() { #ifndef _LIBCPP_NO_EXCEPTIONS if (!valid()) throw future_error(make_error_code(future_errc::no_state)); #endif // _LIBCPP_NO_EXCEPTIONS __p_ = promise(); } template inline _LIBCPP_INLINE_VISIBILITY void swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) { __x.swap(__y); } template struct _LIBCPP_VISIBLE uses_allocator, _Alloc> : public true_type {}; template future<_R> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __make_deferred_assoc_state(_F&& __f) #else __make_deferred_assoc_state(_F __f) #endif { unique_ptr<__deferred_assoc_state<_R, _F>, __release_shared_count> __h(new __deferred_assoc_state<_R, _F>(_VSTD::forward<_F>(__f))); return future<_R>(__h.get()); } template future<_R> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __make_async_assoc_state(_F&& __f) #else __make_async_assoc_state(_F __f) #endif { unique_ptr<__async_assoc_state<_R, _F>, __release_shared_count> __h(new __async_assoc_state<_R, _F>(_VSTD::forward<_F>(__f))); _VSTD::thread(&__async_assoc_state<_R, _F>::__execute, __h.get()).detach(); return future<_R>(__h.get()); } template class __async_func { tuple<_F, _Args...> __f_; public: typedef typename __invoke_of<_F, _Args...>::type _R; _LIBCPP_INLINE_VISIBILITY explicit __async_func(_F&& __f, _Args&&... __args) : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {} _LIBCPP_INLINE_VISIBILITY __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {} _R operator()() { typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index; return __execute(_Index()); } private: template _R __execute(__tuple_indices<_Indices...>) { return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); } }; template future::type, typename decay<_Args>::type...>::type> async(launch __policy, _F&& __f, _Args&&... __args) { typedef __async_func::type, typename decay<_Args>::type...> _BF; typedef typename _BF::_R _R; future<_R> __r; if (__policy & launch::async) __r = _VSTD::__make_async_assoc_state<_R>(_BF(__decay_copy(_VSTD::forward<_F>(__f)), __decay_copy(_VSTD::forward<_Args>(__args))...)); else if (__policy & launch::deferred) __r = _VSTD::__make_deferred_assoc_state<_R>(_BF(__decay_copy(_VSTD::forward<_F>(__f)), __decay_copy(_VSTD::forward<_Args>(__args))...)); return __r; } template inline _LIBCPP_INLINE_VISIBILITY future::type, typename decay<_Args>::type...>::type> async(_F&& __f, _Args&&... __args) { return _VSTD::async(launch::any, _VSTD::forward<_F>(__f), _VSTD::forward<_Args>(__args)...); } #endif // _LIBCPP_HAS_NO_VARIADICS // shared_future template class _LIBCPP_VISIBLE shared_future { __assoc_state<_R>* __state_; public: _LIBCPP_INLINE_VISIBILITY shared_future() : __state_(nullptr) {} _LIBCPP_INLINE_VISIBILITY shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {if (__state_) __state_->__add_shared();} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY shared_future(future<_R>&& __f) : __state_(__f.__state_) {__f.__state_ = nullptr;} _LIBCPP_INLINE_VISIBILITY shared_future(shared_future&& __rhs) : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~shared_future(); shared_future& operator=(const shared_future& __rhs); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY shared_future& operator=(shared_future&& __rhs) { shared_future(std::move(__rhs)).swap(*this); return *this; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES // retrieving the value _LIBCPP_INLINE_VISIBILITY const _R& get() const {return __state_->copy();} _LIBCPP_INLINE_VISIBILITY void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);} // functions to check state _LIBCPP_INLINE_VISIBILITY bool valid() const {return __state_ != nullptr;} _LIBCPP_INLINE_VISIBILITY void wait() const {__state_->wait();} template _LIBCPP_INLINE_VISIBILITY future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {return __state_->wait_for(__rel_time);} template _LIBCPP_INLINE_VISIBILITY future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {return __state_->wait_until(__abs_time);} }; template shared_future<_R>::~shared_future() { if (__state_) __state_->__release_shared(); } template shared_future<_R>& shared_future<_R>::operator=(const shared_future& __rhs) { if (__rhs.__state_) __rhs.__state_->__add_shared(); if (__state_) __state_->__release_shared(); __state_ = __rhs.__state_; return *this; } template class _LIBCPP_VISIBLE shared_future<_R&> { __assoc_state<_R&>* __state_; public: _LIBCPP_INLINE_VISIBILITY shared_future() : __state_(nullptr) {} _LIBCPP_INLINE_VISIBILITY shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {if (__state_) __state_->__add_shared();} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY shared_future(future<_R&>&& __f) : __state_(__f.__state_) {__f.__state_ = nullptr;} _LIBCPP_INLINE_VISIBILITY shared_future(shared_future&& __rhs) : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~shared_future(); shared_future& operator=(const shared_future& __rhs); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY shared_future& operator=(shared_future&& __rhs) { shared_future(std::move(__rhs)).swap(*this); return *this; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES // retrieving the value _LIBCPP_INLINE_VISIBILITY _R& get() const {return __state_->copy();} _LIBCPP_INLINE_VISIBILITY void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);} // functions to check state _LIBCPP_INLINE_VISIBILITY bool valid() const {return __state_ != nullptr;} _LIBCPP_INLINE_VISIBILITY void wait() const {__state_->wait();} template _LIBCPP_INLINE_VISIBILITY future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {return __state_->wait_for(__rel_time);} template _LIBCPP_INLINE_VISIBILITY future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {return __state_->wait_until(__abs_time);} }; template shared_future<_R&>::~shared_future() { if (__state_) __state_->__release_shared(); } template shared_future<_R&>& shared_future<_R&>::operator=(const shared_future& __rhs) { if (__rhs.__state_) __rhs.__state_->__add_shared(); if (__state_) __state_->__release_shared(); __state_ = __rhs.__state_; return *this; } template <> class _LIBCPP_VISIBLE shared_future { __assoc_sub_state* __state_; public: _LIBCPP_INLINE_VISIBILITY shared_future() : __state_(nullptr) {} _LIBCPP_INLINE_VISIBILITY shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {if (__state_) __state_->__add_shared();} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY shared_future(future&& __f) : __state_(__f.__state_) {__f.__state_ = nullptr;} _LIBCPP_INLINE_VISIBILITY shared_future(shared_future&& __rhs) : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~shared_future(); shared_future& operator=(const shared_future& __rhs); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY shared_future& operator=(shared_future&& __rhs) { shared_future(std::move(__rhs)).swap(*this); return *this; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES // retrieving the value _LIBCPP_INLINE_VISIBILITY void get() const {__state_->copy();} _LIBCPP_INLINE_VISIBILITY void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);} // functions to check state _LIBCPP_INLINE_VISIBILITY bool valid() const {return __state_ != nullptr;} _LIBCPP_INLINE_VISIBILITY void wait() const {__state_->wait();} template _LIBCPP_INLINE_VISIBILITY future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {return __state_->wait_for(__rel_time);} template _LIBCPP_INLINE_VISIBILITY future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {return __state_->wait_until(__abs_time);} }; template inline _LIBCPP_INLINE_VISIBILITY void swap(shared_future<_R>& __x, shared_future<_R>& __y) { __x.swap(__y); } template inline _LIBCPP_INLINE_VISIBILITY shared_future<_R> future<_R>::share() { return shared_future<_R>(_VSTD::move(*this)); } template inline _LIBCPP_INLINE_VISIBILITY shared_future<_R&> future<_R&>::share() { return shared_future<_R&>(_VSTD::move(*this)); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES inline _LIBCPP_INLINE_VISIBILITY shared_future future::share() { return shared_future(_VSTD::move(*this)); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_FUTURE