chromium/third_party/libc++/src/include/future

// -*- 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);
    ~packaged_task();

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

    // move support
    packaged_task(packaged_task&& other) noexcept;
    packaged_task& operator=(packaged_task&& other) noexcept;
    void swap(packaged_task& other) noexcept;

    bool valid() const noexcept;

    // result retrieval
    future<R> get_future();

    // execution
    void operator()(ArgTypes... );
    void make_ready_at_thread_exit(ArgTypes...);

    void reset();
};

template <class R>
  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;

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

}  // std

*/

#include <__config>

#if !defined(_LIBCPP_HAS_NO_THREADS)

#  include <__assert>
#  include <__chrono/duration.h>
#  include <__chrono/time_point.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_ptr.h>
#  include <__memory/unique_ptr.h>
#  include <__memory/uses_allocator.h>
#  include <__system_error/error_category.h>
#  include <__system_error/error_code.h>
#  include <__system_error/error_condition.h>
#  include <__type_traits/aligned_storage.h>
#  include <__type_traits/strip_signature.h>
#  include <__utility/auto_cast.h>
#  include <__utility/forward.h>
#  include <__utility/move.h>
#  include <mutex>
#  include <new>
#  include <stdexcept>
#  include <thread>
#  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){};
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG()

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){};
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG()

#  ifndef _LIBCPP_CXX03_LANG

__launch_underlying_type;

inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator&(launch __x, launch __y) {}

inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator|(launch __x, launch __y) {}

inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator^(launch __x, launch __y) {}

inline _LIBCPP_HIDE_FROM_ABI constexpr launch operator~(launch __x) {}

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

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

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

#  endif // !_LIBCPP_CXX03_LANG

// enum class future_status
_LIBCPP_DECLARE_STRONG_ENUM(future_status){};
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG()

_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;

inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT {}

inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT {}

_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev);

class _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error {};

// Declared above std::future_error
void __throw_future_error(future_errc __ev) {}

class _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count {};

template <class _Clock, class _Duration>
future_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {}

template <class _Rep, class _Period>
inline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {}

template <class _Rp>
class _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state {};

template <class _Rp>
void __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT {}

template <class _Rp>
template <class _Arg>
void __assoc_state<_Rp>::set_value(_Arg&& __arg) {}

template <class _Rp>
template <class _Arg>
void __assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) {}

template <class _Rp>
_Rp __assoc_state<_Rp>::move() {}

template <class _Rp>
__add_lvalue_reference_t<_Rp> __assoc_state<_Rp>::copy() {}

__assoc_state<_Rp &>;

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

template <class _Rp>
void __assoc_state<_Rp&>::set_value(_Rp& __arg) {}

template <class _Rp>
void __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) {}

template <class _Rp>
_Rp& __assoc_state<_Rp&>::copy() {}

template <class _Rp, class _Alloc>
class __assoc_state_alloc : public __assoc_state<_Rp> {};

template <class _Rp, class _Alloc>
void __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT {}

__assoc_state_alloc<_Rp &, _Alloc>;

template <class _Rp, class _Alloc>
void __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT {}

template <class _Alloc>
class __assoc_sub_state_alloc : public __assoc_sub_state {};

template <class _Alloc>
void __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT {}

template <class _Rp, class _Fp>
class __deferred_assoc_state : public __assoc_state<_Rp> {};

template <class _Rp, class _Fp>
inline __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) :{}

template <class _Rp, class _Fp>
void __deferred_assoc_state<_Rp, _Fp>::__execute() {}

__deferred_assoc_state<void, _Fp>;

template <class _Fp>
inline __deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) :{}

template <class _Fp>
void __deferred_assoc_state<void, _Fp>::__execute() {}

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

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

template <class _Rp, class _Fp>
void __async_assoc_state<_Rp, _Fp>::__execute() {}

template <class _Rp, class _Fp>
void __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT {}

__async_assoc_state<void, _Fp>;

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

template <class _Fp>
void __async_assoc_state<void, _Fp>::__execute() {}

template <class _Fp>
void __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT {}

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 {};

template <class _Rp>
future<_Rp>::future(__assoc_state<_Rp>* __state) :{}

struct __release_shared_count {};

template <class _Rp>
future<_Rp>::~future() {}

template <class _Rp>
_Rp future<_Rp>::get() {}

future<_Rp &>;

template <class _Rp>
future<_Rp&>::future(__assoc_state<_Rp&>* __state) :{}

template <class _Rp>
future<_Rp&>::~future() {}

template <class _Rp>
_Rp& future<_Rp&>::get() {}

template <>
class _LIBCPP_EXPORTED_FROM_ABI future<void> {};

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

// promise<R>

template <class _Callable>
class packaged_task;

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS promise {};

template <class _Rp>
promise<_Rp>::promise() :{}

template <class _Rp>
template <class _Alloc>
promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) {}

template <class _Rp>
promise<_Rp>::~promise() {}

template <class _Rp>
future<_Rp> promise<_Rp>::get_future() {}

template <class _Rp>
void promise<_Rp>::set_value(const _Rp& __r) {}

template <class _Rp>
void promise<_Rp>::set_value(_Rp&& __r) {}

template <class _Rp>
void promise<_Rp>::set_exception(exception_ptr __p) {}

template <class _Rp>
void promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) {}

template <class _Rp>
void promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) {}

template <class _Rp>
void promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) {}

// promise<R&>

promise<_Rp &>;

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

template <class _Rp>
template <class _Alloc>
promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) {}

template <class _Rp>
promise<_Rp&>::~promise() {}

template <class _Rp>
future<_Rp&> promise<_Rp&>::get_future() {}

template <class _Rp>
void promise<_Rp&>::set_value(_Rp& __r) {}

template <class _Rp>
void promise<_Rp&>::set_exception(exception_ptr __p) {}

template <class _Rp>
void promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) {}

template <class _Rp>
void promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) {}

// promise<void>

template <>
class _LIBCPP_EXPORTED_FROM_ABI promise<void> {};

template <class _Alloc>
promise<void>::promise(allocator_arg_t, const _Alloc& __a0) {}

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

uses_allocator<promise<_Rp>, _Alloc>;

// packaged_task

template <class _Fp>
class __packaged_task_base;

__packaged_task_base<_Rp (_ArgTypes...)>;

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

__packaged_task_func<_Fp, _Alloc, _Rp (_ArgTypes...)>;

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 {}

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

template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
void __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() {}

template <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
_Rp __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) {}

template <class _Callable>
class __packaged_task_function;

__packaged_task_function<_Rp (_ArgTypes...)>;

template <class _Rp, class... _ArgTypes>
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT {}

template <class _Rp, class... _ArgTypes>
template <class _Fp>
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) : __f_(nullptr) {}

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) {}

template <class _Rp, class... _ArgTypes>
__packaged_task_function<_Rp(_ArgTypes...)>&
__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT {}

template <class _Rp, class... _ArgTypes>
__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() {}

template <class _Rp, class... _ArgTypes>
_LIBCPP_NO_CFI void __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT {}

template <class _Rp, class... _ArgTypes>
inline _Rp __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {}

packaged_task<_Rp (_ArgTypes...)>;

template <class _Rp, class... _ArgTypes>
void packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) {}

template <class _Rp, class... _ArgTypes>
void packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {}

template <class _Rp, class... _ArgTypes>
void packaged_task<_Rp(_ArgTypes...)>::reset() {}

packaged_task<void (_ArgTypes...)>;

#  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) {}

template <class... _ArgTypes>
void packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {}

template <class... _ArgTypes>
void packaged_task<void(_ArgTypes...)>::reset() {}

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

uses_allocator<packaged_task<_Callable>, _Alloc>;

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) {}

#  ifndef _LIBCPP_CXX03_LANG

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

inline _LIBCPP_HIDE_FROM_ABI bool __does_policy_contain(launch __policy, launch __value) {}

template <class _Fp, class... _Args>
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
async(launch __policy, _Fp&& __f, _Args&&... __args) {}

template <class _Fp, class... _Args>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type>
async(_Fp&& __f, _Args&&... __args) {}

#  endif // C++03

// shared_future

template <class _Rp>
class _LIBCPP_TEMPLATE_VIS shared_future {};

template <class _Rp>
shared_future<_Rp>::~shared_future() {}

template <class _Rp>
shared_future<_Rp>& shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT {}

shared_future<_Rp &>;

template <class _Rp>
shared_future<_Rp&>::~shared_future() {}

template <class _Rp>
shared_future<_Rp&>& shared_future<_Rp&>::operator=(const shared_future& __rhs) {}

template <>
class _LIBCPP_EXPORTED_FROM_ABI shared_future<void> {};

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

template <class _Rp>
inline shared_future<_Rp> future<_Rp>::share() _NOEXCEPT {}

template <class _Rp>
inline shared_future<_Rp&> future<_Rp&>::share() _NOEXCEPT {}

inline shared_future<void> future<void>::share() _NOEXCEPT {}

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_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>
#endif

#endif // _LIBCPP_FUTURE