// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef _LIBCPP_FUTURE #define _LIBCPP_FUTURE /* future synopsis namespace std { enum class future_errc { future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise }; 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) noexcept; error_condition make_error_condition(future_errc e) noexcept; const error_category& future_category() noexcept; class future_error : public logic_error { public: explicit future_error(future_errc e); // since C++17 const error_code& code() const noexcept; const char* what() const noexcept; private: error_code ec_; // exposition only }; template class promise { public: promise(); template promise(allocator_arg_t, const Allocator& a); promise(promise&& rhs) noexcept; promise(const promise& rhs) = delete; ~promise(); // assignment promise& operator=(promise&& rhs) noexcept; promise& operator=(const promise& rhs) = delete; void swap(promise& other) noexcept; // 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) noexcept; promise(const promise& rhs) = delete; ~promise(); // assignment promise& operator=(promise&& rhs) noexcept; promise& operator=(const promise& rhs) = delete; void swap(promise& other) noexcept; // 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) noexcept; promise(const promise& rhs) = delete; ~promise(); // assignment promise& operator=(promise&& rhs) noexcept; promise& operator=(const promise& rhs) = delete; void swap(promise& other) noexcept; // 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) noexcept; template struct uses_allocator, Alloc> : public true_type {}; template class future { public: future() noexcept; future(future&&) noexcept; future(const future& rhs) = delete; ~future(); future& operator=(const future& rhs) = delete; future& operator=(future&&) noexcept; shared_future share() noexcept; // retrieving the value R get(); // functions to check state bool valid() const noexcept; 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() noexcept; future(future&&) noexcept; future(const future& rhs) = delete; ~future(); future& operator=(const future& rhs) = delete; future& operator=(future&&) noexcept; shared_future share() noexcept; // retrieving the value R& get(); // functions to check state bool valid() const noexcept; 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() noexcept; future(future&&) noexcept; future(const future& rhs) = delete; ~future(); future& operator=(const future& rhs) = delete; future& operator=(future&&) noexcept; shared_future share() noexcept; // retrieving the value void get(); // functions to check state bool valid() const noexcept; 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() noexcept; shared_future(const shared_future& rhs); shared_future(future&&) noexcept; shared_future(shared_future&& rhs) noexcept; ~shared_future(); shared_future& operator=(const shared_future& rhs); shared_future& operator=(shared_future&& rhs) noexcept; // retrieving the value const R& get() const; // functions to check state bool valid() const noexcept; 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() noexcept; shared_future(const shared_future& rhs); shared_future(future&&) noexcept; shared_future(shared_future&& rhs) noexcept; ~shared_future(); shared_future& operator=(const shared_future& rhs); shared_future& operator=(shared_future&& rhs) noexcept; // retrieving the value R& get() const; // functions to check state bool valid() const noexcept; 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() noexcept; shared_future(const shared_future& rhs); shared_future(future&&) noexcept; shared_future(shared_future&& rhs) noexcept; ~shared_future(); shared_future& operator=(const shared_future& rhs); shared_future& operator=(shared_future&& rhs) noexcept; // retrieving the value void get() const; // functions to check state bool valid() const noexcept; 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(typename decay::type...)>::type> async(F&& f, Args&&... args); template future::type(typename decay::type...)>::type> async(launch policy, F&& f, Args&&... args); template class packaged_task; // undefined template class packaged_task { public: typedef R result_type; // extension // construction and destruction packaged_task() noexcept; template explicit packaged_task(F&& f); template packaged_task(allocator_arg_t, const Allocator& a, F&& f); ~packaged_task(); // no copy packaged_task(const packaged_task&) = delete; packaged_task& operator=(const packaged_task&) = delete; // move support packaged_task(packaged_task&& other) noexcept; packaged_task& operator=(packaged_task&& other) noexcept; void swap(packaged_task& other) noexcept; bool valid() const noexcept; // result retrieval future get_future(); // execution void operator()(ArgTypes... ); void make_ready_at_thread_exit(ArgTypes...); void reset(); }; template void swap(packaged_task&) noexcept; template struct uses_allocator, Alloc>; } // std */ #include <__config> #if !defined(_LIBCPP_HAS_NO_THREADS) # include <__assert> # include <__chrono/duration.h> # include <__chrono/time_point.h> # include <__exception/exception_ptr.h> # include <__memory/addressof.h> # include <__memory/allocator.h> # include <__memory/allocator_arg_t.h> # include <__memory/allocator_destructor.h> # include <__memory/allocator_traits.h> # include <__memory/compressed_pair.h> # include <__memory/pointer_traits.h> # include <__memory/shared_ptr.h> # include <__memory/unique_ptr.h> # include <__memory/uses_allocator.h> # include <__system_error/error_category.h> # include <__system_error/error_code.h> # include <__system_error/error_condition.h> # include <__type_traits/aligned_storage.h> # include <__type_traits/strip_signature.h> # include <__utility/auto_cast.h> # include <__utility/forward.h> # include <__utility/move.h> # include # include # include # include # include # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header # endif _LIBCPP_PUSH_MACROS # include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD // enum class future_errc _LIBCPP_DECLARE_STRONG_ENUM(future_errc){ future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise}; _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc) template <> struct _LIBCPP_TEMPLATE_VIS is_error_code_enum : public true_type {}; # ifdef _LIBCPP_CXX03_LANG template <> struct _LIBCPP_TEMPLATE_VIS is_error_code_enum : public true_type {}; # endif // enum class launch _LIBCPP_DECLARE_STRONG_ENUM(launch){async = 1, deferred = 2, any = async | deferred}; _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch) # ifndef _LIBCPP_CXX03_LANG typedef underlying_type::type __launch_underlying_type; inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator&(launch __x, launch __y) { return static_cast(static_cast<__launch_underlying_type>(__x) & static_cast<__launch_underlying_type>(__y)); } inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator|(launch __x, launch __y) { return static_cast(static_cast<__launch_underlying_type>(__x) | static_cast<__launch_underlying_type>(__y)); } inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator^(launch __x, launch __y) { return static_cast(static_cast<__launch_underlying_type>(__x) ^ static_cast<__launch_underlying_type>(__y)); } inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator~(launch __x) { return static_cast(~static_cast<__launch_underlying_type>(__x) & 3); } inline _LIBCPP_HIDE_FROM_ABI launch& operator&=(launch& __x, launch __y) { __x = __x & __y; return __x; } inline _LIBCPP_HIDE_FROM_ABI launch& operator|=(launch& __x, launch __y) { __x = __x | __y; return __x; } inline _LIBCPP_HIDE_FROM_ABI launch& operator^=(launch& __x, launch __y) { __x = __x ^ __y; return __x; } # endif // !_LIBCPP_CXX03_LANG // enum class future_status _LIBCPP_DECLARE_STRONG_ENUM(future_status){ready, timeout, deferred}; _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) _LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT; inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT { return error_code(static_cast(__e), future_category()); } inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT { return error_condition(static_cast(__e), future_category()); } _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev); class _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error { error_code __ec_; future_error(error_code); friend void __throw_future_error(future_errc); template friend class promise; public: # if _LIBCPP_STD_VER >= 17 _LIBCPP_HIDE_FROM_ABI explicit future_error(future_errc __ec) : future_error(std::make_error_code(__ec)) {} # endif _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; } _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default; ~future_error() _NOEXCEPT override; }; // Declared above std::future_error void __throw_future_error(future_errc __ev) { # ifndef _LIBCPP_HAS_NO_EXCEPTIONS throw future_error(make_error_code(__ev)); # else (void)__ev; _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode"); # endif } class _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count { protected: exception_ptr __exception_; mutable mutex __mut_; mutable condition_variable __cv_; unsigned __state_; void __on_zero_shared() _NOEXCEPT override; void __sub_wait(unique_lock& __lk); public: enum { __constructed = 1, __future_attached = 2, ready = 4, deferred = 8 }; _LIBCPP_HIDE_FROM_ABI __assoc_sub_state() : __state_(0) {} _LIBCPP_HIDE_FROM_ABI bool __has_value() const { return (__state_ & __constructed) || (__exception_ != nullptr); } _LIBCPP_HIDE_FROM_ABI void __attach_future() { lock_guard __lk(__mut_); bool __has_future_attached = (__state_ & __future_attached) != 0; if (__has_future_attached) __throw_future_error(future_errc::future_already_retrieved); this->__add_shared(); __state_ |= __future_attached; } _LIBCPP_HIDE_FROM_ABI void __set_deferred() { __state_ |= deferred; } void __make_ready(); _LIBCPP_HIDE_FROM_ABI bool __is_ready() const { return (__state_ & ready) != 0; } 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 _LIBCPP_HIDE_FROM_ABI wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; template _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 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 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 _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state { typedef __assoc_sub_state base; _LIBCPP_SUPPRESS_DEPRECATED_PUSH typedef typename aligned_storage::type _Up; _LIBCPP_SUPPRESS_DEPRECATED_POP protected: _Up __value_; _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; public: template _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg); template _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg); _LIBCPP_HIDE_FROM_ABI _Rp move(); _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy(); }; template void __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT { if (this->__state_ & base::__constructed) reinterpret_cast<_Rp*>(&__value_)->~_Rp(); delete this; } template template void __assoc_state<_Rp>::set_value(_Arg&& __arg) { unique_lock __lk(this->__mut_); if (this->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg)); this->__state_ |= base::__constructed | base::ready; __cv_.notify_all(); } template template void __assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) { unique_lock __lk(this->__mut_); if (this->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg)); this->__state_ |= base::__constructed; __thread_local_data()->__make_ready_at_thread_exit(this); } template _Rp __assoc_state<_Rp>::move() { unique_lock __lk(this->__mut_); this->__sub_wait(__lk); if (this->__exception_ != nullptr) std::rethrow_exception(this->__exception_); return std::move(*reinterpret_cast<_Rp*>(&__value_)); } template __add_lvalue_reference_t<_Rp> __assoc_state<_Rp>::copy() { unique_lock __lk(this->__mut_); this->__sub_wait(__lk); if (this->__exception_ != nullptr) std::rethrow_exception(this->__exception_); return *reinterpret_cast<_Rp*>(&__value_); } template class __assoc_state<_Rp&> : public __assoc_sub_state { typedef __assoc_sub_state base; typedef _Rp* _Up; protected: _Up __value_; _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; public: _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg); _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg); _LIBCPP_HIDE_FROM_ABI _Rp& copy(); }; template void __assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT { delete this; } template void __assoc_state<_Rp&>::set_value(_Rp& __arg) { unique_lock __lk(this->__mut_); if (this->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); __value_ = std::addressof(__arg); this->__state_ |= base::__constructed | base::ready; __cv_.notify_all(); } template void __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) { unique_lock __lk(this->__mut_); if (this->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); __value_ = std::addressof(__arg); this->__state_ |= base::__constructed; __thread_local_data()->__make_ready_at_thread_exit(this); } template _Rp& __assoc_state<_Rp&>::copy() { unique_lock __lk(this->__mut_); this->__sub_wait(__lk); if (this->__exception_ != nullptr) std::rethrow_exception(this->__exception_); return *__value_; } template class __assoc_state_alloc : public __assoc_state<_Rp> { typedef __assoc_state<_Rp> base; _Alloc __alloc_; _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; public: _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {} }; template void __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT { if (this->__state_ & base::__constructed) reinterpret_cast<_Rp*>(std::addressof(this->__value_))->~_Rp(); typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; typedef allocator_traits<_Al> _ATraits; typedef pointer_traits _PTraits; _Al __a(__alloc_); this->~__assoc_state_alloc(); __a.deallocate(_PTraits::pointer_to(*this), 1); } template class __assoc_state_alloc<_Rp&, _Alloc> : public __assoc_state<_Rp&> { typedef __assoc_state<_Rp&> base; _Alloc __alloc_; _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; public: _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {} }; template void __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT { typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al; typedef allocator_traits<_Al> _ATraits; typedef pointer_traits _PTraits; _Al __a(__alloc_); this->~__assoc_state_alloc(); __a.deallocate(_PTraits::pointer_to(*this), 1); } template class __assoc_sub_state_alloc : public __assoc_sub_state { typedef __assoc_sub_state base; _Alloc __alloc_; _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; public: _LIBCPP_HIDE_FROM_ABI explicit __assoc_sub_state_alloc(const _Alloc& __a) : __alloc_(__a) {} }; template void __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT { typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al; typedef allocator_traits<_Al> _ATraits; typedef pointer_traits _PTraits; _Al __a(__alloc_); this->~__assoc_sub_state_alloc(); __a.deallocate(_PTraits::pointer_to(*this), 1); } template class __deferred_assoc_state : public __assoc_state<_Rp> { typedef __assoc_state<_Rp> base; _Fp __func_; public: _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f); _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute(); }; template inline __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) { this->__set_deferred(); } template void __deferred_assoc_state<_Rp, _Fp>::__execute() { # ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { # endif // _LIBCPP_HAS_NO_EXCEPTIONS this->set_value(__func_()); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS } catch (...) { this->set_exception(current_exception()); } # endif // _LIBCPP_HAS_NO_EXCEPTIONS } template class __deferred_assoc_state : public __assoc_sub_state { typedef __assoc_sub_state base; _Fp __func_; public: _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f); _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override; }; template inline __deferred_assoc_state::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) { this->__set_deferred(); } template void __deferred_assoc_state::__execute() { # ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { # endif // _LIBCPP_HAS_NO_EXCEPTIONS __func_(); this->set_value(); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS } catch (...) { this->set_exception(current_exception()); } # endif // _LIBCPP_HAS_NO_EXCEPTIONS } template class __async_assoc_state : public __assoc_state<_Rp> { typedef __assoc_state<_Rp> base; _Fp __func_; _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; public: _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f); _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute(); }; template inline __async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {} template void __async_assoc_state<_Rp, _Fp>::__execute() { # ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { # endif // _LIBCPP_HAS_NO_EXCEPTIONS this->set_value(__func_()); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS } catch (...) { this->set_exception(current_exception()); } # endif // _LIBCPP_HAS_NO_EXCEPTIONS } template void __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT { this->wait(); base::__on_zero_shared(); } template class __async_assoc_state : public __assoc_sub_state { typedef __assoc_sub_state base; _Fp __func_; _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; public: _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f); _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override; }; template inline __async_assoc_state::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {} template void __async_assoc_state::__execute() { # ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { # endif // _LIBCPP_HAS_NO_EXCEPTIONS __func_(); this->set_value(); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS } catch (...) { this->set_exception(current_exception()); } # endif // _LIBCPP_HAS_NO_EXCEPTIONS } template void __async_assoc_state::__on_zero_shared() _NOEXCEPT { this->wait(); base::__on_zero_shared(); } template class _LIBCPP_TEMPLATE_VIS promise; template class _LIBCPP_TEMPLATE_VIS shared_future; // future template class _LIBCPP_TEMPLATE_VIS future; template _LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f); template _LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f); template class _LIBCPP_TEMPLATE_VIS future { __assoc_state<_Rp>* __state_; explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state); template friend class promise; template friend class shared_future; template friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); template friend future<_R1> __make_async_assoc_state(_Fp&& __f); public: _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {} _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } future(const future&) = delete; future& operator=(const future&) = delete; _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT { future(std::move(__rhs)).swap(*this); return *this; } _LIBCPP_HIDE_FROM_ABI ~future(); _LIBCPP_HIDE_FROM_ABI shared_future<_Rp> share() _NOEXCEPT; // retrieving the value _LIBCPP_HIDE_FROM_ABI _Rp get(); _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } // functions to check state _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } template _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { return __state_->wait_for(__rel_time); } template _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { return __state_->wait_until(__abs_time); } }; template future<_Rp>::future(__assoc_state<_Rp>* __state) : __state_(__state) { __state_->__attach_future(); } struct __release_shared_count { _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) { __p->__release_shared(); } }; template future<_Rp>::~future() { if (__state_) __state_->__release_shared(); } template _Rp future<_Rp>::get() { unique_ptr<__shared_count, __release_shared_count> __guard(__state_); __assoc_state<_Rp>* __s = __state_; __state_ = nullptr; return __s->move(); } template class _LIBCPP_TEMPLATE_VIS future<_Rp&> { __assoc_state<_Rp&>* __state_; explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state); template friend class promise; template friend class shared_future; template friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); template friend future<_R1> __make_async_assoc_state(_Fp&& __f); public: _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {} _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } future(const future&) = delete; future& operator=(const future&) = delete; _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT { future(std::move(__rhs)).swap(*this); return *this; } _LIBCPP_HIDE_FROM_ABI ~future(); _LIBCPP_HIDE_FROM_ABI shared_future<_Rp&> share() _NOEXCEPT; // retrieving the value _LIBCPP_HIDE_FROM_ABI _Rp& get(); _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } // functions to check state _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } template _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { return __state_->wait_for(__rel_time); } template _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { return __state_->wait_until(__abs_time); } }; template future<_Rp&>::future(__assoc_state<_Rp&>* __state) : __state_(__state) { __state_->__attach_future(); } template future<_Rp&>::~future() { if (__state_) __state_->__release_shared(); } template _Rp& future<_Rp&>::get() { unique_ptr<__shared_count, __release_shared_count> __guard(__state_); __assoc_state<_Rp&>* __s = __state_; __state_ = nullptr; return __s->copy(); } template <> class _LIBCPP_EXPORTED_FROM_ABI future { __assoc_sub_state* __state_; explicit future(__assoc_sub_state* __state); template friend class promise; template friend class shared_future; template friend future<_R1> __make_deferred_assoc_state(_Fp&& __f); template friend future<_R1> __make_async_assoc_state(_Fp&& __f); public: _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {} _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } future(const future&) = delete; future& operator=(const future&) = delete; _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT { future(std::move(__rhs)).swap(*this); return *this; } ~future(); _LIBCPP_HIDE_FROM_ABI shared_future share() _NOEXCEPT; // retrieving the value void get(); _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } // functions to check state _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } template _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { return __state_->wait_for(__rel_time); } template _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { return __state_->wait_until(__abs_time); } }; template inline _LIBCPP_HIDE_FROM_ABI void swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT { __x.swap(__y); } // promise template class packaged_task; template class _LIBCPP_TEMPLATE_VIS promise { __assoc_state<_Rp>* __state_; _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} template friend class packaged_task; public: _LIBCPP_HIDE_FROM_ABI promise(); template _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a); _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } promise(const promise& __rhs) = delete; _LIBCPP_HIDE_FROM_ABI ~promise(); // assignment _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise& __rhs) = delete; _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } // retrieving the result _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future(); // setting the result _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r); _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r); _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p); // setting the result with deferred notification _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r); _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r); _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p); }; template promise<_Rp>::promise() : __state_(new __assoc_state<_Rp>) {} template template promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) { typedef __assoc_state_alloc<_Rp, _Alloc> _State; typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; typedef __allocator_destructor<_A2> _D2; _A2 __a(__a0); unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); ::new ((void*)std::addressof(*__hold.get())) _State(__a0); __state_ = std::addressof(*__hold.release()); } template promise<_Rp>::~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<_Rp> promise<_Rp>::get_future() { if (__state_ == nullptr) __throw_future_error(future_errc::no_state); return future<_Rp>(__state_); } template void promise<_Rp>::set_value(const _Rp& __r) { if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_value(__r); } template void promise<_Rp>::set_value(_Rp&& __r) { if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_value(std::move(__r)); } template void promise<_Rp>::set_exception(exception_ptr __p) { _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr"); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception(__p); } template void promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) { if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_value_at_thread_exit(__r); } template void promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) { if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_value_at_thread_exit(std::move(__r)); } template void promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) { _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr"); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception_at_thread_exit(__p); } // promise template class _LIBCPP_TEMPLATE_VIS promise<_Rp&> { __assoc_state<_Rp&>* __state_; _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} template friend class packaged_task; public: _LIBCPP_HIDE_FROM_ABI promise(); template _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a); _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } promise(const promise& __rhs) = delete; _LIBCPP_HIDE_FROM_ABI ~promise(); // assignment _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise& __rhs) = delete; _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } // retrieving the result _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future(); // setting the result _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r); _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p); // setting the result with deferred notification _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&); _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p); }; template promise<_Rp&>::promise() : __state_(new __assoc_state<_Rp&>) {} template template promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) { typedef __assoc_state_alloc<_Rp&, _Alloc> _State; typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; typedef __allocator_destructor<_A2> _D2; _A2 __a(__a0); unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); ::new ((void*)std::addressof(*__hold.get())) _State(__a0); __state_ = std::addressof(*__hold.release()); } template promise<_Rp&>::~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<_Rp&> promise<_Rp&>::get_future() { if (__state_ == nullptr) __throw_future_error(future_errc::no_state); return future<_Rp&>(__state_); } template void promise<_Rp&>::set_value(_Rp& __r) { if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_value(__r); } template void promise<_Rp&>::set_exception(exception_ptr __p) { _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr"); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception(__p); } template void promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) { if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_value_at_thread_exit(__r); } template void promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) { _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr"); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception_at_thread_exit(__p); } // promise template <> class _LIBCPP_EXPORTED_FROM_ABI promise { __assoc_sub_state* __state_; _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {} template friend class packaged_task; public: promise(); template _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS promise(allocator_arg_t, const _Allocator& __a); _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } promise(const promise& __rhs) = delete; ~promise(); // assignment _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise& __rhs) = delete; _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::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 __assoc_sub_state_alloc<_Alloc> _State; typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2; typedef __allocator_destructor<_A2> _D2; _A2 __a(__a0); unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1)); ::new ((void*)std::addressof(*__hold.get())) _State(__a0); __state_ = std::addressof(*__hold.release()); } template inline _LIBCPP_HIDE_FROM_ABI void swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT { __x.swap(__y); } template struct _LIBCPP_TEMPLATE_VIS uses_allocator, _Alloc> : public true_type {}; // packaged_task template class __packaged_task_base; template class __packaged_task_base<_Rp(_ArgTypes...)> { public: _LIBCPP_HIDE_FROM_ABI __packaged_task_base() {} __packaged_task_base(const __packaged_task_base&) = delete; __packaged_task_base& operator=(const __packaged_task_base&) = delete; _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__packaged_task_base() {} virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0; virtual void destroy() = 0; virtual void destroy_deallocate() = 0; virtual _Rp operator()(_ArgTypes&&...) = 0; }; template class __packaged_task_func; template class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __packaged_task_base<_Rp(_ArgTypes...)> { __compressed_pair<_Fp, _Alloc> __f_; public: _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {} _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(_Fp&& __f) : __f_(std::move(__f), __default_init_tag()) {} _LIBCPP_HIDE_FROM_ABI __packaged_task_func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} _LIBCPP_HIDE_FROM_ABI __packaged_task_func(_Fp&& __f, const _Alloc& __a) : __f_(std::move(__f), __a) {} _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy(); _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate(); _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __args); }; template void __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to( __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT { ::new ((void*)__p) __packaged_task_func(std::move(__f_.first()), std::move(__f_.second())); } template void __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() { __f_.~__compressed_pair<_Fp, _Alloc>(); } template void __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() { typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap; typedef allocator_traits<_Ap> _ATraits; typedef pointer_traits _PTraits; _Ap __a(__f_.second()); __f_.~__compressed_pair<_Fp, _Alloc>(); __a.deallocate(_PTraits::pointer_to(*this), 1); } template _Rp __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) { return std::__invoke(__f_.first(), std::forward<_ArgTypes>(__arg)...); } template class __packaged_task_function; template class __packaged_task_function<_Rp(_ArgTypes...)> { typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __base* __get_buf() { return (__base*)&__buf_; } _LIBCPP_SUPPRESS_DEPRECATED_PUSH typename aligned_storage<3 * sizeof(void*)>::type __buf_; _LIBCPP_SUPPRESS_DEPRECATED_POP __base* __f_; public: typedef _Rp result_type; // construct/copy/destroy: _LIBCPP_HIDE_FROM_ABI __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} template _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f); template _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; __packaged_task_function(const __packaged_task_function&) = delete; __packaged_task_function& operator=(const __packaged_task_function&) = delete; _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function(); _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; }; template __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT { if (__f.__f_ == nullptr) __f_ = nullptr; else if (__f.__f_ == __f.__get_buf()) { __f.__f_->__move_to(__get_buf()); __f_ = (__base*)&__buf_; } else { __f_ = __f.__f_; __f.__f_ = nullptr; } } template template __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) : __f_(nullptr) { typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR; typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { ::new ((void*)&__buf_) _FF(std::forward<_Fp>(__f)); __f_ = (__base*)&__buf_; } else { typedef allocator<_FF> _Ap; _Ap __a; typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)__hold.get()) _FF(std::forward<_Fp>(__f), allocator<_FR>(__a)); __f_ = __hold.release(); } } template template __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_arg_t, const _Alloc& __a0, _Fp&& __f) : __f_(nullptr) { typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR; typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; if (sizeof(_FF) <= sizeof(__buf_)) { __f_ = (__base*)&__buf_; ::new ((void*)__f_) _FF(std::forward<_Fp>(__f)); } else { typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap; _Ap __a(__a0); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); ::new ((void*)std::addressof(*__hold.get())) _FF(std::forward<_Fp>(__f), _Alloc(__a)); __f_ = std::addressof(*__hold.release()); } } template __packaged_task_function<_Rp(_ArgTypes...)>& __packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT { if (__f_ == __get_buf()) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); __f_ = nullptr; if (__f.__f_ == nullptr) __f_ = nullptr; else if (__f.__f_ == __f.__get_buf()) { __f.__f_->__move_to(__get_buf()); __f_ = __get_buf(); } else { __f_ = __f.__f_; __f.__f_ = nullptr; } return *this; } template __packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() { if (__f_ == __get_buf()) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); } template _LIBCPP_NO_CFI void __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT { if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { _LIBCPP_SUPPRESS_DEPRECATED_PUSH typename aligned_storage::type __tempbuf; _LIBCPP_SUPPRESS_DEPRECATED_POP __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 std::swap(__f_, __f.__f_); } template inline _Rp __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { return (*__f_)(std::forward<_ArgTypes>(__arg)...); } template class _LIBCPP_TEMPLATE_VIS packaged_task<_Rp(_ArgTypes...)> { public: typedef _Rp result_type; // extension private: __packaged_task_function __f_; promise __p_; public: // construction and destruction _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {} template , packaged_task>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {} template , packaged_task>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {} // ~packaged_task() = default; // no copy packaged_task(const packaged_task&) = delete; packaged_task& operator=(const packaged_task&) = delete; // move support _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT : __f_(std::move(__other.__f_)), __p_(std::move(__other.__p_)) {} _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT { __f_ = std::move(__other.__f_); __p_ = std::move(__other.__p_); return *this; } _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT { __f_.swap(__other.__f_); __p_.swap(__other.__p_); } _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; } // result retrieval _LIBCPP_HIDE_FROM_ABI future get_future() { return __p_.get_future(); } // execution _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args); _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args); _LIBCPP_HIDE_FROM_ABI void reset(); }; template void packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) { if (__p_.__state_ == nullptr) __throw_future_error(future_errc::no_state); if (__p_.__state_->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { # endif // _LIBCPP_HAS_NO_EXCEPTIONS __p_.set_value(__f_(std::forward<_ArgTypes>(__args)...)); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS } catch (...) { __p_.set_exception(current_exception()); } # endif // _LIBCPP_HAS_NO_EXCEPTIONS } template void packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) { if (__p_.__state_ == nullptr) __throw_future_error(future_errc::no_state); if (__p_.__state_->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { # endif // _LIBCPP_HAS_NO_EXCEPTIONS __p_.set_value_at_thread_exit(__f_(std::forward<_ArgTypes>(__args)...)); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS } catch (...) { __p_.set_exception_at_thread_exit(current_exception()); } # endif // _LIBCPP_HAS_NO_EXCEPTIONS } template void packaged_task<_Rp(_ArgTypes...)>::reset() { if (!valid()) __throw_future_error(future_errc::no_state); __p_ = promise(); } template class _LIBCPP_TEMPLATE_VIS packaged_task { public: typedef void result_type; // extension private: __packaged_task_function __f_; promise __p_; public: // construction and destruction _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {} template , packaged_task>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {} template , packaged_task>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {} // ~packaged_task() = default; // no copy packaged_task(const packaged_task&) = delete; packaged_task& operator=(const packaged_task&) = delete; // move support _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT : __f_(std::move(__other.__f_)), __p_(std::move(__other.__p_)) {} _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT { __f_ = std::move(__other.__f_); __p_ = std::move(__other.__p_); return *this; } _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT { __f_.swap(__other.__f_); __p_.swap(__other.__p_); } _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; } // result retrieval _LIBCPP_HIDE_FROM_ABI future get_future() { return __p_.get_future(); } // execution _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args); _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args); _LIBCPP_HIDE_FROM_ABI void reset(); }; # if _LIBCPP_STD_VER >= 17 template packaged_task(_Rp (*)(_Args...)) -> packaged_task<_Rp(_Args...)>; template ::type> packaged_task(_Fp) -> packaged_task<_Stripped>; # endif template void packaged_task::operator()(_ArgTypes... __args) { if (__p_.__state_ == nullptr) __throw_future_error(future_errc::no_state); if (__p_.__state_->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { # endif // _LIBCPP_HAS_NO_EXCEPTIONS __f_(std::forward<_ArgTypes>(__args)...); __p_.set_value(); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS } catch (...) { __p_.set_exception(current_exception()); } # endif // _LIBCPP_HAS_NO_EXCEPTIONS } template void packaged_task::make_ready_at_thread_exit(_ArgTypes... __args) { if (__p_.__state_ == nullptr) __throw_future_error(future_errc::no_state); if (__p_.__state_->__has_value()) __throw_future_error(future_errc::promise_already_satisfied); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { # endif // _LIBCPP_HAS_NO_EXCEPTIONS __f_(std::forward<_ArgTypes>(__args)...); __p_.set_value_at_thread_exit(); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS } catch (...) { __p_.set_exception_at_thread_exit(current_exception()); } # endif // _LIBCPP_HAS_NO_EXCEPTIONS } template void packaged_task::reset() { if (!valid()) __throw_future_error(future_errc::no_state); __p_ = promise(); } template inline _LIBCPP_HIDE_FROM_ABI void swap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT { __x.swap(__y); } template struct _LIBCPP_TEMPLATE_VIS uses_allocator, _Alloc> : public true_type {}; template _LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f) { unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> __h( new __deferred_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f))); return future<_Rp>(__h.get()); } template _LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f) { unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h( new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f))); std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach(); return future<_Rp>(__h.get()); } # ifndef _LIBCPP_CXX03_LANG template class _LIBCPP_HIDDEN __async_func { tuple<_Fp, _Args...> __f_; public: typedef typename __invoke_of<_Fp, _Args...>::type _Rp; _LIBCPP_HIDE_FROM_ABI explicit __async_func(_Fp&& __f, _Args&&... __args) : __f_(std::move(__f), std::move(__args)...) {} _LIBCPP_HIDE_FROM_ABI __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {} _LIBCPP_HIDE_FROM_ABI _Rp operator()() { typedef typename __make_tuple_indices<1 + sizeof...(_Args), 1>::type _Index; return __execute(_Index()); } private: template _LIBCPP_HIDE_FROM_ABI _Rp __execute(__tuple_indices<_Indices...>) { return std::__invoke(std::move(std::get<0>(__f_)), std::move(std::get<_Indices>(__f_))...); } }; inline _LIBCPP_HIDE_FROM_ABI bool __does_policy_contain(launch __policy, launch __value) { return (int(__policy) & int(__value)) != 0; } template _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI future, __decay_t<_Args>...>::type> async(launch __policy, _Fp&& __f, _Args&&... __args) { typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF; typedef typename _BF::_Rp _Rp; # ifndef _LIBCPP_HAS_NO_EXCEPTIONS try { # endif if (__does_policy_contain(__policy, launch::async)) return std::__make_async_assoc_state<_Rp>( _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...)); # ifndef _LIBCPP_HAS_NO_EXCEPTIONS } catch (...) { if (__policy == launch::async) throw; } # endif if (__does_policy_contain(__policy, launch::deferred)) return std::__make_deferred_assoc_state<_Rp>( _BF(_LIBCPP_AUTO_CAST(std::forward<_Fp>(__f)), _LIBCPP_AUTO_CAST(std::forward<_Args>(__args))...)); return future<_Rp>{}; } template _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI future, __decay_t<_Args>...>::type> async(_Fp&& __f, _Args&&... __args) { return std::async(launch::any, std::forward<_Fp>(__f), std::forward<_Args>(__args)...); } # endif // C++03 // shared_future template class _LIBCPP_TEMPLATE_VIS shared_future { __assoc_state<_Rp>* __state_; public: _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {} _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { if (__state_) __state_->__add_shared(); } _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; } _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } _LIBCPP_HIDE_FROM_ABI ~shared_future(); _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT { shared_future(std::move(__rhs)).swap(*this); return *this; } // retrieving the value _LIBCPP_HIDE_FROM_ABI const _Rp& get() const { return __state_->copy(); } _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } // functions to check state _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } template _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { return __state_->wait_for(__rel_time); } template _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { return __state_->wait_until(__abs_time); } }; template shared_future<_Rp>::~shared_future() { if (__state_) __state_->__release_shared(); } template shared_future<_Rp>& shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT { if (__rhs.__state_) __rhs.__state_->__add_shared(); if (__state_) __state_->__release_shared(); __state_ = __rhs.__state_; return *this; } template class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> { __assoc_state<_Rp&>* __state_; public: _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {} _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) { if (__state_) __state_->__add_shared(); } _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; } _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } _LIBCPP_HIDE_FROM_ABI ~shared_future(); _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs); _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT { shared_future(std::move(__rhs)).swap(*this); return *this; } // retrieving the value _LIBCPP_HIDE_FROM_ABI _Rp& get() const { return __state_->copy(); } _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } // functions to check state _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } template _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { return __state_->wait_for(__rel_time); } template _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { return __state_->wait_until(__abs_time); } }; template shared_future<_Rp&>::~shared_future() { if (__state_) __state_->__release_shared(); } template shared_future<_Rp&>& shared_future<_Rp&>::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_EXPORTED_FROM_ABI shared_future { __assoc_sub_state* __state_; public: _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {} _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) { if (__state_) __state_->__add_shared(); } _LIBCPP_HIDE_FROM_ABI shared_future(future&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; } _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; } ~shared_future(); shared_future& operator=(const shared_future& __rhs); _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT { shared_future(std::move(__rhs)).swap(*this); return *this; } // retrieving the value _LIBCPP_HIDE_FROM_ABI void get() const { __state_->copy(); } _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); } // functions to check state _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; } _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); } template _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const { return __state_->wait_for(__rel_time); } template _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const { return __state_->wait_until(__abs_time); } }; template inline _LIBCPP_HIDE_FROM_ABI void swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT { __x.swap(__y); } template inline shared_future<_Rp> future<_Rp>::share() _NOEXCEPT { return shared_future<_Rp>(std::move(*this)); } template inline shared_future<_Rp&> future<_Rp&>::share() _NOEXCEPT { return shared_future<_Rp&>(std::move(*this)); } inline shared_future future::share() _NOEXCEPT { return shared_future(std::move(*this)); } _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS #endif // !defined(_LIBCPP_HAS_NO_THREADS) #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17 # include #endif #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 # include # include # include # include # include #endif #endif // _LIBCPP_FUTURE