Skip to content

Instantly share code, notes, and snippets.

@nikhedonia
Created October 29, 2018 13:35
Show Gist options
  • Save nikhedonia/b17d63c64217757d40296f42c833ce85 to your computer and use it in GitHub Desktop.
Save nikhedonia/b17d63c64217757d40296f42c833ce85 to your computer and use it in GitHub Desktop.
#include <experimental/coroutine>
#include <type_traits>
#include <iostream>
#include <memory>
using namespace std::experimental;
template<class T>
struct AwaitValue {
T x;
bool await_ready() { return false; }
void await_suspend(coroutine_handle<>) {}
T await_resume() {
return x;
}
};
template<class In, class Out>
struct DuplexGenerator {
struct promise_type {
void unhandled_exception(){}
auto get_return_object() {
return DuplexGenerator{
coroutine_handle<promise_type>::from_promise(*this)
};
}
auto initial_suspend() {
return suspend_always{};
}
auto final_suspend() {
return suspend_always{};
}
In input;
Out output;
bool done;
auto return_void(){}
auto yield_value(Out const& x) {
output = x;
return AwaitValue<int>{input};
}
};
coroutine_handle<promise_type> h;
DuplexGenerator(coroutine_handle<promise_type> h):h{h} {}
auto operator()(In const& x) {
h.promise().input = x;
h.resume();
return h.promise().output;
}
};
DuplexGenerator<int, int> sum(int a) {
while(1) {
a = a + (co_yield a);
}
}
int main() {
auto f = sum(0);
auto y = f(7);
std::cout << y;
auto z = f(2);
std::cout << y+z;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment