To Integrate networking with the concurrency approach, and provide protable classes and functions.
The steps are:
struct immovable{ immovable() = default; immovable(immovable&&) = delete;}
class task
{
public:
template<tyename S>
struct awaiter
{
using ResultType = typename S::result_t;
struct receiver {
awaiter* a;
friend void set_value(receiver self, auto v) {
self.a->value_.emplace(std::move(v));
self.a->handle_.resume();
}
friend void set_value(receiver self, auto e) {
self.a->error_ = e;
self.a->handle_.resume();
}
};
awaiter(S s): state_(connect(s, reicever{this})) {}
bool await_ready() {return false;}
void await_suspend(std::coroutine_handle<void> handle) {
this->handle_ = handle;
start(state_);
}
ResultType await_resume() {
if(error_) std::rethrow_exception(error);
return std::move(*value);
}
using state_t = decltype(connect(std::declval<S>(), std::declval<receiver>()));
std::coroutine_handle<void> handle_;
state_t state_;
std::optional<RusultType> value_;
std::exception_ptr error_;
};
struct none {};
using result_t = none;
struct state_base: immovable {
state_base() = default;
state_base(state_base&&) = delete;
virtual void complete() = 0;
};
struct promise_type: immovable
{
state_base* state = nullptr;
task get_return_object() {
return {std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_always initial_suspend() {return {};}
std::suspend_never final_suspend() noexcept {
if(state) state->complete();
return {};
}
void unhandled_exception() { std::terminate();}
}
}