Skip to content

Instantly share code, notes, and snippets.

@HungMingWu
Created April 27, 2018 07:49
Show Gist options
  • Select an option

  • Save HungMingWu/7da330e125fe277b7b69f97b5a5e9864 to your computer and use it in GitHub Desktop.

Select an option

Save HungMingWu/7da330e125fe277b7b69f97b5a5e9864 to your computer and use it in GitHub Desktop.
#include <type_traits>
#include <iostream>
#include <experimental/coroutine>
struct generator {
struct promise_type {
int current_value;
promise_type() {
std::cout << "Promise created" << std::endl;
}
~promise_type() {
std::cout << "Promise died" << std::endl;
}
auto initial_suspend() {
std::cout << "Started the coroutine, let's pause!" << std::endl;
return std::experimental::suspend_always{};
}
auto final_suspend() {
std::cout << "Finished the coroutine" << std::endl;
return std::experimental::suspend_always{};
}
auto get_return_object() {
std::cout << "Send back a generator" << std::endl;
return generator{ handle_type::from_promise(*this) };
}
void unhandled_exception() {
std::cout << "Exception...." << std::endl;
std::exit(1);
}
auto return_void() {
std::cout << "return_void" << std::endl;
return std::experimental::suspend_never{};
}
auto yield_value(int value) {
std::cout << "Yielded " << value << std::endl;
current_value = value;
return std::experimental::suspend_always{};
}
};
using handle_type =
std::experimental::coroutine_handle<promise_type>;
int current_value() {
return coro.promise().current_value;
}
class iterator {
generator &owner;
bool done;
void advance() {
std::cout << "Moving to next" << std::endl;;
owner.coro.resume();
std::cout << "Are we done? ";
auto still_going = not owner.coro.done();
std::cout << (still_going ? "There is another" : "We're done") << std::endl;
done = not still_going;
}
public:
bool operator != (const iterator &r) const {
return done != r.done;
}
iterator(generator &o, bool d)
: owner(o), done(d) {
if (not done) advance();
}
iterator &operator ++ () {
advance();
return *this;
}
int operator * () const {
return owner.coro.promise().current_value;
}
};
iterator begin() {
return iterator{ *this, false };
}
iterator end() {
return iterator{ *this, true };
}
private:
generator(handle_type h)
: coro(h) {
std::cout << "generator" << std::endl;
}
handle_type coro;
};
generator count() {
std::cout << "Going to yield 1" << std::endl;
co_yield 1;
std::cout << "Going to yield 2" << std::endl;
co_yield 2;
std::cout << "Going to yield 3" << std::endl;
co_yield 3;
std::cout << "count() is done" << std::endl;
}
int main() {
for (auto v : count())
std::cout << ">> " << v << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment