Skip to content

Instantly share code, notes, and snippets.

@fakedrake
Created March 29, 2021 03:00
Show Gist options
  • Save fakedrake/cbf359a4623c0b99ccf2cd123fe369ac to your computer and use it in GitHub Desktop.
Save fakedrake/cbf359a4623c0b99ccf2cd123fe369ac to your computer and use it in GitHub Desktop.
#include <experimental/coroutine>
#include <stdio.h>
#include <future>
// we get suspend_never and return_value
// template<typename T,typename... Args>
// struct std::experimental::coroutine_traits<std::future<T>,Args...> {
// struct promise_type {
// suspend_never initial_suspend() { return {}; }
// suspend_never final_suspend() { return {}; }
// void return_value(T val) { printf("return_value(%d)", val); }
// };
// };
using namespace std::experimental;
struct sentinel_t {};
struct gen_t {
struct promise_type;
using hndl_t=coroutine_handle<promise_type>;
gen_t(hndl_t h) : coro_handler(h) {}
~gen_t() {if (coro_handler) coro_handler.destroy();}
struct awaitable {
awaitable(int val) : value(val) {}
~awaitable() {}
bool await_ready() {return false;}
void await_resume() {
printf("await_resume()\n");
}
void await_suspend(hndl_t hndl) {
printf("await_suspend(coroutine_handle{%s})\n", hndl.promise().show().c_str());
}
int value;
};
struct promise_type {
int promised_val;
std::string show() const {
return "promise_type{" + std::to_string(promised_val) + "}";
}
suspend_never initial_suspend() {return {};}
suspend_never final_suspend() {return {};}
void return_void() { done = true; printf("return_void()\n"); }
awaitable yield_value(int val) {
printf("yield_value(%d)\n", val);
promised_val = val;
return {val};
}
gen_t get_return_object() {return {hndl_t::from_promise(*this)};}
void unhandled_exception() { abort(); }
};
struct iter_t {
iter_t(hndl_t coro_handler_) : coro_handler{coro_handler_} {
}
int& operator*() const {
printf("*it -> %s\n", coro_handler.promise().show().c_str());
if (!coro_handler) abort();
return coro_handler.promise().promised_val;
}
void operator ++() {
printf("it++\n");
coro_handler.resume();
}
bool operator !=(sentinel_t) const {
printf("it != end ?\n");
return coro_handler && !coro_handler.done();
}
private:
hndl_t coro_handler;
};
iter_t begin() {
printf("gen.begin()\n");
return iter_t{coro_handler};
}
sentinel_t end() {
printf("gen.end()\n");
return {};
}
private:
hndl_t coro_handler;
};
gen_t f( ) {
printf("f()\n");
// co_yield expr;
// ==
// co_await promise.yield_value(expr)
// ==
// awaitable && tmp = EXPR;
// if (!tmp.await_ready()) {
// tmp.await_suspend(coro_handle); // do other stuff
// }
// return tmp.await_resume();
co_yield 1;
co_yield 2;
co_yield 3;
}
int main() {
for (int i : f()) {
printf("Iter: i = %d\n", i);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment