Last active
September 16, 2024 22:35
-
-
Save dietmarkuehl/431219bf6758444ff1e1abb45afee886 to your computer and use it in GitHub Desktop.
coroutine example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <coroutine> | |
#include <iostream> | |
#include <optional> | |
#include <string> | |
#include <unordered_map> | |
struct task | |
{ | |
struct promise_type { | |
std::unique_ptr<char const, decltype([](auto msg){ std::cout << msg; })> | |
on_exit{"releasing promise_type\n"}; | |
std::suspend_always initial_suspend() const { std::cout << "initial_suspend()\n"; return {}; } | |
std::suspend_always final_suspend() const noexcept { return {}; } | |
//void return_void() { std::cout << "return_void\n"; } | |
void unhandled_exception() {} | |
task get_return_object() { | |
std::cout << "get_return_object()\n"; | |
return {promise_ptr(this)}; | |
} | |
std::optional<std::string> result; | |
void return_value(std::string const& value) { | |
std::cout << "return_value("<< value << ")\n"; | |
result = value; | |
} | |
}; | |
using promise_ptr = std::unique_ptr<promise_type, decltype([](auto* p){ | |
std::coroutine_handle<promise_type>::from_promise(*p).destroy(); | |
})>; | |
promise_ptr promise; | |
void run() { | |
std::coroutine_handle<promise_type>::from_promise(*promise.get()).resume(); | |
} | |
std::string get_result() const { return promise->result.value_or("<not set>"); } | |
}; | |
struct awaiter; | |
using outstanding_type = std::unordered_map<std::string, awaiter*>; | |
struct awaiter | |
{ | |
std::string name; | |
outstanding_type* outstanding; | |
std::coroutine_handle<> h{}; | |
int result{}; | |
void complete(int r) { | |
result = r; | |
h.resume(); | |
} | |
bool await_ready() const { return false; } | |
void await_suspend(std::coroutine_handle<> h) { | |
this->h = h; | |
(*outstanding)[name] = this; | |
} | |
int await_resume() { | |
return result; | |
} | |
}; | |
auto f(auto* outstanding, std::string name) -> task | |
{ | |
//std::cout << "inside coroutine\n"; | |
//co_await std::suspend_always{}; | |
//std::cout << "after second suspend\n"; | |
auto result = co_await awaiter{name, outstanding}; | |
std::cout << "awaiter-result=" << result << "\n";; | |
co_return std::string("hello"); | |
} | |
int main() | |
{ | |
outstanding_type outstanding; | |
std::cout << "before f\n"; | |
task t = f(&outstanding, "first"); | |
task t2 = f(&outstanding, "second"); | |
std::cout << "after f\n"; | |
t.run(); | |
t2.run(); | |
std::cout << "after 1st run()\n"; | |
outstanding["second"]->complete(42); | |
outstanding["first"]->complete(17); | |
std::cout << "coro return=" << t.get_result() << "\n"; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CXXFLAGS = -W -Wall -std=c++20 -fsanitize=address | |
default: coro | |
./coro |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment