102 lines
2.5 KiB
C++
102 lines
2.5 KiB
C++
//
|
|
// Created by selim on 03.01.2022.
|
|
//
|
|
|
|
#ifndef AUTOCAT_GNOME_TASK_H
|
|
#define AUTOCAT_GNOME_TASK_H
|
|
|
|
#include <coroutine>
|
|
#include <iostream>
|
|
#include <optional>
|
|
|
|
template<typename T>
|
|
class Task {
|
|
public:
|
|
struct promise_type {
|
|
auto initial_suspend() const noexcept {
|
|
std::cout << "initial_suspend" << std::endl;
|
|
return std::suspend_never();
|
|
}
|
|
|
|
auto final_suspend() const noexcept {
|
|
std::cout << "final_suspend" << std::endl;
|
|
return std::suspend_never();
|
|
}
|
|
|
|
Task<T> get_return_object() {
|
|
std::cout << "get_return_object" << std::endl;
|
|
return Task<T>{ std::coroutine_handle<promise_type>::from_promise(*this) };
|
|
}
|
|
|
|
void return_value(const T& value) noexcept(std::is_nothrow_copy_constructible_v<T>) {
|
|
std::cout << "return_value: " << value << std::endl;
|
|
_value = value;
|
|
}
|
|
|
|
// void return_void() {
|
|
// std::cout << "return_void" << std::endl;
|
|
// }
|
|
|
|
void unhandled_exception() {
|
|
std::cout << "unhandled_exception" << std::endl;
|
|
throw;
|
|
}
|
|
};
|
|
|
|
private:
|
|
std::optional<T> _value = std::nullopt;
|
|
std::coroutine_handle<promise_type> _handle;
|
|
|
|
//public:
|
|
// bool await_ready() const noexcept {
|
|
// std::cout << "Awaiter::await_ready" << std::endl;
|
|
// return false;
|
|
// }
|
|
//
|
|
// void await_suspend(std::coroutine_handle<promise_type> handle) const {
|
|
// std::cout << "Awaiter::await_suspend" << std::endl;
|
|
// _handle = handle;
|
|
// }
|
|
//
|
|
// T await_resume() {
|
|
// std::cout << "Awaiter::await_resume" << std::endl;
|
|
// return _value.value();
|
|
// }
|
|
|
|
public:
|
|
void set_result(T result) {
|
|
_value = result;
|
|
_handle();
|
|
}
|
|
};
|
|
|
|
template<typename U> struct Awaiter {
|
|
public:
|
|
bool await_ready() const noexcept {
|
|
std::cout << "Awaiter::await_ready" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
void await_suspend(std::coroutine_handle<typename Task<U>::promise_type> cont) const {
|
|
std::cout << "Awaiter::await_suspend" << std::endl;
|
|
}
|
|
|
|
U await_resume() {
|
|
std::cout << "Awaiter::await_resume" << std::endl;
|
|
return _task.value();
|
|
}
|
|
|
|
private:
|
|
Task<U> _task;
|
|
|
|
public:
|
|
explicit Awaiter(Task<U> task): _task(task) {}
|
|
};
|
|
|
|
template<typename T>
|
|
auto operator co_await(Task<T> task) noexcept /*requires(!std::is_reference_v<T>)*/ {
|
|
return Awaiter<T>(task);
|
|
}
|
|
|
|
#endif //AUTOCAT_GNOME_TASK_H
|