Iros
 
Loading...
Searching...
No Matches
coroutine.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/meta/language.h"
4#include "di/types/prelude.h"
5
6#ifndef DI_NO_USE_STD
7#include <coroutine>
8#else
9namespace std {
10template<typename, typename...>
11struct coroutine_traits {};
12
13template<typename R, typename... Args>
14requires(requires { typename R::promise_type; })
15struct coroutine_traits<R, Args...> {
16 using promise_type = typename R::promise_type;
17};
18
19template<typename Promise = void>
20struct coroutine_handle;
21
22template<>
23struct coroutine_handle<void> {
24public:
25 constexpr coroutine_handle() noexcept = default;
26 constexpr coroutine_handle(std::nullptr_t) noexcept {}
27
28 constexpr auto operator=(std::nullptr_t) noexcept -> coroutine_handle& {
29 m_frame_pointer = nullptr;
30 return *this;
31 }
32
33 auto done() const noexcept -> bool { return __builtin_coro_done(m_frame_pointer); }
34 constexpr explicit operator bool() const noexcept { return bool(m_frame_pointer); }
35
36 void operator()() const { resume(); }
37 void resume() const { __builtin_coro_resume(m_frame_pointer); }
38
39 void destroy() const { __builtin_coro_destroy(m_frame_pointer); }
40
41 constexpr auto address() const noexcept -> void* { return m_frame_pointer; }
42 constexpr static auto from_address(void* address) noexcept -> coroutine_handle {
43 coroutine_handle result;
44 result.m_frame_pointer = address;
45 return result;
46 }
47
48protected:
49 void* m_frame_pointer { nullptr };
50};
51
52template<typename Promise>
53requires(!di::concepts::LanguageVoid<Promise>)
54struct coroutine_handle<Promise> {
55public:
56 constexpr coroutine_handle() noexcept = default;
57 constexpr coroutine_handle(std::nullptr_t) noexcept {}
58
59 constexpr auto operator=(std::nullptr_t) noexcept -> coroutine_handle& {
60 m_frame_pointer = nullptr;
61 return *this;
62 }
63
64 constexpr operator coroutine_handle<>() const noexcept { return std::coroutine_handle<>::from_address(address()); }
65
66 auto done() const noexcept -> bool { return __builtin_coro_done(m_frame_pointer); }
67 constexpr explicit operator bool() const noexcept { return bool(m_frame_pointer); }
68
69 void operator()() const { resume(); }
70 void resume() const { __builtin_coro_resume(m_frame_pointer); }
71
72 void destroy() const { __builtin_coro_destroy(m_frame_pointer); }
73
74 auto promise() const -> Promise& {
75 void* promise_pointer = __builtin_coro_promise(m_frame_pointer, alignof(Promise), false);
76 return *static_cast<Promise*>(promise_pointer);
77 }
78 static auto from_promise(Promise& promise) -> coroutine_handle {
79 coroutine_handle result;
80 result.m_frame_pointer = __builtin_coro_promise((char*) &promise, alignof(Promise), true);
81 return result;
82 }
83
84 constexpr auto address() const noexcept -> void* { return m_frame_pointer; }
85 constexpr static auto from_address(void* address) noexcept -> coroutine_handle {
86 coroutine_handle result;
87 result.m_frame_pointer = address;
88 return result;
89 }
90
91private:
92 void* m_frame_pointer { nullptr };
93};
94
95constexpr auto operator==(std::coroutine_handle<> a, std::coroutine_handle<> b) noexcept -> bool {
96 return a.address() == b.address();
97}
98
99constexpr auto operator<=>(std::coroutine_handle<> a, std::coroutine_handle<> b) noexcept -> std::strong_ordering {
100 return a.address() <=> b.address();
101}
102
103struct noop_coroutine_promise {};
104
105template<>
106struct coroutine_handle<noop_coroutine_promise> {
107private:
108 struct Frame {
109 constexpr static void noop() {}
110
111 void (*resume)() = noop;
112 void (*destroy)() = noop;
113 struct noop_coroutine_promise promise;
114 };
115 static Frame static_frame;
116
117public:
118 constexpr operator coroutine_handle<>() const noexcept { return std::coroutine_handle<>::from_address(address()); }
119
120 constexpr auto done() const noexcept -> bool { return false; }
121 constexpr explicit operator bool() const noexcept { return true; }
122
123 constexpr void operator()() const noexcept { resume(); }
124 constexpr void resume() const noexcept {}
125
126 constexpr void destroy() const noexcept {}
127
128 constexpr auto promise() const noexcept -> noop_coroutine_promise& { return static_frame.promise; }
129
130 constexpr auto address() const noexcept -> void* { return m_frame_pointer; }
131
132private:
133 friend auto noop_coroutine() noexcept -> coroutine_handle;
134
135 explicit coroutine_handle() noexcept = default;
136
137 void* m_frame_pointer { &static_frame };
138};
139
140using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
141
142inline noop_coroutine_handle::Frame noop_coroutine_handle::static_frame {};
143
144inline auto noop_coroutine() noexcept -> noop_coroutine_handle {
145 return noop_coroutine_handle();
146}
147
148struct suspend_never {
149 constexpr auto await_ready() const noexcept -> bool { return true; }
150 constexpr void await_suspend(std::coroutine_handle<>) const noexcept {}
151 constexpr void await_resume() const noexcept {}
152};
153
154struct suspend_always {
155 constexpr auto await_ready() const noexcept -> bool { return false; }
156 constexpr void await_suspend(std::coroutine_handle<>) const noexcept {}
157 constexpr void await_resume() const noexcept {}
158};
159}
160#endif
161
162namespace di {
163template<typename Promise = void>
164using CoroutineHandle = std::coroutine_handle<Promise>;
165
166using NoopCoroutineHandle = std::noop_coroutine_handle;
167using NoopCoroutinePromise = std::noop_coroutine_promise;
168
169using SuspendAlways = std::suspend_always;
170using SuspendNever = std::suspend_never;
171
172using std::noop_coroutine;
173}
frame::FrameImpl< di::ByteBuffer > Frame
Definition frame.h:73
constexpr auto operator==(Duration< Rep1, Period1 > const &a, Duration< Rep2, Period2 > const &b) -> bool
Definition duration.h:108
constexpr auto operator<=>(Duration< Rep1, Period1 > const &a, Duration< Rep2, Period2 > const &b)
Definition duration.h:115
constexpr auto destroy
Definition destroy.h:35
OperationState< Receiver >::promise_type Promise
Definition connect_awaitable.h:118
Definition zstring_parser.h:9
std::suspend_never SuspendNever
Definition coroutine.h:170
std::coroutine_handle< Promise > CoroutineHandle
Definition coroutine.h:164
std::noop_coroutine_handle NoopCoroutineHandle
Definition coroutine.h:166
std::noop_coroutine_promise NoopCoroutinePromise
Definition coroutine.h:167
std::suspend_always SuspendAlways
Definition coroutine.h:169
Definition enable_generate_structed_bindings.h:46
@ R
Definition key.h:27