Created
March 29, 2021 03:00
-
-
Save fakedrake/cbf359a4623c0b99ccf2cd123fe369ac to your computer and use it in GitHub Desktop.
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 <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