Created
April 27, 2018 07:49
-
-
Save HungMingWu/7da330e125fe277b7b69f97b5a5e9864 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 <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