[futures.task] and [futures.async].  Requires variadics and rvalue-ref support.

llvm-svn: 112500
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 27f000e10bee7e8320b79f1723dc5ca05ad52227
diff --git a/include/future b/include/future
index abfb77d..b75014a 100644
--- a/include/future
+++ b/include/future
@@ -399,11 +399,6 @@
     // 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);
-    explicit packaged_task(R(*f)(ArgTypes...));
-    template <class F>
         explicit packaged_task(F&& f);
     template <class F, class Allocator>
         explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
@@ -538,7 +533,7 @@
     unsigned __state_;
 
     virtual void __on_zero_shared();
-
+    void __sub_wait(unique_lock<mutex>& __lk);
 public:
     enum
     {
@@ -556,6 +551,8 @@
     void __set_future_attached() {__state_ |= __future_attached;}
     bool __has_future_attached() const {return __state_ & __future_attached;}
 
+    void __set_deferred() {__state_ |= deferred;}
+
     void __make_ready();
     bool __is_ready() const {return __state_ & ready;}
 
@@ -567,13 +564,15 @@
 
     void copy();
 
-    void wait() const;
+    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>
@@ -581,12 +580,12 @@
 __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
 {
     unique_lock<mutex> __lk(__mut_);
-    while (!(__state_ & (ready | deferred)) && _Clock::now() < __abs_time)
+    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;
-    if (__state_ & deferred)
-        return future_status::deferred;
     return future_status::timeout;
 }
 
@@ -678,8 +677,7 @@
 __assoc_state<_R>::move()
 {
     unique_lock<mutex> __lk(this->__mut_);
-    while (!this->__is_ready())
-        this->__cv_.wait(__lk);
+    this->__sub_wait(__lk);
     if (this->__exception_ != nullptr)
         rethrow_exception(this->__exception_);
     return _STD::move(*reinterpret_cast<_R*>(&__value_));
@@ -690,8 +688,7 @@
 __assoc_state<_R>::copy()
 {
     unique_lock<mutex> __lk(this->__mut_);
-    while (!this->__is_ready())
-        this->__cv_.wait(__lk);
+    this->__sub_wait(__lk);
     if (this->__exception_ != nullptr)
         rethrow_exception(this->__exception_);
     return *reinterpret_cast<_R*>(&__value_);
@@ -753,8 +750,7 @@
 __assoc_state<_R&>::copy()
 {
     unique_lock<mutex> __lk(this->__mut_);
-    while (!this->__is_ready())
-        this->__cv_.wait(__lk);
+    this->__sub_wait(__lk);
     if (this->__exception_ != nullptr)
         rethrow_exception(this->__exception_);
     return *__value_;
@@ -829,10 +825,113 @@
     __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:
+#ifdef _LIBCPP_MOVE
+    explicit __deferred_assoc_state(_F&& __f);
+#endif
+
+    virtual void __execute();
+};
+
+#ifdef _LIBCPP_MOVE
+
+template <class _R, class _F>
+inline _LIBCPP_INLINE_VISIBILITY
+__deferred_assoc_state<_R, _F>::__deferred_assoc_state(_F&& __f)
+    : __func_(_STD::forward<_F>(__f))
+{
+    this->__set_deferred();
+}
+
+#endif  // _LIBCPP_MOVE
+
+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:
+#ifdef _LIBCPP_MOVE
+    explicit __deferred_assoc_state(_F&& __f);
+#endif
+
+    virtual void __execute();
+};
+
+#ifdef _LIBCPP_MOVE
+
+template <class _F>
+inline _LIBCPP_INLINE_VISIBILITY
+__deferred_assoc_state<void, _F>::__deferred_assoc_state(_F&& __f)
+    : __func_(_STD::forward<_F>(__f))
+{
+    this->__set_deferred();
+}
+
+#endif  // _LIBCPP_MOVE
+
+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> class promise;
 
 // future
 
+template <class _R> class future;
+
+template <class _R, class _F>
+future<_R>
+#ifdef _LIBCPP_MOVE
+__make_deferred_assoc_state(_F&& __f);
+#else
+__make_deferred_assoc_state(_F __f);
+#endif
+
 template <class _R>
 class future
 {
@@ -841,6 +940,14 @@
     explicit future(__assoc_state<_R>* __state);
 
     template <class> friend class promise;
+
+    template <class _R1, class _F>
+#ifdef _LIBCPP_MOVE
+        friend future<_R1> __make_deferred_assoc_state(_F&& __f);
+#else
+        friend future<_R1> __make_deferred_assoc_state(_F __f);
+#endif
+
 public:
     future() : __state_(nullptr) {}
 #ifdef _LIBCPP_MOVE
@@ -887,8 +994,14 @@
     if (__state_->__has_future_attached())
         throw future_error(make_error_code(future_errc::future_already_retrieved));
     __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()
 {
@@ -900,6 +1013,7 @@
 _R
 future<_R>::get()
 {
+    unique_ptr<__shared_count, __release_shared_count> __(__state_);
     __assoc_state<_R>* __s = __state_;
     __state_ = nullptr;
     return __s->move();
@@ -913,6 +1027,14 @@
     explicit future(__assoc_state<_R&>* __state);
 
     template <class> friend class promise;
+
+    template <class _R1, class _F>
+#ifdef _LIBCPP_MOVE
+        friend future<_R1> __make_deferred_assoc_state(_F&& __f);
+#else
+        friend future<_R1> __make_deferred_assoc_state(_F __f);
+#endif
+
 public:
     future() : __state_(nullptr) {}
 #ifdef _LIBCPP_MOVE
@@ -959,6 +1081,7 @@
     if (__state_->__has_future_attached())
         throw future_error(make_error_code(future_errc::future_already_retrieved));
     __state_->__add_shared();
+    __state_->__set_future_attached();
 }
 
 template <class _R>
@@ -972,6 +1095,7 @@
 _R&
 future<_R&>::get()
 {
+    unique_ptr<__shared_count, __release_shared_count> __(__state_);
     __assoc_state<_R&>* __s = __state_;
     __state_ = nullptr;
     return __s->copy();
@@ -985,6 +1109,14 @@
     explicit future(__assoc_sub_state* __state);
 
     template <class> friend class promise;
+
+    template <class _R1, class _F>
+#ifdef _LIBCPP_MOVE
+        friend future<_R1> __make_deferred_assoc_state(_F&& __f);
+#else
+        friend future<_R1> __make_deferred_assoc_state(_F __f);
+#endif
+
 public:
     future() : __state_(nullptr) {}
 #ifdef _LIBCPP_MOVE
@@ -1026,10 +1158,16 @@
 
 // promise<R>
 
+template <class> class packaged_task;
+
 template <class _R>
 class promise
 {
     __assoc_state<_R>* __state_;
+
+    explicit promise(nullptr_t) : __state_(nullptr) {}
+
+    template <class> friend class packaged_task;
 public:
     promise();
     template <class _Alloc>
@@ -1186,6 +1324,11 @@
 class promise<_R&>
 {
     __assoc_state<_R&>* __state_;
+
+    explicit promise(nullptr_t) : __state_(nullptr) {}
+
+    template <class> friend class packaged_task;
+
 public:
     promise();
     template <class _Allocator>
@@ -1310,6 +1453,11 @@
 class promise<void>
 {
     __assoc_sub_state* __state_;
+
+    explicit promise(nullptr_t) : __state_(nullptr) {}
+
+    template <class> friend class packaged_task;
+
 public:
     promise();
     template <class _Allocator>
@@ -1374,6 +1522,534 @@
 template <class _R, class _Alloc>
     struct 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:
+    __packaged_task_base() {}
+    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:
+    explicit __packaged_task_func(const _F& __f) : __f_(__f) {}
+    explicit __packaged_task_func(_F&& __f) : __f_(_STD::move(__f)) {}
+    __packaged_task_func(const _F& __f, const _Alloc& __a)
+        : __f_(__f, __a) {}
+    __packaged_task_func(_F&& __f, const _Alloc& __a)
+        : __f_(_STD::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(_STD::move(__f_.first()), _STD::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(), _STD::forward<_ArgTypes>(__arg)...);
+}
+
+template <class> 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:
+    __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(_STD::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(_STD::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(_STD::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(_STD::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
+        _STD::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_)(_STD::forward<_ArgTypes>(__arg)...);
+}
+
+template<class _R, class ..._ArgTypes>
+class 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
+    packaged_task() : __p_(nullptr) {}
+    template <class _F>
+        explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
+    template <class _F, class _Allocator>
+        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
+             : __f_(allocator_arg, __a, _STD::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
+    packaged_task(packaged_task&& __other)
+        : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
+    packaged_task& operator=(packaged_task&& __other)
+    {
+        __f_ = _STD::move(__other.__f_);
+        __p_ = _STD::move(__other.__p_);
+        return *this;
+    }
+    void swap(packaged_task& __other)
+    {
+        __f_.swap(__other.__f_);
+        __p_.swap(__other.__p_);
+    }
+
+    //explicit
+        operator bool() const {return __p_.__state_ != nullptr;}
+
+    // result retrieval
+    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_(_STD::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_(_STD::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 (!(*this))
+        throw future_error(make_error_code(future_errc::no_state));
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    __p_ = promise<result_type>();
+}
+
+template<class ..._ArgTypes>
+class 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
+    packaged_task() : __p_(nullptr) {}
+    template <class _F>
+        explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
+    template <class _F, class _Allocator>
+        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
+             : __f_(allocator_arg, __a, _STD::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
+    packaged_task(packaged_task&& __other)
+        : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
+    packaged_task& operator=(packaged_task&& __other)
+    {
+        __f_ = _STD::move(__other.__f_);
+        __p_ = _STD::move(__other.__p_);
+        return *this;
+    }
+    void swap(packaged_task& __other)
+    {
+        __f_.swap(__other.__f_);
+        __p_.swap(__other.__p_);
+    }
+
+    //explicit
+        operator bool() const {return __p_.__state_ != nullptr;}
+
+    // result retrieval
+    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_(_STD::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_(_STD::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 (!(*this))
+        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 uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {};
+
+template <class _R, class _F>
+future<_R>
+#ifdef _LIBCPP_MOVE
+__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>(_STD::forward<_F>(__f)));
+    return future<_R>(__h.get());
+}
+
+template <class _F, class... _Args>
+future<typename result_of<_F(_Args...)>::type>
+async(launch __policy, _F&& __f, _Args&&... __args)
+{
+    typedef typename result_of<_F(_Args...)>::type _R;
+    future<_R> __r;
+    if (__policy == launch::sync)
+        __r = _STD::__make_deferred_assoc_state<_R>(bind(_STD::forward<_F>(__f),
+                                               _STD::forward<_Args>(__args)...));
+    else
+    {
+        packaged_task<_R()> __pk(bind(_STD::forward<_F>(__f),
+                                      _STD::forward<_Args>(__args)...));
+        __r = __pk.get_future();
+        thread(_STD::move(__pk)).detach();
+    }
+    return __r;
+}
+
+template <class _F, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_same<typename decay<_F>::type, launch>::value,
+    future<typename result_of<_F(_Args...)>::type>
+>::type
+async(_F&& __f, _Args&&... __args)
+{
+    return async(launch::any, _STD::forward<_F>(__f),
+                              _STD::forward<_Args>(__args)...);
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_FUTURE