// -*- 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:
    explicit future_error(future_errc e); // since C++17

    const error_code& code() const noexcept;
    const char*       what() const noexcept;

private:
    error_code ec_;             // exposition only
};

template <class 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);              // removed in C++17
    ~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>; // removed in C++17

}  // std

*/

#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#  include <__cxx03/future>
#else
#  include <__config>

#  if _LIBCPP_HAS_THREADS

#    include <__assert>
#    include <__chrono/duration.h>
#    include <__chrono/steady_clock.h>
#    include <__chrono/time_point.h>
#    include <__condition_variable/condition_variable.h>
#    include <__cstddef/nullptr_t.h>
#    include <__exception/exception_ptr.h>
#    include <__memory/addressof.h>
#    include <__memory/allocator.h>
#    include <__memory/allocator_arg_t.h>
#    include <__memory/allocator_destructor.h>
#    include <__memory/allocator_traits.h>
#    include <__memory/compressed_pair.h>
#    include <__memory/pointer_traits.h>
#    include <__memory/shared_count.h>
#    include <__memory/unique_ptr.h>
#    include <__memory/uses_allocator.h>
#    include <__mutex/lock_guard.h>
#    include <__mutex/mutex.h>
#    include <__mutex/unique_lock.h>
#    include <__system_error/error_category.h>
#    include <__system_error/error_code.h>
#    include <__system_error/error_condition.h>
#    include <__thread/thread.h>
#    include <__type_traits/add_lvalue_reference.h>
#    include <__type_traits/aligned_storage.h>
#    include <__type_traits/conditional.h>
#    include <__type_traits/decay.h>
#    include <__type_traits/enable_if.h>
#    include <__type_traits/invoke.h>
#    include <__type_traits/is_same.h>
#    include <__type_traits/remove_cvref.h>
#    include <__type_traits/remove_reference.h>
#    include <__type_traits/strip_signature.h>
#    include <__type_traits/underlying_type.h>
#    include <__utility/auto_cast.h>
#    include <__utility/forward.h>
#    include <__utility/move.h>
#    include <__utility/swap.h>
#    include <stdexcept>
#    include <tuple>
#    include <version>

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

_LIBCPP_PUSH_MACROS
#    include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

// enum class future_errc
_LIBCPP_DECLARE_STRONG_ENUM(future_errc){
    future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise};
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)

template <>
struct is_error_code_enum<future_errc> : public true_type {};

#    ifdef _LIBCPP_CXX03_LANG
template <>
struct 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

using __launch_underlying_type _LIBCPP_NODEBUG = __underlying_type_t<launch>;

inline _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI constexpr launch operator~(launch __x) {
  return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
}

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

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

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

#    endif // !_LIBCPP_CXX03_LANG

// enum class future_status
_LIBCPP_DECLARE_STRONG_ENUM(future_status){ready, timeout, deferred};
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)

_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;

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

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

[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev);

class _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error {
  error_code __ec_;

  future_error(error_code);
  friend void __throw_future_error(future_errc);
  template <class>
  friend class promise;

public:
#    if _LIBCPP_STD_VER >= 17
  _LIBCPP_HIDE_FROM_ABI explicit future_error(future_errc __ec) : future_error(std::make_error_code(__ec)) {}
#    endif

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

  _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default;
  ~future_error() _NOEXCEPT override;
};

// Declared above std::future_error
void __throw_future_error(future_errc __ev) {
#    if _LIBCPP_HAS_EXCEPTIONS
  throw future_error(make_error_code(__ev));
#    else
  (void)__ev;
  _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode");
#    endif
}

class _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count {
protected:
  exception_ptr __exception_;
  mutable mutex __mut_;
  mutable condition_variable __cv_;
  unsigned __state_;

  void __on_zero_shared() _NOEXCEPT override;
  void __sub_wait(unique_lock<mutex>& __lk);

public:
  enum { __constructed = 1, __future_attached = 2, ready = 4, deferred = 8 };

  _LIBCPP_HIDE_FROM_ABI __assoc_sub_state() : __state_(0) {}

  _LIBCPP_HIDE_FROM_ABI bool __has_value() const { return (__state_ & __constructed) || (__exception_ != nullptr); }

  _LIBCPP_HIDE_FROM_ABI void __attach_future() {
    lock_guard<mutex> __lk(__mut_);
    bool __has_future_attached = (__state_ & __future_attached) != 0;
    if (__has_future_attached)
      std::__throw_future_error(future_errc::future_already_retrieved);
    this->__add_shared();
    __state_ |= __future_attached;
  }

  _LIBCPP_HIDE_FROM_ABI void __set_deferred() { __state_ |= deferred; }

  void __make_ready();
  _LIBCPP_HIDE_FROM_ABI bool __is_ready() const { return (__state_ & ready) != 0; }

  void set_value();
  void set_value_at_thread_exit();

  void set_exception(exception_ptr __p);
  void set_exception_at_thread_exit(exception_ptr __p);

  void copy();

  void wait();
  template <class _Rep, class _Period>
  future_status _LIBCPP_HIDE_FROM_ABI wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
  template <class _Clock, class _Duration>
  _LIBCPP_HIDE_FROM_ABI future_status 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;
  }

  virtual void __execute();
};

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_HIDDEN __assoc_state : public __assoc_sub_state {
  typedef __assoc_sub_state base;
  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
  typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up;
  _LIBCPP_SUPPRESS_DEPRECATED_POP

protected:
  _Up __value_;

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;

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

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

  _LIBCPP_HIDE_FROM_ABI _Rp move();
  _LIBCPP_HIDE_FROM_ABI _Rp& copy();
};

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

template <class _Rp>
template <class _Arg>
void __assoc_state<_Rp>::set_value(_Arg&& __arg) {
  unique_lock<mutex> __lk(this->__mut_);
  if (this->__has_value())
    std::__throw_future_error(future_errc::promise_already_satisfied);
  ::new ((void*)std::addressof(__value_)) _Rp(std::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())
    std::__throw_future_error(future_errc::promise_already_satisfied);
  ::new ((void*)std::addressof(__value_)) _Rp(std::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)
    std::rethrow_exception(this->__exception_);
  return std::move(*reinterpret_cast<_Rp*>(std::addressof(__value_)));
}

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

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

protected:
  _Up __value_;

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;

public:
  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg);
  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg);

  _LIBCPP_HIDE_FROM_ABI _Rp& copy();
};

template <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())
    std::__throw_future_error(future_errc::promise_already_satisfied);
  __value_ = std::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())
    std::__throw_future_error(future_errc::promise_already_satisfied);
  __value_ = std::addressof(__arg);
  this->__state_ |= base::__constructed;
  __thread_local_data()->__make_ready_at_thread_exit(this);
}

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

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

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
};

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

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

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
};

template <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 __assoc_sub_state_alloc : public __assoc_sub_state {
  typedef __assoc_sub_state base;
  _Alloc __alloc_;

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __assoc_sub_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
};

template <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 __deferred_assoc_state : public __assoc_state<_Rp> {
  typedef __assoc_state<_Rp> base;

  _Fp __func_;

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

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
};

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

template <class _Rp, class _Fp>
void __deferred_assoc_state<_Rp, _Fp>::__execute() {
#    if _LIBCPP_HAS_EXCEPTIONS
  try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
    this->set_value(__func_());
#    if _LIBCPP_HAS_EXCEPTIONS
  } catch (...) {
    this->set_exception(current_exception());
  }
#    endif // _LIBCPP_HAS_EXCEPTIONS
}

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

  _Fp __func_;

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

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
};

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

template <class _Fp>
void __deferred_assoc_state<void, _Fp>::__execute() {
#    if _LIBCPP_HAS_EXCEPTIONS
  try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
    __func_();
    this->set_value();
#    if _LIBCPP_HAS_EXCEPTIONS
  } catch (...) {
    this->set_exception(current_exception());
  }
#    endif // _LIBCPP_HAS_EXCEPTIONS
}

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

  _Fp __func_;

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
};

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

template <class _Rp, class _Fp>
void __async_assoc_state<_Rp, _Fp>::__execute() {
#    if _LIBCPP_HAS_EXCEPTIONS
  try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
    this->set_value(__func_());
#    if _LIBCPP_HAS_EXCEPTIONS
  } catch (...) {
    this->set_exception(current_exception());
  }
#    endif // _LIBCPP_HAS_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 __async_assoc_state<void, _Fp> : public __assoc_sub_state {
  typedef __assoc_sub_state base;

  _Fp __func_;

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
};

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

template <class _Fp>
void __async_assoc_state<void, _Fp>::__execute() {
#    if _LIBCPP_HAS_EXCEPTIONS
  try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
    __func_();
    this->set_value();
#    if _LIBCPP_HAS_EXCEPTIONS
  } catch (...) {
    this->set_exception(current_exception());
  }
#    endif // _LIBCPP_HAS_EXCEPTIONS
}

template <class _Fp>
void __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT {
  this->wait();
  base::__on_zero_shared();
}

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

// future

template <class _Rp>
class future;

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

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

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

  explicit _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
  future(const future&)            = delete;
  future& operator=(const future&) = delete;
  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
    future(std::move(__rhs)).swap(*this);
    return *this;
  }

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

  // retrieving the value
  _LIBCPP_HIDE_FROM_ABI _Rp get();

  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }

  // functions to check state
  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }

  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
  template <class _Rep, class _Period>
  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
    return __state_->wait_for(__rel_time);
  }
  template <class _Clock, class _Duration>
  _LIBCPP_HIDE_FROM_ABI 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 {
  _LIBCPP_HIDE_FROM_ABI 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> __guard(__state_);
  __assoc_state<_Rp>* __s = __state_;
  __state_                = nullptr;
  return __s->move();
}

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

  explicit _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
  future(const future&)            = delete;
  future& operator=(const future&) = delete;
  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
    future(std::move(__rhs)).swap(*this);
    return *this;
  }

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

  // retrieving the value
  _LIBCPP_HIDE_FROM_ABI _Rp& get();

  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }

  // functions to check state
  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }

  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
  template <class _Rep, class _Period>
  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
    return __state_->wait_for(__rel_time);
  }
  template <class _Clock, class _Duration>
  _LIBCPP_HIDE_FROM_ABI 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> __guard(__state_);
  __assoc_state<_Rp&>* __s = __state_;
  __state_                 = nullptr;
  return __s->copy();
}

template <>
class _LIBCPP_EXPORTED_FROM_ABI 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_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
  future(const future&)            = delete;
  future& operator=(const future&) = delete;
  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
    future(std::move(__rhs)).swap(*this);
    return *this;
  }

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

  // retrieving the value
  void get();

  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }

  // functions to check state
  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }

  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
  template <class _Rep, class _Period>
  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
    return __state_->wait_for(__rel_time);
  }
  template <class _Clock, class _Duration>
  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
    return __state_->wait_until(__abs_time);
  }
};

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

// promise<R>

template <class _Callable>
class packaged_task;

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

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

  template <class>
  friend class packaged_task;

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

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

  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }

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

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

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

template <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*)std::addressof(*__hold.get())) _State(__a0);
  __state_ = std::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)
    std::__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)
    std::__throw_future_error(future_errc::no_state);
  __state_->set_value(__r);
}

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

template <class _Rp>
void promise<_Rp>::set_exception(exception_ptr __p) {
  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
  if (__state_ == nullptr)
    std::__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)
    std::__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)
    std::__throw_future_error(future_errc::no_state);
  __state_->set_value_at_thread_exit(std::move(__r));
}

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

// promise<R&>

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

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

  template <class>
  friend class packaged_task;

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

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

  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }

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

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

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

template <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*)std::addressof(*__hold.get())) _State(__a0);
  __state_ = std::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)
    std::__throw_future_error(future_errc::no_state);
  return future<_Rp&>(__state_);
}

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

template <class _Rp>
void promise<_Rp&>::set_exception(exception_ptr __p) {
  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
  if (__state_ == nullptr)
    std::__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)
    std::__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_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr");
  if (__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  __state_->set_exception_at_thread_exit(__p);
}

// promise<void>

template <>
class _LIBCPP_EXPORTED_FROM_ABI promise<void> {
  __assoc_sub_state* __state_;

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

  template <class>
  friend class packaged_task;

public:
  promise();
  template <class _Alloc>
  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a0) {
    typedef __assoc_sub_state_alloc<_Alloc> _State;
    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
    typedef __allocator_destructor<_A2> _D2;
    _A2 __a(__a0);
    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
    ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
    __state_ = std::addressof(*__hold.release());
  }

  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
  promise(const promise& __rhs) = delete;
  ~promise();

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

  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }

  // retrieving the result
  future<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 _Rp>
inline _LIBCPP_HIDE_FROM_ABI void swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT {
  __x.swap(__y);
}

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

// packaged_task

template <class _Fp>
class __packaged_task_base;

template <class _Rp, class... _ArgTypes>
class __packaged_task_base<_Rp(_ArgTypes...)> {
public:
  _LIBCPP_HIDE_FROM_ABI __packaged_task_base() {}
  __packaged_task_base(const __packaged_task_base&)            = delete;
  __packaged_task_base& operator=(const __packaged_task_base&) = delete;
  _LIBCPP_HIDE_FROM_ABI_VIRTUAL
  virtual ~__packaged_task_base() {}
  virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
  virtual void destroy()                                  = 0;
  virtual void destroy_deallocate()                       = 0;
  virtual _Rp operator()(_ArgTypes&&...)                  = 0;
};

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

template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __packaged_task_base<_Rp(_ArgTypes...)> {
  _LIBCPP_COMPRESSED_PAIR(_Fp, __func_, _Alloc, __alloc_);

public:
  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(const _Fp& __f) : __func_(__f) {}
  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(_Fp&& __f) : __func_(std::move(__f)) {}
  _LIBCPP_HIDE_FROM_ABI __packaged_task_func(const _Fp& __f, const _Alloc& __a) : __func_(__f), __alloc_(__a) {}
  _LIBCPP_HIDE_FROM_ABI __packaged_task_func(_Fp&& __f, const _Alloc& __a) : __func_(std::move(__f)), __alloc_(__a) {}
  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy();
  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate();
  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __args);
};

template <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(std::move(__func_), std::move(__alloc_));
}

template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
void __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() {
  __func_.~_Fp();
  __alloc_.~_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(__alloc_);
  __func_.~_Fp();
  __alloc_.~_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 std::__invoke(__func_, std::forward<_ArgTypes>(__arg)...);
}

template <class _Callable>
class __packaged_task_function;

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

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

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

public:
  typedef _Rp result_type;

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

  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
  _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;

  __packaged_task_function(const __packaged_task_function&)            = delete;
  __packaged_task_function& operator=(const __packaged_task_function&) = delete;

  _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function();

  _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT;

  _LIBCPP_HIDE_FROM_ABI _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 __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
  typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
  if (sizeof(_FF) <= sizeof(__buf_)) {
    ::new ((void*)&__buf_) _FF(std::forward<_Fp>(__f));
    __f_ = (__base*)&__buf_;
  } else {
    typedef allocator<_FF> _Ap;
    _Ap __a;
    typedef __allocator_destructor<_Ap> _Dp;
    unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
    ::new ((void*)__hold.get()) _FF(std::forward<_Fp>(__f), allocator<_FR>(__a));
    __f_ = __hold.release();
  }
}

template <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 __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
  typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
  if (sizeof(_FF) <= sizeof(__buf_)) {
    __f_ = (__base*)&__buf_;
    ::new ((void*)__f_) _FF(std::forward<_Fp>(__f));
  } else {
    typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
    _Ap __a(__a0);
    typedef __allocator_destructor<_Ap> _Dp;
    unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
    ::new ((void*)std::addressof(*__hold.get())) _FF(std::forward<_Fp>(__f), _Alloc(__a));
    __f_ = std::addressof(*__hold.release());
  }
}

