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()检查协程是否在最终挂起点。

浙公网安备 33010602011771号