// -*- 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 _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_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)
      __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_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_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*>(&__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())
    __throw_future_error(future_errc::promise_already_satisfied);
  ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
  this->__state_ |= base::__constructed | base::ready;
  __cv_.notify_all();
}

template <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(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*>(&__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*>(&__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())
    __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())
    __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 _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_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 _LIBCPP_TEMPLATE_VIS 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 _LIBCPP_TEMPLATE_VIS 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 _LIBCPP_TEMPLATE_VIS 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)
    __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(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)
    __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(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)
    __throw_future_error(future_errc::no_state);
  __state_->set_exception_at_thread_exit(__p);
}

// promise<R&>

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

// promise<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 _Allocator>
  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS promise(allocator_arg_t, const _Allocator& __a);
  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
  promise(const promise& __rhs) = delete;
  ~promise();

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

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

  // retrieving the result
  future<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*)std::addressof(*__hold.get())) _State(__a0);
  __state_ = std::addressof(*__hold.release());
}

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 _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 __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 _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 _LIBCPP_TEMPLATE_VIS 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_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<result_type> 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)
    __throw_future_error(future_errc::no_state);
  if (__p_.__state_->__has_value())
    __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)
    __throw_future_error(future_errc::no_state);
  if (__p_.__state_->__has_value())
    __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())
    __throw_future_error(future_errc::no_state);
  __p_ = promise<result_type>();
}

template <class... _ArgTypes>
class _LIBCPP_TEMPLATE_VIS 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_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<result_type> 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)
    __throw_future_error(future_errc::no_state);
  if (__p_.__state_->__has_value())
    __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)
    __throw_future_error(future_errc::no_state);
  if (__p_.__state_->__has_value())
    __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())
    __throw_future_error(future_errc::no_state);
  __p_ = promise<result_type>();
}

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 _LIBCPP_TEMPLATE_VIS 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:
  typedef typename __invoke_of<_Fp, _Args...>::type _Rp;

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

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

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

private:
  template <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<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
async(launch __policy, _Fp&& __f, _Args&&... __args) {
  typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF;
  typedef typename _BF::_Rp _Rp;

#      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<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
async(_Fp&& __f, _Args&&... __args) {
  return std::async(launch::any, std::forward<_Fp>(__f), std::forward<_Args>(__args)...);
}

#    endif // C++03

// shared_future

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

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

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

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

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

  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
  template <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 _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> {
  __assoc_state<_Rp&>* __state_;

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

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

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

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

  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
  template <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
