diff options
Diffstat (limited to 'include/future')
-rw-r--r-- | include/future | 2517 |
1 files changed, 2517 insertions, 0 deletions
diff --git a/include/future b/include/future new file mode 100644 index 0000000..f6896a3 --- /dev/null +++ b/include/future @@ -0,0 +1,2517 @@ +// -*- 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<future_errc> : 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 R> +class promise +{ +public: + promise(); + template <class Allocator> + 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<R> 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 R> +class promise<R&> +{ +public: + promise(); + template <class Allocator> + 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<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 <> +class promise<void> +{ +public: + promise(); + template <class Allocator> + 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<void> 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 <class R> void swap(promise<R>& x, promise<R>& y); + +template <class R, class Alloc> + struct uses_allocator<promise<R>, Alloc> : public true_type {}; + +template <class R> +class future +{ +public: + future(); + future(future&&); + future(const future& rhs) = delete; + ~future(); + future& operator=(const future& rhs) = delete; + future& operator=(future&&); + shared_future<R> share() &&; + + // retrieving the value + R get(); + + // functions to check state + bool valid() const; + + void wait() const; + template <class Rep, class Period> + future_status + wait_for(const chrono::duration<Rep, Period>& rel_time) const; + template <class Clock, class Duration> + future_status + wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; +}; + +template <class R> +class future<R&> +{ +public: + future(); + future(future&&); + future(const future& rhs) = delete; + ~future(); + future& operator=(const future& rhs) = delete; + future& operator=(future&&); + shared_future<R&> share() &&; + + // retrieving the value + R& get(); + + // functions to check state + bool valid() const; + + void wait() const; + template <class Rep, class Period> + future_status + wait_for(const chrono::duration<Rep, Period>& rel_time) const; + template <class Clock, class Duration> + future_status + wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; +}; + +template <> +class future<void> +{ +public: + future(); + future(future&&); + future(const future& rhs) = delete; + ~future(); + future& operator=(const future& rhs) = delete; + future& operator=(future&&); + shared_future<void> share() &&; + + // retrieving the value + void get(); + + // functions to check state + bool valid() const; + + void wait() const; + template <class Rep, class Period> + future_status + wait_for(const chrono::duration<Rep, Period>& rel_time) const; + template <class Clock, class Duration> + future_status + wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; +}; + +template <class R> +class shared_future +{ +public: + shared_future(); + shared_future(const shared_future& rhs); + shared_future(future<R>&&); + 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 <class Rep, class Period> + future_status + wait_for(const chrono::duration<Rep, Period>& rel_time) const; + template <class Clock, class Duration> + future_status + wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; +}; + +template <class R> +class shared_future<R&> +{ +public: + shared_future(); + shared_future(const shared_future& rhs); + shared_future(future<R&>&&); + 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 <class Rep, class Period> + future_status + wait_for(const chrono::duration<Rep, Period>& rel_time) const; + template <class Clock, class Duration> + future_status + wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; +}; + +template <> +class shared_future<void> +{ +public: + shared_future(); + shared_future(const shared_future& rhs); + shared_future(future<void>&&); + 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 <class Rep, class Period> + future_status + wait_for(const chrono::duration<Rep, Period>& rel_time) const; + template <class Clock, class Duration> + future_status + wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; +}; + +template <class F, class... Args> + future<typename result_of<F(Args...)>::type> + async(F&& f, Args&&... args); + +template <class F, class... Args> + future<typename result_of<F(Args...)>::type> + async(launch policy, F&& f, Args&&... args); + +template <class> class packaged_task; // undefined + +template <class R, class... ArgTypes> +class packaged_task<R(ArgTypes...)> +{ +public: + typedef R result_type; + + // construction and destruction + packaged_task(); + template <class F> + explicit packaged_task(F&& f); + template <class F, class Allocator> + 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<R> get_future(); + + // execution + void operator()(ArgTypes... ); + void make_ready_at_thread_exit(ArgTypes...); + + void reset(); +}; + +template <class R> + void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&); + +template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; + +} // std + +*/ + +#include <__config> +#include <system_error> +#include <memory> +#include <chrono> +#include <exception> +#include <mutex> +#include <thread> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_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<future_errc> : 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<int>(__e), future_category()); +} + +inline _LIBCPP_INLINE_VISIBILITY +error_condition +make_error_condition(future_errc __e) +{ + return error_condition(static_cast<int>(__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<mutex>& __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 <class _Rep, class _Period> + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const; + template <class _Clock, class _Duration> + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const; + + virtual void __execute(); +}; + +template <class _Clock, class _Duration> +future_status +__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const +{ + unique_lock<mutex> __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 <class _Rep, class _Period> +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 _R> +class __assoc_state + : public __assoc_sub_state +{ + typedef __assoc_sub_state base; + typedef typename aligned_storage<sizeof(_R), alignment_of<_R>::value>::type _U; +protected: + _U __value_; + + virtual void __on_zero_shared() _NOEXCEPT; +public: + + template <class _Arg> +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + void set_value(_Arg&& __arg); +#else + void set_value(_Arg& __arg); +#endif + + template <class _Arg> +#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 <class _R> +void +__assoc_state<_R>::__on_zero_shared() _NOEXCEPT +{ + if (this->__state_ & base::__constructed) + reinterpret_cast<_R*>(&__value_)->~_R(); + delete this; +} + +template <class _R> +template <class _Arg> +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<mutex> __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 <class _R> +template <class _Arg> +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<mutex> __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 <class _R> +_R +__assoc_state<_R>::move() +{ + unique_lock<mutex> __lk(this->__mut_); + this->__sub_wait(__lk); + if (this->__exception_ != nullptr) + rethrow_exception(this->__exception_); + return _VSTD::move(*reinterpret_cast<_R*>(&__value_)); +} + +template <class _R> +typename add_lvalue_reference<_R>::type +__assoc_state<_R>::copy() +{ + unique_lock<mutex> __lk(this->__mut_); + this->__sub_wait(__lk); + if (this->__exception_ != nullptr) + rethrow_exception(this->__exception_); + return *reinterpret_cast<_R*>(&__value_); +} + +template <class _R> +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 <class _R> +void +__assoc_state<_R&>::__on_zero_shared() _NOEXCEPT +{ + delete this; +} + +template <class _R> +void +__assoc_state<_R&>::set_value(_R& __arg) +{ + unique_lock<mutex> __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 <class _R> +void +__assoc_state<_R&>::set_value_at_thread_exit(_R& __arg) +{ + unique_lock<mutex> __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 <class _R> +_R& +__assoc_state<_R&>::copy() +{ + unique_lock<mutex> __lk(this->__mut_); + this->__sub_wait(__lk); + if (this->__exception_ != nullptr) + rethrow_exception(this->__exception_); + return *__value_; +} + +template <class _R, class _Alloc> +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 <class _R, class _Alloc> +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 _R, class _Alloc> +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 <class _R, class _Alloc> +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 _Alloc> +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 <class _Alloc> +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 _R, class _F> +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 <class _R, class _F> +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 <class _R, class _F> +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 _F> +class __deferred_assoc_state<void, _F> + : 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 <class _F> +inline _LIBCPP_INLINE_VISIBILITY +__deferred_assoc_state<void, _F>::__deferred_assoc_state(_F&& __f) + : __func_(_VSTD::forward<_F>(__f)) +{ + this->__set_deferred(); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template <class _F> +void +__deferred_assoc_state<void, _F>::__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 _R, class _F> +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 <class _R, class _F> +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 <class _R, class _F> +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 <class _R, class _F> +void +__async_assoc_state<_R, _F>::__on_zero_shared() _NOEXCEPT +{ + this->wait(); + base::__on_zero_shared(); +} + +template <class _F> +class __async_assoc_state<void, _F> + : 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 <class _F> +inline _LIBCPP_INLINE_VISIBILITY +__async_assoc_state<void, _F>::__async_assoc_state(_F&& __f) + : __func_(_VSTD::forward<_F>(__f)) +{ +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template <class _F> +void +__async_assoc_state<void, _F>::__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 _F> +void +__async_assoc_state<void, _F>::__on_zero_shared() _NOEXCEPT +{ + this->wait(); + base::__on_zero_shared(); +} + +template <class _R> class promise; +template <class _R> class shared_future; + +// future + +template <class _R> class future; + +template <class _R, class _F> +future<_R> +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +__make_deferred_assoc_state(_F&& __f); +#else +__make_deferred_assoc_state(_F __f); +#endif + +template <class _R, class _F> +future<_R> +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +__make_async_assoc_state(_F&& __f); +#else +__make_async_assoc_state(_F __f); +#endif + +template <class _R> +class _LIBCPP_VISIBLE future +{ + __assoc_state<_R>* __state_; + + explicit future(__assoc_state<_R>* __state); + + template <class> friend class promise; + template <class> friend class shared_future; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template <class _R1, class _F> + friend future<_R1> __make_deferred_assoc_state(_F&& __f); + template <class _R1, class _F> + friend future<_R1> __make_async_assoc_state(_F&& __f); +#else + template <class _R1, class _F> + friend future<_R1> __make_deferred_assoc_state(_F __f); + template <class _R1, class _F> + 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 <class _Rep, class _Period> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template <class _Clock, class _Duration> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template <class _R> +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 <class _R> +future<_R>::~future() +{ + if (__state_) + __state_->__release_shared(); +} + +template <class _R> +_R +future<_R>::get() +{ + unique_ptr<__shared_count, __release_shared_count> __(__state_); + __assoc_state<_R>* __s = __state_; + __state_ = nullptr; + return __s->move(); +} + +template <class _R> +class _LIBCPP_VISIBLE future<_R&> +{ + __assoc_state<_R&>* __state_; + + explicit future(__assoc_state<_R&>* __state); + + template <class> friend class promise; + template <class> friend class shared_future; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template <class _R1, class _F> + friend future<_R1> __make_deferred_assoc_state(_F&& __f); + template <class _R1, class _F> + friend future<_R1> __make_async_assoc_state(_F&& __f); +#else + template <class _R1, class _F> + friend future<_R1> __make_deferred_assoc_state(_F __f); + template <class _R1, class _F> + 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 <class _Rep, class _Period> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template <class _Clock, class _Duration> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template <class _R> +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 <class _R> +future<_R&>::~future() +{ + if (__state_) + __state_->__release_shared(); +} + +template <class _R> +_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<void> +{ + __assoc_sub_state* __state_; + + explicit future(__assoc_sub_state* __state); + + template <class> friend class promise; + template <class> friend class shared_future; + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template <class _R1, class _F> + friend future<_R1> __make_deferred_assoc_state(_F&& __f); + template <class _R1, class _F> + friend future<_R1> __make_async_assoc_state(_F&& __f); +#else + template <class _R1, class _F> + friend future<_R1> __make_deferred_assoc_state(_F __f); + template <class _R1, class _F> + 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<void> 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 <class _Rep, class _Period> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template <class _Clock, class _Duration> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template <class _R> +inline _LIBCPP_INLINE_VISIBILITY +void +swap(future<_R>& __x, future<_R>& __y) +{ + __x.swap(__y); +} + +// promise<R> + +template <class _Callable> class packaged_task; + +template <class _R> +class _LIBCPP_VISIBLE promise +{ + __assoc_state<_R>* __state_; + + _LIBCPP_INLINE_VISIBILITY + explicit promise(nullptr_t) : __state_(nullptr) {} + + template <class> friend class packaged_task; +public: + promise(); + template <class _Alloc> + 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 <class _R> +promise<_R>::promise() + : __state_(new __assoc_state<_R>) +{ +} + +template <class _R> +template <class _Alloc> +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 <class _R> +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 <class _R> +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 <class _R> +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 <class _R> +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 <class _R> +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 <class _R> +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 <class _R> +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 <class _R> +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<R&> + +template <class _R> +class _LIBCPP_VISIBLE promise<_R&> +{ + __assoc_state<_R&>* __state_; + + _LIBCPP_INLINE_VISIBILITY + explicit promise(nullptr_t) : __state_(nullptr) {} + + template <class> friend class packaged_task; + +public: + promise(); + template <class _Allocator> + 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 <class _R> +promise<_R&>::promise() + : __state_(new __assoc_state<_R&>) +{ +} + +template <class _R> +template <class _Alloc> +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 <class _R> +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 <class _R> +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 <class _R> +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 <class _R> +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 <class _R> +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 <class _R> +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<void> + +template <> +class _LIBCPP_VISIBLE promise<void> +{ + __assoc_sub_state* __state_; + + _LIBCPP_INLINE_VISIBILITY + explicit promise(nullptr_t) : __state_(nullptr) {} + + template <class> friend class packaged_task; + +public: + promise(); + template <class _Allocator> + 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<void> 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 <class _Alloc> +promise<void>::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 <class _R> +inline _LIBCPP_INLINE_VISIBILITY +void +swap(promise<_R>& __x, promise<_R>& __y) +{ + __x.swap(__y); +} + +template <class _R, class _Alloc> + struct _LIBCPP_VISIBLE uses_allocator<promise<_R>, _Alloc> + : public true_type {}; + +#ifndef _LIBCPP_HAS_NO_VARIADICS + +// packaged_task + +template<class _Fp> class __packaged_task_base; + +template<class _R, class ..._ArgTypes> +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 _FD, class _Alloc, class _FB> class __packaged_task_func; + +template<class _F, class _Alloc, class _R, class ..._ArgTypes> +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<class _F, class _Alloc, class _R, class ..._ArgTypes> +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<class _F, class _Alloc, class _R, class ..._ArgTypes> +void +__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy() +{ + __f_.~__compressed_pair<_F, _Alloc>(); +} + +template<class _F, class _Alloc, class _R, class ..._ArgTypes> +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<class _F, class _Alloc, class _R, class ..._ArgTypes> +_R +__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) +{ + return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); +} + +template <class _Callable> class __packaged_task_function; + +template<class _R, class ..._ArgTypes> +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<class _F> + __packaged_task_function(_F&& __f); + template<class _F, class _Alloc> + __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<class _R, class ..._ArgTypes> +__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<class _R, class ..._ArgTypes> +template <class _F> +__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<class _R, class ..._ArgTypes> +template <class _F, class _Alloc> +__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<class _R, class ..._ArgTypes> +__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<class _R, class ..._ArgTypes> +__packaged_task_function<_R(_ArgTypes...)>::~__packaged_task_function() +{ + if (__f_ == (__base*)&__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); +} + +template<class _R, class ..._ArgTypes> +void +__packaged_task_function<_R(_ArgTypes...)>::swap(__packaged_task_function& __f) +{ + if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + { + typename aligned_storage<sizeof(__buf_)>::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<class _R, class ..._ArgTypes> +inline _LIBCPP_INLINE_VISIBILITY +_R +__packaged_task_function<_R(_ArgTypes...)>::operator()(_ArgTypes... __arg) const +{ + return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); +} + +template<class _R, class ..._ArgTypes> +class _LIBCPP_VISIBLE packaged_task<_R(_ArgTypes...)> +{ +public: + typedef _R result_type; + +private: + __packaged_task_function<result_type(_ArgTypes...)> __f_; + promise<result_type> __p_; + +public: + // construction and destruction + _LIBCPP_INLINE_VISIBILITY + packaged_task() : __p_(nullptr) {} + template <class _F> + _LIBCPP_INLINE_VISIBILITY + explicit packaged_task(_F&& __f) : __f_(_VSTD::forward<_F>(__f)) {} + template <class _F, class _Allocator> + _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<result_type> get_future() {return __p_.get_future();} + + // execution + void operator()(_ArgTypes... __args); + void make_ready_at_thread_exit(_ArgTypes... __args); + + void reset(); +}; + +template<class _R, class ..._ArgTypes> +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<class _R, class ..._ArgTypes> +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<class _R, class ..._ArgTypes> +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<result_type>(); +} + +template<class ..._ArgTypes> +class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)> +{ +public: + typedef void result_type; + +private: + __packaged_task_function<result_type(_ArgTypes...)> __f_; + promise<result_type> __p_; + +public: + // construction and destruction + _LIBCPP_INLINE_VISIBILITY + packaged_task() : __p_(nullptr) {} + template <class _F> + _LIBCPP_INLINE_VISIBILITY + explicit packaged_task(_F&& __f) : __f_(_VSTD::forward<_F>(__f)) {} + template <class _F, class _Allocator> + _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<result_type> get_future() {return __p_.get_future();} + + // execution + void operator()(_ArgTypes... __args); + void make_ready_at_thread_exit(_ArgTypes... __args); + + void reset(); +}; + +template<class ..._ArgTypes> +void +packaged_task<void(_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 + __f_(_VSTD::forward<_ArgTypes>(__args)...); + __p_.set_value(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __p_.set_exception(current_exception()); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +template<class ..._ArgTypes> +void +packaged_task<void(_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 + __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<class ..._ArgTypes> +void +packaged_task<void(_ArgTypes...)>::reset() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (!valid()) + throw future_error(make_error_code(future_errc::no_state)); +#endif // _LIBCPP_NO_EXCEPTIONS + __p_ = promise<result_type>(); +} + +template <class _Callable> +inline _LIBCPP_INLINE_VISIBILITY +void +swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) +{ + __x.swap(__y); +} + +template <class _Callable, class _Alloc> +struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc> + : public true_type {}; + +template <class _R, class _F> +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 <class _R, class _F> +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 _F, class... _Args> +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 <size_t ..._Indices> + _R + __execute(__tuple_indices<_Indices...>) + { + return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); + } +}; + +template <class _F, class... _Args> +future<typename __invoke_of<typename decay<_F>::type, typename decay<_Args>::type...>::type> +async(launch __policy, _F&& __f, _Args&&... __args) +{ + typedef __async_func<typename decay<_F>::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 <class _F, class... _Args> +inline _LIBCPP_INLINE_VISIBILITY +future<typename __invoke_of<typename decay<_F>::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 _R> +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 <class _Rep, class _Period> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template <class _Clock, class _Duration> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template <class _R> +shared_future<_R>::~shared_future() +{ + if (__state_) + __state_->__release_shared(); +} + +template <class _R> +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 _R> +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 <class _Rep, class _Period> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template <class _Clock, class _Duration> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template <class _R> +shared_future<_R&>::~shared_future() +{ + if (__state_) + __state_->__release_shared(); +} + +template <class _R> +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<void> +{ + __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<void>&& __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 <class _Rep, class _Period> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const + {return __state_->wait_for(__rel_time);} + template <class _Clock, class _Duration> + _LIBCPP_INLINE_VISIBILITY + future_status + wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const + {return __state_->wait_until(__abs_time);} +}; + +template <class _R> +inline _LIBCPP_INLINE_VISIBILITY +void +swap(shared_future<_R>& __x, shared_future<_R>& __y) +{ + __x.swap(__y); +} + +template <class _R> +inline _LIBCPP_INLINE_VISIBILITY +shared_future<_R> +future<_R>::share() +{ + return shared_future<_R>(_VSTD::move(*this)); +} + +template <class _R> +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<void> +future<void>::share() +{ + return shared_future<void>(_VSTD::move(*this)); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_FUTURE |