A weird game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
turings-tarpit/corotest.cpp

125 lines
2.1 KiB

#include <concepts>
#include <coroutine>
#include <exception>
#include <iostream>
#include <vector>
#include <assert.h>
#include <chrono>
using namespace std;
using namespace std::chrono;
template<typename T>
struct Task {
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
struct promise_type {
T value_;
std::exception_ptr exception_;
Task get_return_object() {
return Task(handle_type::from_promise(*this));
}
std::suspend_always initial_suspend() {
return {};
}
std::suspend_always final_suspend() noexcept {
return {};
}
void unhandled_exception() {
exception_ = std::current_exception();
}
template<std::convertible_to<T> From> // C++20 concept
void return_value(From &&from) {
value_ = std::forward<From>(from);
}
template<std::convertible_to<T> From> // C++20 concept
std::suspend_always yield_value(From &&from) {
value_ = std::forward<From>(from);
return {};
}
void return_void() {}
};
handle_type h_;
Task() {
}
Task(handle_type h) : h_(h) {
}
Task(const Task &t) : h_(t.h_) {
}
void destroy() {
h_.destroy();
}
T operator()() {
assert(!h_.done());
call();
return std::move(h_.promise().value_);
}
bool done() {
return h_.done();
}
private:
void call() {
h_();
if (h_.promise().exception_)
std::rethrow_exception(h_.promise().exception_);
}
};
#define pass() co_await std::suspend_always{}
Task<unsigned> task_test()
{
pass();
for (unsigned i = 0; i < 3; ++i)
co_yield i;
co_return 1000;
}
int main()
{
const int task_count = 4;
vector<Task<unsigned>> tasks;
for(int i = 0; i < task_count; i++) {
auto t = task_test();
tasks.push_back(std::move(t));
}
int done_count = 0;
while(done_count < task_count) {
for(int i = 0; i < task_count; i++) {
Task<unsigned> &t = tasks[i];
if(t.done()) {
t.destroy();
done_count++;
} else {
auto res = t();
cout << "T# " << i << " result "
<< res << endl;
}
}
}
}