template <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_) {
    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
    typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
    _LIBCPP_SUPPRESS_DEPRECATED_POP
    __base* __t = (__base*)&__tempbuf;
    __f_->__move_to(__t);
    __f_->destroy();
    __f_ = nullptr;
    __f.__f_->__move_to((__base*)&__buf_);
    __f.__f_->destroy();
    __f.__f_ = nullptr;
    __f_     = (__base*)&__buf_;
    __t->__move_to((__base*)&__f.__buf_);
    __t->destroy();
    __f.__f_ = (__base*)&__f.__buf_;
  } else if (__f_ == (__base*)&__buf_) {
    __f_->__move_to((__base*)&__f.__buf_);
    __f_->destroy();
    __f_     = __f.__f_;
    __f.__f_ = (__base*)&__f.__buf_;
  } else if (__f.__f_ == (__base*)&__f.__buf_) {
    __f.__f_->__move_to((__base*)&__buf_);
    __f.__f_->destroy();
    __f.__f_ = __f_;
    __f_     = (__base*)&__buf_;
  } else
    std::swap(__f_, __f.__f_);
}

template <class _Rp, class... _ArgTypes>
inline _Rp __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {
  return (*__f_)(std::forward<_ArgTypes>(__arg)...);
}

template <class _Rp, class... _ArgTypes>
class packaged_task<_Rp(_ArgTypes...)> {
public:
  using result_type _LIBCPP_DEPRECATED = _Rp; // extension

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

public:
  // construction and destruction
  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}

  template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}

#    if _LIBCPP_STD_VER <= 14
  template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
#    endif
  // ~packaged_task() = default;

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

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

  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }

  // result retrieval
  _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future() { return __p_.get_future(); }

  // execution
  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);

  _LIBCPP_HIDE_FROM_ABI void reset();
};

template <class _Rp, class... _ArgTypes>
void packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) {
  if (__p_.__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  if (__p_.__state_->__has_value())
    std::__throw_future_error(future_errc::promise_already_satisfied);
#    if _LIBCPP_HAS_EXCEPTIONS
  try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
    __p_.set_value(__f_(std::forward<_ArgTypes>(__args)...));
#    if _LIBCPP_HAS_EXCEPTIONS
  } catch (...) {
    __p_.set_exception(current_exception());
  }
#    endif // _LIBCPP_HAS_EXCEPTIONS
}

template <class _Rp, class... _ArgTypes>
void packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
  if (__p_.__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  if (__p_.__state_->__has_value())
    std::__throw_future_error(future_errc::promise_already_satisfied);
#    if _LIBCPP_HAS_EXCEPTIONS
  try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
    __p_.set_value_at_thread_exit(__f_(std::forward<_ArgTypes>(__args)...));
#    if _LIBCPP_HAS_EXCEPTIONS
  } catch (...) {
    __p_.set_exception_at_thread_exit(current_exception());
  }
#    endif // _LIBCPP_HAS_EXCEPTIONS
}

template <class _Rp, class... _ArgTypes>
void packaged_task<_Rp(_ArgTypes...)>::reset() {
  if (!valid())
    std::__throw_future_error(future_errc::no_state);
  __p_ = promise<_Rp>();
}

template <class... _ArgTypes>
class packaged_task<void(_ArgTypes...)> {
public:
  using result_type _LIBCPP_DEPRECATED = void; // extension

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

public:
  // construction and destruction
  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
  template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
#    if _LIBCPP_STD_VER <= 14
  template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
#    endif
  // ~packaged_task() = default;

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

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

  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }

  // result retrieval
  _LIBCPP_HIDE_FROM_ABI future<void> get_future() { return __p_.get_future(); }

  // execution
  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);

  _LIBCPP_HIDE_FROM_ABI void reset();
};

#    if _LIBCPP_STD_VER >= 17

template <class _Rp, class... _Args>
packaged_task(_Rp (*)(_Args...)) -> packaged_task<_Rp(_Args...)>;

template <class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type>
packaged_task(_Fp) -> packaged_task<_Stripped>;

#    endif

template <class... _ArgTypes>
void packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) {
  if (__p_.__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  if (__p_.__state_->__has_value())
    std::__throw_future_error(future_errc::promise_already_satisfied);
#    if _LIBCPP_HAS_EXCEPTIONS
  try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
    __f_(std::forward<_ArgTypes>(__args)...);
    __p_.set_value();
#    if _LIBCPP_HAS_EXCEPTIONS
  } catch (...) {
    __p_.set_exception(current_exception());
  }
#    endif // _LIBCPP_HAS_EXCEPTIONS
}

