-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcoroutines.cpp
76 lines (65 loc) · 2.02 KB
/
coroutines.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include<iostream> // std::cout
#include<string> // std::string
#include<coroutine> // std::suspend always, std::coroutine_handle
#include<utility> // std::exchange
struct promise_type;
struct Chat
{
using handle = std::coroutine_handle<promise_type>;
handle coroutine_handle{};
explicit Chat(promise_type* p) : coroutine_handle(handle::from_promise(*p)) {}
Chat(Chat&& rhs) : coroutine_handle{std::exchange(rhs.coroutine_handle, nullptr)} {}
~Chat()
{
if(coroutine_handle) {coroutine_handle.destroy();}
}
std::string listen()
{
if(not coroutine_handle.done()) {coroutine_handle.resume();}
return std::move(coroutine_handle.promise().message_out);
}
void answer(std::string msg)
{
coroutine_handle.promise().message_in = msg;
if(not coroutine_handle.done()) {coroutine_handle.resume();}
}
};
struct promise_type
{
std::string message_out{};
std::string message_in{};
void unhandled_exception() noexcept {}
Chat get_return_object() {return Chat(this);}
std::suspend_always initial_suspend() noexcept {return {};}
std::suspend_always yield_value(std::string msg) noexcept
{
message_out = std::move(msg);
return {};
}
auto await_transform(std::string) noexcept
{
struct awaiter
{
promise_type& pt;
constexpr bool await_ready() const noexcept {return true;}
std::string await_resume() const noexcept {return std::move(pt.message_in);}
void await_suspend(std::coroutine_handle<>) const noexcept {}
};
return awaiter(*this);
}
void return_value(std::string msg) noexcept {message_out = std::move(msg);}
std::suspend_always final_suspend() noexcept {return {};}
};
Chat Fun()
{
co_yield std::string("Hello!\n");
std::cout << co_await std::string{};
co_return "Here!\n";
}
void use()
{
Chat chat = Fun();
std::cout << chat.listen();
chat.answer("Where are you?\n");
std::cout << chat.listen();
}