Skip to content

Instantly share code, notes, and snippets.

@dietmarkuehl
Last active September 16, 2024 22:35
Show Gist options
  • Save dietmarkuehl/431219bf6758444ff1e1abb45afee886 to your computer and use it in GitHub Desktop.
Save dietmarkuehl/431219bf6758444ff1e1abb45afee886 to your computer and use it in GitHub Desktop.
coroutine example
#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";
}
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