#include "base.hpp" #include #include #include template struct cor_range { struct promise_type { T _value; cor_range get_return_object() { return cor_range(std::experimental::coroutine_handle::from_promise(*this)); } auto initial_suspend() { return suspend_always(); } auto final_suspend() { return suspend_always(); } void return_value(T value) { _value = value; } auto yield_value(T value) { _value = value; return suspend_always(); } void unhandled_exception() {} }; std::experimental::coroutine_handle _coroutine = nullptr; explicit cor_range(std::experimental::coroutine_handle coroutine) : _coroutine(coroutine) {} ~cor_range() { if(_coroutine) { _coroutine.destroy(); } } cor_range() = default; cor_range(cor_range const &) = delete; cor_range& operator=(cor_range const &) = delete; cor_range(cor_range&& other) { std::swap(_coroutine, other._coroutine); } cor_range& operator=(cor_range&& other) { if(&other != this) { _coroutine = other._coroutine; other._coroutine = nullptr; } return *this; } T next() { _coroutine.resume(); return _coroutine.promise()._value; } struct iterator : std::iterator { std::experimental::coroutine_handle _coroutine = nullptr; iterator() = default; explicit iterator(std::experimental::coroutine_handle coroutine) : _coroutine(coroutine) {} iterator& operator++() { _coroutine.resume(); return *this; } T const & operator*() const { return _coroutine.promise()._value; } }; iterator begin() { if(_coroutine) { _coroutine.resume(); if(_coroutine.done()) { return end(); } } return iterator{ _coroutine }; } iterator end() { return iterator{}; } }; cor_range fib() { int fn; fn = 0; int fn1 = fn; co_yield fn; fn = 1; int fn2 = fn1; fn1 = fn; co_yield fn; for(;;) { fn = fn1 + fn2; fn2 = fn1; fn1 = fn; co_yield fn; } } int main() { { auto f1 = fib(); auto f2 = fib(); for(int i = 0; i < 10; i++) { std::cout << f1.next() << " " << f2.next() << std::endl; } } { auto f1 = fib(); std::vector fibs; std::copy_n(f1.begin(), 10, std::back_inserter(fibs)); for(auto i : fibs) { std::cout << i << std::endl; } } }