// -*- 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<future_errc> : 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:
    future_error(error_code ec);  // exposition only
    explicit future_error(future_errc); // C++17
    const error_code& code() const noexcept;
    const char*       what() const noexcept;
};

template <class R>
class promise
{
public:
    promise();
    template <class Allocator>
        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<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) 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<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) 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<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) noexcept;

template <class R, class Alloc>
    struct uses_allocator<promise<R>, Alloc> : public true_type {};

template <class R>
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<R> share() noexcept;

    // retrieving the value
    R get();

    // functions to check state
    bool valid() const noexcept;

    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() noexcept;
    future(future&&) noexcept;
    future(const future& rhs) = delete;
    ~future();
    future& operator=(const future& rhs) = delete;
    future& operator=(future&&) noexcept;
    shared_future<R&> share() noexcept;

    // retrieving the value
    R& get();

    // functions to check state
    bool valid() const noexcept;

    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() noexcept;
    future(future&&) noexcept;
    future(const future& rhs) = delete;
    ~future();
    future& operator=(const future& rhs) = delete;
    future& operator=(future&&) noexcept;
    shared_future<void> share() noexcept;

    // retrieving the value
    void get();

    // functions to check state
    bool valid() const noexcept;

    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() noexcept;
    shared_future(const shared_future& rhs);
    shared_future(future<R>&&) 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 <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() noexcept;
    shared_future(const shared_future& rhs);
    shared_future(future<R&>&&) 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 <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() noexcept;
    shared_future(const shared_future& rhs);
    shared_future(future<void>&&) 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 <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<typename decay<F>::type(typename decay<Args>::type...)>::type>
  async(F&& f, Args&&... args);

template <class F, class... Args>
  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::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; // extension

    // construction and destruction
    packaged_task() noexcept;
    template <class F>
        explicit packaged_task(F&& f);
    template <class F, class Allocator>
        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<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...)>&) noexcept;

template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;

}  // std

*/

#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__chrono/duration.h>
#include <__chrono/time_point.h>
#include <__config>
#include <__memory/allocator_arg_t.h>
#include <__memory/uses_allocator.h>
#include <__utility/auto_cast.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <exception>
#include <memory>
#include <mutex>
#include <system_error>
#include <thread>
#include <version>

#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
#  include <chrono>
#endif

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

#ifdef _LIBCPP_HAS_NO_THREADS
# error "<future> is not supported since libc++ has been configured without support for threads."
#endif

_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<future_errc> : public true_type {};

#ifdef _LIBCPP_CXX03_LANG
template <>
struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : 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<launch>::type __launch_underlying_type;

inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR
launch
operator&(launch __x, launch __y)
{
    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
                               static_cast<__launch_underlying_type>(__y));
}

inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR
launch
operator|(launch __x, launch __y)
{
    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
                               static_cast<__launch_underlying_type>(__y));
}

inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR
launch
operator^(launch __x, launch __y)
{
    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
                               static_cast<__launch_underlying_type>(__y));
}

inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR
launch
operator~(launch __x)
{
    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
}

inline _LIBCPP_INLINE_VISIBILITY
launch&
operator&=(launch& __x, launch __y)
{
    __x = __x & __y; return __x;
}

inline _LIBCPP_INLINE_VISIBILITY
launch&
operator|=(launch& __x, launch __y)
{
    __x = __x | __y; return __x;
}

inline _LIBCPP_INLINE_VISIBILITY
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_FUNC_VIS
const error_category& future_category() _NOEXCEPT;

inline _LIBCPP_INLINE_VISIBILITY
error_code
make_error_code(future_errc __e) _NOEXCEPT
{
    return error_code(static_cast<int>(__e), future_category());
}

inline _LIBCPP_INLINE_VISIBILITY
error_condition
make_error_condition(future_errc __e) _NOEXCEPT
{
    return error_condition(static_cast<int>(__e), future_category());
}

class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
    : public logic_error
{
    error_code __ec_;
public:
    future_error(error_code __ec);

    _LIBCPP_INLINE_VISIBILITY
    const error_code& code() const _NOEXCEPT {return __ec_;}

    future_error(const future_error&) _NOEXCEPT = default;
    virtual ~future_error() _NOEXCEPT;
};

_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
#ifndef _LIBCPP_NO_EXCEPTIONS
_LIBCPP_AVAILABILITY_FUTURE_ERROR
#endif
void __throw_future_error(future_errc _Ev)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    throw future_error(make_error_code(_Ev));
#else
    ((void)_Ev);
    _VSTD::abort();
#endif
}

class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __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 __attach_future() {
        lock_guard<mutex> __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_INLINE_VISIBILITY
    void __set_deferred() {__state_ |= deferred;}

    void __make_ready();
    _LIBCPP_INLINE_VISIBILITY
    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 <class _Rep, class _Period>
        future_status
        _LIBCPP_INLINE_VISIBILITY
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
    template <class _Clock, class _Duration>
        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
        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
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 _Rp>
class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
    : public __assoc_sub_state
{
    typedef __assoc_sub_state base;
    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
protected:
    _Up __value_;

    virtual void __on_zero_shared() _NOEXCEPT;
public:

    template <class _Arg>
    void set_value(_Arg&& __arg);

    template <class _Arg>
    void set_value_at_thread_exit(_Arg&& __arg);

    _Rp move();
    typename add_lvalue_reference<_Rp>::type copy();
};

template <class _Rp>
void
__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
{
    if (this->__state_ & base::__constructed)
        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
    delete this;
}

template <class _Rp>
template <class _Arg>
_LIBCPP_AVAILABILITY_FUTURE
void
__assoc_state<_Rp>::set_value(_Arg&& __arg)
{
    unique_lock<mutex> __lk(this->__mut_);
    if (this->__has_value())
        __throw_future_error(future_errc::promise_already_satisfied);
    ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
    this->__state_ |= base::__constructed | base::ready;
    __cv_.notify_all();
}

template <class _Rp>
template <class _Arg>
void
__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
{
    unique_lock<mutex> __lk(this->__mut_);
    if (this->__has_value())
        __throw_future_error(future_errc::promise_already_satisfied);
    ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
    this->__state_ |= base::__constructed;
    __thread_local_data()->__make_ready_at_thread_exit(this);
}

template <class _Rp>
_Rp
__assoc_state<_Rp>::move()
{
    unique_lock<mutex> __lk(this->__mut_);
    this->__sub_wait(__lk);
    if (this->__exception_ != nullptr)
        rethrow_exception(this->__exception_);
    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
}

template <class _Rp>
typename add_lvalue_reference<_Rp>::type
__assoc_state<_Rp>::copy()
{
    unique_lock<mutex> __lk(this->__mut_);
    this->__sub_wait(__lk);
    if (this->__exception_ != nullptr)
        rethrow_exception(this->__exception_);
    return *reinterpret_cast<_Rp*>(&__value_);
}

template <class _Rp>
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
    : public __assoc_sub_state
{
    typedef __assoc_sub_state base;
    typedef _Rp* _Up;
protected:
    _Up __value_;

    virtual void __on_zero_shared() _NOEXCEPT;
public:

    void set_value(_Rp& __arg);
    void set_value_at_thread_exit(_Rp& __arg);

    _Rp& copy();
};

template <class _Rp>
void
__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
{
    delete this;
}

template <class _Rp>
void
__assoc_state<_Rp&>::set_value(_Rp& __arg)
{
    unique_lock<mutex> __lk(this->__mut_);
    if (this->__has_value())
        __throw_future_error(future_errc::promise_already_satisfied);
    __value_ = _VSTD::addressof(__arg);
    this->__state_ |= base::__constructed | base::ready;
    __cv_.notify_all();
}

template <class _Rp>
void
__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
{
    unique_lock<mutex> __lk(this->__mut_);
    if (this->__has_value())
        __throw_future_error(future_errc::promise_already_satisfied);
    __value_ = _VSTD::addressof(__arg);
    this->__state_ |= base::__constructed;
    __thread_local_data()->__make_ready_at_thread_exit(this);
}

template <class _Rp>
_Rp&
__assoc_state<_Rp&>::copy()
{
    unique_lock<mutex> __lk(this->__mut_);
    this->__sub_wait(__lk);
    if (this->__exception_ != nullptr)
        rethrow_exception(this->__exception_);
    return *__value_;
}

template <class _Rp, class _Alloc>
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
    : public __assoc_state<_Rp>
{
    typedef __assoc_state<_Rp> base;
    _Alloc __alloc_;

    virtual void __on_zero_shared() _NOEXCEPT;
public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __assoc_state_alloc(const _Alloc& __a)
        : __alloc_(__a) {}
};

template <class _Rp, class _Alloc>
void
__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
{
    if (this->__state_ & base::__constructed)
        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
    typedef allocator_traits<_Al> _ATraits;
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
    _Al __a(__alloc_);
    this->~__assoc_state_alloc();
    __a.deallocate(_PTraits::pointer_to(*this), 1);
}

template <class _Rp, class _Alloc>
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
    : public __assoc_state<_Rp&>
{
    typedef __assoc_state<_Rp&> base;
    _Alloc __alloc_;

    virtual void __on_zero_shared() _NOEXCEPT;
public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __assoc_state_alloc(const _Alloc& __a)
        : __alloc_(__a) {}
};

template <class _Rp, class _Alloc>
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<typename _ATraits::pointer> _PTraits;
    _Al __a(__alloc_);
    this->~__assoc_state_alloc();
    __a.deallocate(_PTraits::pointer_to(*this), 1);
}

template <class _Alloc>
class _LIBCPP_AVAILABILITY_FUTURE __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
{
    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
    typedef allocator_traits<_Al> _ATraits;
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
    _Al __a(__alloc_);
    this->~__assoc_sub_state_alloc();
    __a.deallocate(_PTraits::pointer_to(*this), 1);
}

template <class _Rp, class _Fp>
class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
    : public __assoc_state<_Rp>
{
    typedef __assoc_state<_Rp> base;

    _Fp __func_;

public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __deferred_assoc_state(_Fp&& __f);

    virtual void __execute();
};

template <class _Rp, class _Fp>
inline
__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
    : __func_(_VSTD::forward<_Fp>(__f))
{
    this->__set_deferred();
}

template <class _Rp, class _Fp>
void
__deferred_assoc_state<_Rp, _Fp>::__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 _Fp>
class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
    : public __assoc_sub_state
{
    typedef __assoc_sub_state base;

    _Fp __func_;

public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __deferred_assoc_state(_Fp&& __f);

    virtual void __execute();
};

template <class _Fp>
inline
__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
    : __func_(_VSTD::forward<_Fp>(__f))
{
    this->__set_deferred();
}

template <class _Fp>
void
__deferred_assoc_state<void, _Fp>::__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 _Rp, class _Fp>
class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
    : public __assoc_state<_Rp>
{
    typedef __assoc_state<_Rp> base;

    _Fp __func_;

    virtual void __on_zero_shared() _NOEXCEPT;
public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __async_assoc_state(_Fp&& __f);

    virtual void __execute();
};

template <class _Rp, class _Fp>
inline
__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
    : __func_(_VSTD::forward<_Fp>(__f))
{
}

template <class _Rp, class _Fp>
void
__async_assoc_state<_Rp, _Fp>::__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 _Rp, class _Fp>
void
__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
{
    this->wait();
    base::__on_zero_shared();
}

template <class _Fp>
class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
    : public __assoc_sub_state
{
    typedef __assoc_sub_state base;

    _Fp __func_;

    virtual void __on_zero_shared() _NOEXCEPT;
public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __async_assoc_state(_Fp&& __f);

    virtual void __execute();
};

template <class _Fp>
inline
__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
    : __func_(_VSTD::forward<_Fp>(__f))
{
}

template <class _Fp>
void
__async_assoc_state<void, _Fp>::__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 _Fp>
void
__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
{
    this->wait();
    base::__on_zero_shared();
}

template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;

// future

template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;

template <class _Rp, class _Fp>
_LIBCPP_INLINE_VISIBILITY future<_Rp>
__make_deferred_assoc_state(_Fp&& __f);

template <class _Rp, class _Fp>
_LIBCPP_INLINE_VISIBILITY future<_Rp>
__make_async_assoc_state(_Fp&& __f);

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
{
    __assoc_state<_Rp>* __state_;

    explicit future(__assoc_state<_Rp>* __state);

    template <class> friend class promise;
    template <class> friend class shared_future;

    template <class _R1, class _Fp>
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
    template <class _R1, class _Fp>
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);

public:
    _LIBCPP_INLINE_VISIBILITY
    future() _NOEXCEPT : __state_(nullptr) {}
    _LIBCPP_INLINE_VISIBILITY
    future(future&& __rhs) _NOEXCEPT
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
    future(const future&) = delete;
    future& operator=(const future&) = delete;
    _LIBCPP_INLINE_VISIBILITY
    future& operator=(future&& __rhs) _NOEXCEPT
        {
            future(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }

    ~future();
    _LIBCPP_INLINE_VISIBILITY
    shared_future<_Rp> share() _NOEXCEPT;

    // retrieving the value
    _Rp get();

    _LIBCPP_INLINE_VISIBILITY
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}

    // functions to check state
    _LIBCPP_INLINE_VISIBILITY
    bool valid() const _NOEXCEPT {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 _Rp>
future<_Rp>::future(__assoc_state<_Rp>* __state)
    : __state_(__state)
{
    __state_->__attach_future();
}

struct __release_shared_count
{
    void operator()(__shared_count* p) {p->__release_shared();}
};

template <class _Rp>
future<_Rp>::~future()
{
    if (__state_)
        __state_->__release_shared();
}

template <class _Rp>
_Rp
future<_Rp>::get()
{
    unique_ptr<__shared_count, __release_shared_count> __(__state_);
    __assoc_state<_Rp>* __s = __state_;
    __state_ = nullptr;
    return __s->move();
}

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
{
    __assoc_state<_Rp&>* __state_;

    explicit future(__assoc_state<_Rp&>* __state);

    template <class> friend class promise;
    template <class> friend class shared_future;

    template <class _R1, class _Fp>
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
    template <class _R1, class _Fp>
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);

public:
    _LIBCPP_INLINE_VISIBILITY
    future() _NOEXCEPT : __state_(nullptr) {}
    _LIBCPP_INLINE_VISIBILITY
    future(future&& __rhs) _NOEXCEPT
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
    future(const future&) = delete;
    future& operator=(const future&) = delete;
    _LIBCPP_INLINE_VISIBILITY
    future& operator=(future&& __rhs) _NOEXCEPT
        {
            future(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }

    ~future();
    _LIBCPP_INLINE_VISIBILITY
    shared_future<_Rp&> share() _NOEXCEPT;

    // retrieving the value
    _Rp& get();

    _LIBCPP_INLINE_VISIBILITY
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}

    // functions to check state
    _LIBCPP_INLINE_VISIBILITY
    bool valid() const _NOEXCEPT {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 _Rp>
future<_Rp&>::future(__assoc_state<_Rp&>* __state)
    : __state_(__state)
{
    __state_->__attach_future();
}

template <class _Rp>
future<_Rp&>::~future()
{
    if (__state_)
        __state_->__release_shared();
}

template <class _Rp>
_Rp&
future<_Rp&>::get()
{
    unique_ptr<__shared_count, __release_shared_count> __(__state_);
    __assoc_state<_Rp&>* __s = __state_;
    __state_ = nullptr;
    return __s->copy();
}

template <>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
{
    __assoc_sub_state* __state_;

    explicit future(__assoc_sub_state* __state);

    template <class> friend class promise;
    template <class> friend class shared_future;

    template <class _R1, class _Fp>
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
    template <class _R1, class _Fp>
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);

public:
    _LIBCPP_INLINE_VISIBILITY
    future() _NOEXCEPT : __state_(nullptr) {}
    _LIBCPP_INLINE_VISIBILITY
    future(future&& __rhs) _NOEXCEPT
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
    future(const future&) = delete;
    future& operator=(const future&) = delete;
    _LIBCPP_INLINE_VISIBILITY
    future& operator=(future&& __rhs) _NOEXCEPT
        {
            future(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }

    ~future();
    _LIBCPP_INLINE_VISIBILITY
    shared_future<void> share() _NOEXCEPT;

    // retrieving the value
    void get();

    _LIBCPP_INLINE_VISIBILITY
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}

    // functions to check state
    _LIBCPP_INLINE_VISIBILITY
    bool valid() const _NOEXCEPT {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 _Rp>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
{
    __x.swap(__y);
}

// promise<R>

template <class _Callable> class packaged_task;

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
{
    __assoc_state<_Rp>* __state_;

    _LIBCPP_INLINE_VISIBILITY
    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}

    template <class> friend class packaged_task;
public:
    promise();
    template <class _Alloc>
        promise(allocator_arg_t, const _Alloc& __a);
    _LIBCPP_INLINE_VISIBILITY
    promise(promise&& __rhs) _NOEXCEPT
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
    promise(const promise& __rhs) = delete;
    ~promise();

    // assignment
    _LIBCPP_INLINE_VISIBILITY
    promise& operator=(promise&& __rhs) _NOEXCEPT
        {
            promise(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }
    promise& operator=(const promise& __rhs) = delete;

    _LIBCPP_INLINE_VISIBILITY
    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}

    // retrieving the result
    future<_Rp> get_future();

    // setting the result
    void set_value(const _Rp& __r);
    void set_value(_Rp&& __r);
    void set_exception(exception_ptr __p);

    // setting the result with deferred notification
    void set_value_at_thread_exit(const _Rp& __r);
    void set_value_at_thread_exit(_Rp&& __r);
    void set_exception_at_thread_exit(exception_ptr __p);
};

template <class _Rp>
promise<_Rp>::promise()
    : __state_(new __assoc_state<_Rp>)
{
}

template <class _Rp>
template <class _Alloc>
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*)_VSTD::addressof(*__hold.get())) _State(__a0);
    __state_ = _VSTD::addressof(*__hold.release());
}

template <class _Rp>
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 <class _Rp>
future<_Rp>
promise<_Rp>::get_future()
{
    if (__state_ == nullptr)
        __throw_future_error(future_errc::no_state);
    return future<_Rp>(__state_);
}

template <class _Rp>
void
promise<_Rp>::set_value(const _Rp& __r)
{
    if (__state_ == nullptr)
        __throw_future_error(future_errc::no_state);
    __state_->set_value(__r);
}

template <class _Rp>
void
promise<_Rp>::set_value(_Rp&& __r)
{
    if (__state_ == nullptr)
        __throw_future_error(future_errc::no_state);
    __state_->set_value(_VSTD::move(__r));
}

template <class _Rp>
void
promise<_Rp>::set_exception(exception_ptr __p)
{
    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
    if (__state_ == nullptr)
        __throw_future_error(future_errc::no_state);
    __state_->set_exception(__p);
}

template <class _Rp>
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 <class _Rp>
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(_VSTD::move(__r));
}

template <class _Rp>
void
promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
{
    _LIBCPP_ASSERT( __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<R&>

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
{
    __assoc_state<_Rp&>* __state_;

    _LIBCPP_INLINE_VISIBILITY
    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}

    template <class> friend class packaged_task;

public:
    promise();
    template <class _Allocator>
        promise(allocator_arg_t, const _Allocator& __a);
    _LIBCPP_INLINE_VISIBILITY
    promise(promise&& __rhs) _NOEXCEPT
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
    promise(const promise& __rhs) = delete;
    ~promise();

    // assignment
    _LIBCPP_INLINE_VISIBILITY
    promise& operator=(promise&& __rhs) _NOEXCEPT
        {
            promise(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }
    promise& operator=(const promise& __rhs) = delete;

    _LIBCPP_INLINE_VISIBILITY
    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}

    // retrieving the result
    future<_Rp&> get_future();

    // setting the result
    void set_value(_Rp& __r);
    void set_exception(exception_ptr __p);

    // setting the result with deferred notification
    void set_value_at_thread_exit(_Rp&);
    void set_exception_at_thread_exit(exception_ptr __p);
};

template <class _Rp>
promise<_Rp&>::promise()
    : __state_(new __assoc_state<_Rp&>)
{
}

template <class _Rp>
template <class _Alloc>
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*)_VSTD::addressof(*__hold.get())) _State(__a0);
    __state_ = _VSTD::addressof(*__hold.release());
}

template <class _Rp>
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 <class _Rp>
future<_Rp&>
promise<_Rp&>::get_future()
{
    if (__state_ == nullptr)
        __throw_future_error(future_errc::no_state);
    return future<_Rp&>(__state_);
}

template <class _Rp>
void
promise<_Rp&>::set_value(_Rp& __r)
{
    if (__state_ == nullptr)
        __throw_future_error(future_errc::no_state);
    __state_->set_value(__r);
}

template <class _Rp>
void
promise<_Rp&>::set_exception(exception_ptr __p)
{
    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
    if (__state_ == nullptr)
        __throw_future_error(future_errc::no_state);
    __state_->set_exception(__p);
}

template <class _Rp>
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 <class _Rp>
void
promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
{
    _LIBCPP_ASSERT( __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<void>

template <>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
{
    __assoc_sub_state* __state_;

    _LIBCPP_INLINE_VISIBILITY
    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}

    template <class> friend class packaged_task;

public:
    promise();
    template <class _Allocator>
        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
        promise(allocator_arg_t, const _Allocator& __a);
    _LIBCPP_INLINE_VISIBILITY
    promise(promise&& __rhs) _NOEXCEPT
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
    promise(const promise& __rhs) = delete;
    ~promise();

    // assignment
    _LIBCPP_INLINE_VISIBILITY
    promise& operator=(promise&& __rhs) _NOEXCEPT
        {
            promise(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }
    promise& operator=(const promise& __rhs) = delete;

    _LIBCPP_INLINE_VISIBILITY
    void swap(promise& __rhs) _NOEXCEPT {_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 __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*)_VSTD::addressof(*__hold.get())) _State(__a0);
    __state_ = _VSTD::addressof(*__hold.release());
}

template <class _Rp>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
{
    __x.swap(__y);
}

template <class _Rp, class _Alloc>
    struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
        : public true_type {};

// packaged_task

template<class _Fp> class __packaged_task_base;

template<class _Rp, class ..._ArgTypes>
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_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*) _NOEXCEPT = 0;
    virtual void destroy() = 0;
    virtual void destroy_deallocate() = 0;
    virtual _Rp operator()(_ArgTypes&& ...) = 0;
};

template<class _FD, class _Alloc, class _FB> class __packaged_task_func;

template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
    : public  __packaged_task_base<_Rp(_ArgTypes...)>
{
    __compressed_pair<_Fp, _Alloc> __f_;
public:
    _LIBCPP_INLINE_VISIBILITY
    explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
    _LIBCPP_INLINE_VISIBILITY
    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
    _LIBCPP_INLINE_VISIBILITY
    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
        : __f_(__f, __a) {}
    _LIBCPP_INLINE_VISIBILITY
    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
        : __f_(_VSTD::move(__f), __a) {}
    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
    virtual void destroy();
    virtual void destroy_deallocate();
    virtual _Rp operator()(_ArgTypes&& ... __args);
};

template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
void
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
{
    ::new ((void*)__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
}

template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
void
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
{
    __f_.~__compressed_pair<_Fp, _Alloc>();
}

template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
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<typename _ATraits::pointer> _PTraits;
    _Ap __a(__f_.second());
    __f_.~__compressed_pair<_Fp, _Alloc>();
    __a.deallocate(_PTraits::pointer_to(*this), 1);
}

template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
_Rp
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
{
    return _VSTD::__invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
}

template <class _Callable> class __packaged_task_function;

template<class _Rp, class ..._ArgTypes>
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
{
    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;

    _LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
    __base* __get_buf() { return (__base*)&__buf_; }

    typename aligned_storage<3*sizeof(void*)>::type __buf_;
    __base* __f_;

public:
    typedef _Rp result_type;

    // construct/copy/destroy:
    _LIBCPP_INLINE_VISIBILITY
    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
    template<class _Fp>
      __packaged_task_function(_Fp&& __f);
    template<class _Fp, class _Alloc>
      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);

    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
    __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;

    ~__packaged_task_function();

    void swap(__packaged_task_function&) _NOEXCEPT;

    _LIBCPP_INLINE_VISIBILITY
    _Rp operator()(_ArgTypes...) const;
};

template<class _Rp, class ..._ArgTypes>
__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<class _Rp, class ..._ArgTypes>
template <class _Fp>
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
    : __f_(nullptr)
{
    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
    if (sizeof(_FF) <= sizeof(__buf_))
    {
        ::new ((void*)&__buf_) _FF(_VSTD::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(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
        __f_ = __hold.release();
    }
}

template<class _Rp, class ..._ArgTypes>
template <class _Fp, class _Alloc>
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
    : __f_(nullptr)
{
    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
    if (sizeof(_FF) <= sizeof(__buf_))
    {
        __f_ = (__base*)&__buf_;
        ::new ((void*)__f_) _FF(_VSTD::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*)_VSTD::addressof(*__hold.get()))
            _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
        __f_ = _VSTD::addressof(*__hold.release());
    }
}

template<class _Rp, class ..._ArgTypes>
__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<class _Rp, class ..._ArgTypes>
__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
{
    if (__f_ == __get_buf())
        __f_->destroy();
    else if (__f_)
        __f_->destroy_deallocate();
}

template<class _Rp, class ..._ArgTypes>
_LIBCPP_NO_CFI
void
__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
{
    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 _Rp, class ..._ArgTypes>
inline
_Rp
__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
{
    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
}

template<class _Rp, class ..._ArgTypes>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
{
public:
    typedef _Rp result_type; // extension

private:
    __packaged_task_function<result_type(_ArgTypes...)> __f_;
    promise<result_type>                                __p_;

public:
    // construction and destruction
    _LIBCPP_INLINE_VISIBILITY
    packaged_task() _NOEXCEPT : __p_(nullptr) {}
    template <class _Fp,
              class = __enable_if_t<!is_same<__uncvref_t<_Fp>, packaged_task>::value> >
        _LIBCPP_INLINE_VISIBILITY
        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
    template <class _Fp, class _Allocator,
              class = __enable_if_t<!is_same<__uncvref_t<_Fp>, packaged_task>::value> >
        _LIBCPP_INLINE_VISIBILITY
        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
               __p_(allocator_arg, __a) {}
    // ~packaged_task() = default;

    // no copy
    packaged_task(const packaged_task&) = delete;
    packaged_task& operator=(const packaged_task&) = delete;

    // move support
    _LIBCPP_INLINE_VISIBILITY
    packaged_task(packaged_task&& __other) _NOEXCEPT
        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
    _LIBCPP_INLINE_VISIBILITY
    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
    {
        __f_ = _VSTD::move(__other.__f_);
        __p_ = _VSTD::move(__other.__p_);
        return *this;
    }
    _LIBCPP_INLINE_VISIBILITY
    void swap(packaged_task& __other) _NOEXCEPT
    {
        __f_.swap(__other.__f_);
        __p_.swap(__other.__p_);
    }

    _LIBCPP_INLINE_VISIBILITY
    bool valid() const _NOEXCEPT {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 _Rp, class ..._ArgTypes>
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_NO_EXCEPTIONS
    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 _Rp, class ..._ArgTypes>
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_NO_EXCEPTIONS
    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 _Rp, class ..._ArgTypes>
void
packaged_task<_Rp(_ArgTypes...)>::reset()
{
    if (!valid())
        __throw_future_error(future_errc::no_state);
    __p_ = promise<result_type>();
}

template<class ..._ArgTypes>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
{
public:
    typedef void result_type; // extension

private:
    __packaged_task_function<result_type(_ArgTypes...)> __f_;
    promise<result_type>                                __p_;

public:
    // construction and destruction
    _LIBCPP_INLINE_VISIBILITY
    packaged_task() _NOEXCEPT : __p_(nullptr) {}
    template <class _Fp,
              class = __enable_if_t<!is_same<__uncvref_t<_Fp>, packaged_task>::value> >
        _LIBCPP_INLINE_VISIBILITY
        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
    template <class _Fp, class _Allocator,
              class = __enable_if_t<!is_same<__uncvref_t<_Fp>, packaged_task>::value> >
        _LIBCPP_INLINE_VISIBILITY
        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
               __p_(allocator_arg, __a) {}
    // ~packaged_task() = default;

    // no copy
    packaged_task(const packaged_task&) = delete;
    packaged_task& operator=(const packaged_task&) = delete;

    // move support
    _LIBCPP_INLINE_VISIBILITY
    packaged_task(packaged_task&& __other) _NOEXCEPT
        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
    _LIBCPP_INLINE_VISIBILITY
    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
    {
        __f_ = _VSTD::move(__other.__f_);
        __p_ = _VSTD::move(__other.__p_);
        return *this;
    }
    _LIBCPP_INLINE_VISIBILITY
    void swap(packaged_task& __other) _NOEXCEPT
    {
        __f_.swap(__other.__f_);
        __p_.swap(__other.__p_);
    }

    _LIBCPP_INLINE_VISIBILITY
    bool valid() const _NOEXCEPT {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)
{
    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_NO_EXCEPTIONS
    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)
{
    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_NO_EXCEPTIONS
    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()
{
    if (!valid())
        __throw_future_error(future_errc::no_state);
    __p_ = promise<result_type>();
}

template <class _Rp, class... _ArgTypes>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
{
    __x.swap(__y);
}

template <class _Callable, class _Alloc>
struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
    : public true_type {};

template <class _Rp, class _Fp>
_LIBCPP_INLINE_VISIBILITY 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>(_VSTD::forward<_Fp>(__f)));
    return future<_Rp>(__h.get());
}

template <class _Rp, class _Fp>
_LIBCPP_INLINE_VISIBILITY 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>(_VSTD::forward<_Fp>(__f)));
    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
    return future<_Rp>(__h.get());
}

#ifndef _LIBCPP_CXX03_LANG

template <class _Fp, class... _Args>
class _LIBCPP_HIDDEN __async_func
{
    tuple<_Fp, _Args...> __f_;

public:
    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;

    _LIBCPP_INLINE_VISIBILITY
    explicit __async_func(_Fp&& __f, _Args&&... __args)
        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}

    _LIBCPP_INLINE_VISIBILITY
    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}

    _Rp operator()()
    {
        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
        return __execute(_Index());
    }
private:
    template <size_t ..._Indices>
    _Rp
    __execute(__tuple_indices<_Indices...>)
    {
        return _VSTD::__invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
    }
};

inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
{ return (int(__policy) & int(__value)) != 0; }

template <class _Fp, class... _Args>
_LIBCPP_NODISCARD_AFTER_CXX17
future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
async(launch __policy, _Fp&& __f, _Args&&... __args)
{
    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
    typedef typename _BF::_Rp _Rp;

#ifndef _LIBCPP_NO_EXCEPTIONS
    try
    {
#endif
        if (__does_policy_contain(__policy, launch::async))
        return _VSTD::__make_async_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(_VSTD::forward<_Fp>(__f)),
                                                        _LIBCPP_AUTO_CAST(_VSTD::forward<_Args>(__args))...));
#ifndef _LIBCPP_NO_EXCEPTIONS
    }
    catch ( ... ) { if (__policy == launch::async) throw ; }
#endif

    if (__does_policy_contain(__policy, launch::deferred))
        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(_VSTD::forward<_Fp>(__f)),
                                                           _LIBCPP_AUTO_CAST(_VSTD::forward<_Args>(__args))...));
    return future<_Rp>{};
}

template <class _Fp, class... _Args>
_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
async(_Fp&& __f, _Args&&... __args)
{
    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
                                    _VSTD::forward<_Args>(__args)...);
}

#endif // C++03

// shared_future

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS shared_future
{
    __assoc_state<_Rp>* __state_;

public:
    _LIBCPP_INLINE_VISIBILITY
    shared_future() _NOEXCEPT : __state_(nullptr) {}
    _LIBCPP_INLINE_VISIBILITY
    shared_future(const shared_future& __rhs)  _NOEXCEPT : __state_(__rhs.__state_)
        {if (__state_) __state_->__add_shared();}
    _LIBCPP_INLINE_VISIBILITY
    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
        {__f.__state_ = nullptr;}
    _LIBCPP_INLINE_VISIBILITY
    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
        {__rhs.__state_ = nullptr;}
    ~shared_future();
    shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
    _LIBCPP_INLINE_VISIBILITY
    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
        {
            shared_future(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }

    // retrieving the value
    _LIBCPP_INLINE_VISIBILITY
    const _Rp& get() const {return __state_->copy();}

    _LIBCPP_INLINE_VISIBILITY
    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}

    // functions to check state
    _LIBCPP_INLINE_VISIBILITY
    bool valid() const _NOEXCEPT {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 _Rp>
shared_future<_Rp>::~shared_future()
{
    if (__state_)
        __state_->__release_shared();
}

template <class _Rp>
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 _Rp>
class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
{
    __assoc_state<_Rp&>* __state_;

public:
    _LIBCPP_INLINE_VISIBILITY
    shared_future() _NOEXCEPT : __state_(nullptr) {}
    _LIBCPP_INLINE_VISIBILITY
    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
        {if (__state_) __state_->__add_shared();}
    _LIBCPP_INLINE_VISIBILITY
    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
        {__f.__state_ = nullptr;}
    _LIBCPP_INLINE_VISIBILITY
    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
        {__rhs.__state_ = nullptr;}
    ~shared_future();
    shared_future& operator=(const shared_future& __rhs);
    _LIBCPP_INLINE_VISIBILITY
    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
        {
            shared_future(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }

    // retrieving the value
    _LIBCPP_INLINE_VISIBILITY
    _Rp& get() const {return __state_->copy();}

    _LIBCPP_INLINE_VISIBILITY
    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}

    // functions to check state
    _LIBCPP_INLINE_VISIBILITY
    bool valid() const _NOEXCEPT {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 _Rp>
shared_future<_Rp&>::~shared_future()
{
    if (__state_)
        __state_->__release_shared();
}

template <class _Rp>
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_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
{
    __assoc_sub_state* __state_;

public:
    _LIBCPP_INLINE_VISIBILITY
    shared_future() _NOEXCEPT : __state_(nullptr) {}
    _LIBCPP_INLINE_VISIBILITY
    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
        {if (__state_) __state_->__add_shared();}
    _LIBCPP_INLINE_VISIBILITY
    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
        {__f.__state_ = nullptr;}
    _LIBCPP_INLINE_VISIBILITY
    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
        {__rhs.__state_ = nullptr;}
    ~shared_future();
    shared_future& operator=(const shared_future& __rhs);
    _LIBCPP_INLINE_VISIBILITY
    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
        {
            shared_future(_VSTD::move(__rhs)).swap(*this);
            return *this;
        }

    // retrieving the value
    _LIBCPP_INLINE_VISIBILITY
    void get() const {__state_->copy();}

    _LIBCPP_INLINE_VISIBILITY
    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}

    // functions to check state
    _LIBCPP_INLINE_VISIBILITY
    bool valid() const _NOEXCEPT {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 _Rp>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
{
    __x.swap(__y);
}

template <class _Rp>
inline
shared_future<_Rp>
future<_Rp>::share() _NOEXCEPT
{
    return shared_future<_Rp>(_VSTD::move(*this));
}

template <class _Rp>
inline
shared_future<_Rp&>
future<_Rp&>::share() _NOEXCEPT
{
    return shared_future<_Rp&>(_VSTD::move(*this));
}

inline
shared_future<void>
future<void>::share() _NOEXCEPT
{
    return shared_future<void>(_VSTD::move(*this));
}

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_FUTURE