template <class... _ArgTypes>
void packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
  if (__p_.__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  if (__p_.__state_->__has_value())
    std::__throw_future_error(future_errc::promise_already_satisfied);
#    if _LIBCPP_HAS_EXCEPTIONS
  try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
    __f_(std::forward<_ArgTypes>(__args)...);
    __p_.set_value_at_thread_exit();
#    if _LIBCPP_HAS_EXCEPTIONS
  } catch (...) {
    __p_.set_exception_at_thread_exit(current_exception());
  }
#    endif // _LIBCPP_HAS_EXCEPTIONS
}

template <class... _ArgTypes>
void packaged_task<void(_ArgTypes...)>::reset() {
  if (!valid())
    std::__throw_future_error(future_errc::no_state);
  __p_ = promise<void>();
}

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

#    if _LIBCPP_STD_VER <= 14
template <class _Callable, class _Alloc>
struct uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {};
#    endif

template <class _Rp, class _Fp>
_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f) {
  unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
      new __deferred_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
  return future<_Rp>(__h.get());
}

template <class _Rp, class _Fp>
_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f) {
  unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
      new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
  std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
  return future<_Rp>(__h.get());
}

#    ifndef _LIBCPP_CXX03_LANG

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

public:
  using _Rp _LIBCPP_NODEBUG = __invoke_result_t<_Fp, _Args...>;

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

  _LIBCPP_HIDE_FROM_ABI __async_func(__async_func&& __f) : __f_(std::move(__f.__f_)) {}

  _LIBCPP_HIDE_FROM_ABI _Rp operator()() {
    typedef typename __make_tuple_indices<1 + sizeof...(_Args), 1>::type _Index;
    return __execute(_Index());
  }

private:
  template <size_t... _Indices>
  _LIBCPP_HIDE_FROM_ABI _Rp __execute(__tuple_indices<_Indices...>) {
    return std::__invoke(std::move(std::get<0>(__f_)), std::move(std::get<_Indices>(__f_))...);
  }
};

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

template <class _Fp, class... _Args>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI future<__invoke_result_t<__decay_t<_Fp>, __decay_t<_Args>...> >
async(launch __policy, _Fp&& __f, _Args&&... __args) {
  typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF;
  typedef typename _BF::_Rp _Rp;

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

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

template <class _Fp, class... _Args>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI future<__invoke_result_t<__decay_t<_Fp>, __decay_t<_Args>...> >
async(_Fp&& __f, _Args&&... __args) {
  return std::async(launch::any, std::forward<_Fp>(__f), std::forward<_Args>(__args)...);
}

#    endif // C++03

// shared_future

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

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

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

  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }

  // functions to check state
  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }

  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
  template <class _Rep, class _Period>
  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
    return __state_->wait_for(__rel_time);
  }
  template <class _Clock, class _Duration>
  _LIBCPP_HIDE_FROM_ABI 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 shared_future<_Rp&> {
  __assoc_state<_Rp&>* __state_;

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

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

  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }

  // functions to check state
  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }

  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
  template <class _Rep, class _Period>
  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
    return __state_->wait_for(__rel_time);
  }
  template <class _Clock, class _Duration>
  _LIBCPP_HIDE_FROM_ABI 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_EXPORTED_FROM_ABI shared_future<void> {
  __assoc_sub_state* __state_;

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

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

  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }

  // functions to check state
  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }

  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
  template <class _Rep, class _Period>
  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
    return __state_->wait_for(__rel_time);
  }
  template <class _Clock, class _Duration>
  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
    return __state_->wait_until(__abs_time);
  }
};

template <class _Rp>
inline _LIBCPP_HIDE_FROM_ABI 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>(std::move(*this));
}

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

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

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#  endif // _LIBCPP_HAS_THREADS

#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
#    include <chrono>
#  endif

#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#    include <atomic>
#    include <cstdlib>
#    include <exception>
#    include <iosfwd>
#    include <system_error>
#    include <thread>
#  endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif // _LIBCPP_FUTURE
