C++协程代码

promise_type:

内置型:

 1 template<typename = void> struct Promise;
 2 
 3 template<> struct Promise<void> {
 4     Promise() = default;
 5     template<typename Self> Promise(Self&& obj) {  }
 6     std::coroutine_handle<Promise> get_return_object() { return std::coroutine_handle<Promise>::from_promise(*this); }
 7     std::suspend_never initial_suspend() { return {}; }
 8     std::suspend_always yield_value(auto&& i) { return {}; }
 9     void return_void() {}
10     std::suspend_always final_suspend() noexcept { return {}; }
11     void unhandled_exception() {}
12     template <typename T> decltype(auto) await_transform(T&& p) { return std::forward<T>(p); }
13 };
14 template<typename T> struct Promise {
15 
16     Promise() = default;
17     template<typename Self> Promise(Self&& obj) {  }
18     std::coroutine_handle<Promise> get_return_object() { return std::coroutine_handle<Promise>::from_promise(*this); }
19     std::suspend_never initial_suspend() { return {}; }
20     std::suspend_always yield_value(auto&& i) { return {}; }
21     void return_value(auto val) { this->r_v = std::move(val); }
22     std::suspend_always final_suspend()noexcept { return {}; }
23     void unhandled_exception() {}
24     template <typename Ty> decltype(auto) await_transform(Ty&& p) { return std::forward<Ty>(p); }
25     T r_v{};
26 };

外置型:

 1 template <class _Ty, class... _ArgTypes>
 2 struct std::coroutine_traits<std::future<_Ty>, _ArgTypes...> {
 3     struct promise_type {
 4         std::promise<_Ty> _MyPromise;
 5         std::future<_Ty> get_return_object() { return _MyPromise.get_future(); }
 6         std::suspend_never initial_suspend() const noexcept { return {}; }
 7         std::suspend_never final_suspend() const noexcept { return {}; }
 8         template <class _Ut> void return_value(_Ut&& _Value) { _MyPromise.set_value(std::forward<_Ut>(_Value)); }
 9         void unhandled_exception() { _MyPromise.set_exception(std::current_exception()); }
10     };
11 };
12 
13 template <class... _ArgTypes>
14 struct std::coroutine_traits<std::future<void>, _ArgTypes...> {
15     struct promise_type {
16         std::promise<void> _MyPromise;
17         std::future<void> get_return_object() { return _MyPromise.get_future(); }
18         std::suspend_never initial_suspend() const noexcept { return {}; }
19         std::suspend_never final_suspend() const noexcept { return {}; }
20         void return_void() { _MyPromise.set_value(); }
21         void unhandled_exception() { _MyPromise.set_exception(std::current_exception()); }
22     };
23 };

等待体的设计:

 1 template <class _Ty> struct future_awaiter {
 2     std::future<_Ty>& _Fut;
 3     bool await_ready() const { return (_Fut.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready); }
 4     void await_suspend(std::coroutine_handle<> _ResumeCb) {
 5         std::thread _WaitingThread([&_Fut = _Fut, _ResumeCb]() mutable {
 6             _Fut.wait();
 7             _ResumeCb.resume();
 8             });
 9         _WaitingThread.detach();
10     }
11     decltype(auto) await_resume() { return _Fut.get(); }
12 };
 1 template<typename T> struct Task_Awaiter {
 2     bool await_ready() {
 3         if (task.coro == nullptr) {
 4             return true;
 5         }
 6         return task.coro.done();
 7     }
 8 
 9     bool await_suspend(auto&& h) {
10         std::thread([h, this]() {
11             while (!this->task.coro.done())
12                 std::this_thread::yield();
13             h.resume();
14             }).detach();
15         return true;
16     }
17     decltype(auto) await_resume() {
18         if constexpr (!std::is_same_v<T, void>) {
19             return task.coro.promise().r_v;
20         }
21     }
22     Task<T>& task;
23 };

关于co_await表达式解析有两种方式,一种是重载operator co_await

template<typename T> inline Task_Awaiter<T> operator co_await(Task<T>&& v)
{
    return { v };
}
template<typename T> inline Task_Awaiter<T> operator co_await(Task<T>& v)
{
    return { v };
}
template <class _Ty>auto operator co_await(std::future<_Ty>&& _Fut) { return future_awaiter<_Ty>{_Fut}; }
template <class _Ty> auto operator co_await(std::future<_Ty>& _Fut) { return future_awaiter<_Ty>{_Fut}; }

另一种是实现await_transform

例如内置promise_type中的await_transform

template<typename T> struct Promise {

    Promise() = default;
    template<typename Self> Promise(Self&& obj) {  }
    std::coroutine_handle<Promise> get_return_object() { return std::coroutine_handle<Promise>::from_promise(*this); }
    std::suspend_never initial_suspend() { return {}; }
    std::suspend_always yield_value(auto&& i) { return {}; }
    void return_value(auto val) { this->r_v = std::move(val); }
    std::suspend_always final_suspend()noexcept { return {}; }
    void unhandled_exception() {}

        //该函数用于定于co_await的语义
    template <typename Ty> decltype(auto) await_transform(Ty&& p) { return std::forward<Ty>(p); }


    T r_v{};
};

resume()负责恢复协程,done()检查协程是否在最终挂起点。

posted @ 2025-05-02 08:58  大笨瓜  阅读(10)  评论(1)    收藏  举报