Commit 1369f985 authored by Xavier Thompson's avatar Xavier Thompson

Allow co_awaiting anything

parent a5f699f1
#include <typon/typon.hpp>
#include <typon/logger.hpp>
#include <python/builtins.hpp>
#include <typon/generator.hpp>
using namespace typon;
......@@ -12,7 +10,7 @@ int fibo(int n) {
}
Task<void> hello(int id) {
int n = fibo(20);
int n = fibo(40);
LOG("hello(%d), fibo(20) = %d", id, n);
co_return;
}
......
......@@ -23,6 +23,7 @@ Task<void> with_lock(int id)
LOG("with_lock(%d), acquired", id);
int n = fibo(N);
LOG("with_lock(%d), fibo(%d) = %d", id, N, n);
LOG("with_lock(%d), releasing", id);
}
LOG("with_lock(%d), released", id);
}
......
......@@ -30,7 +30,9 @@ namespace typon
Fork(std::coroutine_handle<promise_type> coroutine) noexcept
: _coroutine(coroutine)
{}
{
static_assert(meta::Awaitable<Fork>);
}
Fork(const Fork &) = delete;
Fork& operator=(const Fork &) = delete;
......
......@@ -6,6 +6,7 @@
#include <cstdint>
#include <utility>
#include <typon/meta.hpp>
#include <typon/result.hpp>
#include <typon/scheduler.hpp>
#include <typon/stack.hpp>
......
......@@ -24,7 +24,9 @@ namespace typon
coroutine_type _coroutine;
Join(coroutine_type coroutine) noexcept : _coroutine(coroutine) {}
Join(coroutine_type coroutine) noexcept : _coroutine(coroutine) {
static_assert(meta::Awaitable<Join>);
}
Join(const Join &) = delete;
Join & operator=(const Join &) = delete;
......@@ -73,12 +75,19 @@ namespace typon
_span.set_sequential_exception(std::current_exception());
}
template <typename U>
template <meta::Awaitable U>
decltype(auto) await_transform(U && expr) noexcept
{
return std::forward<U>(expr);
}
template <typename U>
requires (! meta::Awaitable<U>)
decltype(auto) await_transform(U && expr) noexcept
{
return meta::AwaitReady{std::forward<U>(expr)};
}
auto await_transform(Sync &&) noexcept
{
struct awaitable
......
#ifndef TYPON_META_HPP_INCLUDED
#define TYPON_META_HPP_INCLUDED
#include <coroutine>
#include <type_traits>
namespace typon::meta
{
struct Empty {};
template <typename T>
concept Awaiter = requires (T && a, std::coroutine_handle<void> h)
{
// simplified
a.await_ready();
a.await_suspend(h);
a.await_resume();
};
template <typename T>
concept Awaitable = Awaiter<std::remove_cvref_t<T>> || requires (T && a)
{
// simplified
std::forward<T>(a).operator co_await();
};
template <typename T>
requires (! Awaitable<T>)
struct AwaitReady : std::suspend_never {
T _ready;
AwaitReady() = delete;
AwaitReady(const AwaitReady &) = delete;
AwaitReady & operator=(const AwaitReady &) = delete;
AwaitReady(T && ready) : _ready(std::move(ready)) {}
AwaitReady(const T & ready) : _ready(ready) {}
T await_resume() noexcept {
return std::move(_ready);
}
};
}
......
......@@ -4,6 +4,7 @@
#include <coroutine>
#include <utility>
#include <typon/meta.hpp>
#include <typon/result.hpp>
......@@ -17,7 +18,9 @@ namespace typon
std::coroutine_handle<promise_type> _coroutine;
Task(std::coroutine_handle<promise_type> coroutine) noexcept : _coroutine(coroutine) {}
Task(std::coroutine_handle<promise_type> coroutine) noexcept : _coroutine(coroutine) {
static_assert(meta::Awaitable<Task>);
}
Task(const Task &) = delete;
Task & operator=(const Task &) = delete;
......@@ -54,6 +57,19 @@ namespace typon
return {};
}
template <meta::Awaitable U>
decltype(auto) await_transform(U && expr) noexcept
{
return std::forward<U>(expr);
}
template <typename U>
requires (! meta::Awaitable<U>)
decltype(auto) await_transform(U && expr) noexcept
{
return meta::AwaitReady{std::forward<U>(expr)};
}
auto final_suspend() noexcept
{
struct awaitable : std::suspend_always
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment