Skip to content

Instantly share code, notes, and snippets.

@Qix-
Created August 30, 2020 08:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Qix-/caa277fbf1a4e6ca55a27f2242df3b9a to your computer and use it in GitHub Desktop.
Save Qix-/caa277fbf1a4e6ca55a27f2242df3b9a to your computer and use it in GitHub Desktop.
Actually working minimal test of coroutines in C++
/*
I couldn't find a good example of a simplistic, *working*
program using coroutines without a bunch of dependencies
or bloat. Further, most of the code examples didn't work
or missed some detail.
As of this writing, this is a working example in Clang 12.
Public domain.
Written with the help of https://blog.panicsoftware.com/your-first-coroutine/.
*/
#include <iostream>
#include <cassert>
#include <experimental/coroutine>
class resumable {
public:
struct promise_type;
using coro_handle = std::experimental::coroutine_handle<promise_type>;
resumable(coro_handle &handle) : co_handle(handle) { assert(handle); }
resumable(resumable &) = delete;
resumable(resumable &&) = delete;
~resumable() {
co_handle.destroy();
}
bool resume() {
if (!co_handle.done()) {
co_handle.resume();
}
return !co_handle.done();
}
private:
coro_handle co_handle;
};
struct resumable::promise_type {
using coro_handle = std::experimental::coroutine_handle<promise_type>;
auto get_return_object() {
return coro_handle::from_promise(*this);
}
auto initial_suspend() { return std::experimental::suspend_always(); }
auto final_suspend() noexcept { return std::experimental::suspend_always(); }
void return_void() {}
void unhandled_exception() {
std::terminate();
}
};
resumable foo() {
std::cout << "First" << std::endl;
co_await std::experimental::suspend_always();
std::cout << "Second" << std::endl;
}
int main() {
auto p = foo();
while (p.resume());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment