#include <iostream>
#include <experimental/coroutine>

struct counter_cor {
	struct promise_type {
		counter_cor get_return_object() {
			return counter_cor(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
		}

		auto initial_suspend() { return std::experimental::suspend_never(); }
		auto final_suspend()   { return std::experimental::suspend_never(); }

		void return_void() {}

		void unhandled_exception() {}
	};

	std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;

	explicit counter_cor(std::experimental::coroutine_handle<promise_type> coroutine)
		: _coroutine(coroutine)
	{}

	~counter_cor() {
		if(_coroutine) { _coroutine.destroy(); }
	}

	counter_cor() = default;
	counter_cor(counter_cor const &) = delete;
	counter_cor& operator=(counter_cor const &) = delete;

	counter_cor(counter_cor&& other) {
		std::swap(_coroutine, other._coroutine);
	}

	counter_cor& operator=(counter_cor&& other) {
		if(&other != this) {
			_coroutine = other._coroutine;
			other._coroutine = nullptr;
		}
		return *this;
	}

	void resume() { _coroutine.resume(); }
};

counter_cor counter() {
	std::cout << "Counter: called\n";
	for(unsigned i = 1;; i++) {
		co_await std::experimental::suspend_always{};
		std::cout << "Counter: Resumed " << i << " time(s)\n";
	}
}

int main() {
	std::cout << "Main: calling counter\n";
	auto c = counter();
	std::cout << "Main: resumes\n";
	c.resume();
	c.resume();
	std::cout << "Main: done\n";
}