# 标准库头文件 <coroutine>

< cpp‎ | header

此头文件是协程支持库的一部分。

### 包含
<compare> (C++20) | 三路比较运算符支持
### 类
coroutine_traits (C++20) | 用于发现协程承诺类型的特征类型 (类模板)
coroutine_handle (C++20) | 用于指代暂停或执行的协程 (类模板)
std::hash<std::coroutine_handle> (C++20) | std::coroutine_handle 的散列支持 (类模板特化)
##### 无操作协程
noop_coroutine_promise (C++20) | 用于无可观察作用的协程 (类)
noop_coroutine_handle (C++20) | std::coroutine_handle<std::noop_coroutine_promise> ，有意用于指代无操作协程 (typedef)
##### 平凡可等待体
suspend_never (C++20) | 指示 await 表达式应该决不暂停 (类)
suspend_always (C++20) | 指示 await 表达式应该始终暂停 (类)
### 函数
operator==operator<=> (C++20) | 比较二个 `coroutine_handle` 对象 (函数)
##### 无操作协程
noop_coroutine (C++20) | 创建在等待或销毁时无可观察作用的协程柄 (函数)

### 概要

    #include <compare>

    namespace std {
      // 协程表征
      template<class R, class... ArgTypes>
        struct coroutine_traits;

      // 协程柄
      template<class Promise = void>
        struct coroutine_handle;

      // 比较运算符
      constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept;
      constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept;

      // 散列支持
      template<class T> struct hash;
      template<class P> struct hash<coroutine_handle<P>>;

      // 无操作协程
      struct noop_coroutine_promise;

      template<> struct coroutine_handle<noop_coroutine_promise>;
      using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;

      noop_coroutine_handle noop_coroutine() noexcept;

      // 平凡可等待体
      struct suspend_never;
      struct suspend_always;
    }

#### 类模板 std::coroutine_handle

    namespace std {
      template<>
      struct coroutine_handle<void>
      {
        // 构造/重置
        constexpr coroutine_handle() noexcept;
        constexpr coroutine_handle(nullptr_t) noexcept;
        coroutine_handle& operator=(nullptr_t) noexcept;

        // 导入/导出
        constexpr void* address() const noexcept;
        static constexpr coroutine_handle from_address(void* addr);

        // 观察器
        constexpr explicit operator bool() const noexcept;
        bool done() const;

        // 恢复
        void operator()() const;
        void resume() const;
        void destroy() const;

      private:
        void* ptr;  // 仅用于阐释
      };

      template<class Promise>
      struct coroutine_handle
      {
        // 构造/重置
        constexpr coroutine_handle() noexcept;
        constexpr coroutine_handle(nullptr_t) noexcept;
        static coroutine_handle from_promise(Promise&);
        coroutine_handle& operator=(nullptr_t) noexcept;

        // 导出/导入
        constexpr void* address() const noexcept;
        static constexpr coroutine_handle from_address(void* addr);

        // 转换
        constexpr operator coroutine_handle<>() const noexcept;

        // 观察器
        constexpr explicit operator bool() const noexcept;
        bool done() const;

        // 恢复
        void operator()() const;
        void resume() const;
        void destroy() const;

        // 承诺访问
        Promise& promise() const;

      private:
        void* ptr;  // 仅用于阐释
      };
    }

#### 类 std::noop_coroutine_promise

    namespace std {
      struct noop_coroutine_promise {};
    }

#### 类 std::coroutine_handle<std::noop_coroutine_promise>

    namespace std {
      template<>
      struct coroutine_handle<noop_coroutine_promise>
      {
        // 转换
        constexpr operator coroutine_handle<>() const noexcept;

        // 观察器
        constexpr explicit operator bool() const noexcept;
        constexpr bool done() const noexcept;

        // 恢复
        constexpr void operator()() const noexcept;
        constexpr void resume() const noexcept;
        constexpr void destroy() const noexcept;

        // 承诺访问
        noop_coroutine_promise& promise() const noexcept;

        // 地址
        constexpr void* address() const noexcept;
      private:
        coroutine_handle(/* 未指明 */);
        void* ptr;  // 仅用于阐释
      };
    }

#### 类 std::suspend_never

    namespace std {
      struct suspend_never {
        constexpr bool await_ready() const noexcept { return true; }
        constexpr void await_suspend(coroutine_handle<>) const noexcept {}
        constexpr void await_resume() const noexcept {}
      };
    }

#### 类 std::suspend_always

    namespace std {
      struct suspend_always {
        constexpr bool await_ready() const noexcept { return false; }
        constexpr void await_suspend(coroutine_handle<>) const noexcept {}
        constexpr void await_resume() const noexcept {}
      };
    }