comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/kj/async-prelude.h @ 69:33d812a61356

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 17:55:14 -0400
parents
children
comparison
equal deleted inserted replaced
67:0e9998148a16 69:33d812a61356
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
2 // Licensed under the MIT License:
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21
22 // This file contains a bunch of internal declarations that must appear before async.h can start.
23 // We don't define these directly in async.h because it makes the file hard to read.
24
25 #pragma once
26
27 #include <kj/exception.h>
28 #include <kj/tuple.h>
29 #include <kj/source-location.h>
30
31 // Detect whether or not we should enable kj::Promise<T> coroutine integration.
32 //
33 // TODO(someday): Support coroutines with -fno-exceptions.
34 #if !KJ_NO_EXCEPTIONS
35 #ifdef __has_include
36 #if (__cpp_impl_coroutine >= 201902L) && __has_include(<coroutine>)
37 // C++20 Coroutines detected.
38 #include <coroutine>
39 #define KJ_HAS_COROUTINE 1
40 #define KJ_COROUTINE_STD_NAMESPACE std
41 #elif (__cpp_coroutines >= 201703L) && __has_include(<experimental/coroutine>)
42 // Coroutines TS detected.
43 #include <experimental/coroutine>
44 #define KJ_HAS_COROUTINE 1
45 #define KJ_COROUTINE_STD_NAMESPACE std::experimental
46 #endif
47 #endif
48 #endif
49
50 KJ_BEGIN_HEADER
51
52 namespace kj {
53
54 class EventLoop;
55 template <typename T>
56 class Promise;
57 class WaitScope;
58 class TaskSet;
59
60 Promise<void> joinPromises(Array<Promise<void>>&& promises, SourceLocation location = {});
61 Promise<void> joinPromisesFailFast(Array<Promise<void>>&& promises, SourceLocation location = {});
62 // Out-of-line <void> specialization of template function defined in async.h.
63
64 namespace _ { // private
65
66 template <typename T>
67 Promise<T> chainPromiseType(T*);
68 template <typename T>
69 Promise<T> chainPromiseType(Promise<T>*);
70
71 template <typename T>
72 using ChainPromises = decltype(chainPromiseType((T*)nullptr));
73 // Constructs a promise for T, reducing double-promises. That is, if T is Promise<U>, resolves to
74 // Promise<U>, otherwise resolves to Promise<T>.
75
76 template <typename T>
77 Promise<T> reducePromiseType(T*, ...);
78 template <typename T>
79 Promise<T> reducePromiseType(Promise<T>*, ...);
80 template <typename T, typename Reduced = decltype(T::reducePromise(kj::instance<Promise<T>>()))>
81 Reduced reducePromiseType(T*, bool);
82
83 template <typename T>
84 using ReducePromises = decltype(reducePromiseType((T*)nullptr, false));
85 // Like ChainPromises, but also takes into account whether T has a method `reducePromise` that
86 // reduces Promise<T> to something else. In particular this allows Promise<capnp::RemotePromise<U>>
87 // to reduce to capnp::RemotePromise<U>.
88
89 template <typename T> struct UnwrapPromise_;
90 template <typename T> struct UnwrapPromise_<Promise<T>> { typedef T Type; };
91
92 template <typename T>
93 using UnwrapPromise = typename UnwrapPromise_<T>::Type;
94
95 class PropagateException {
96 // A functor which accepts a kj::Exception as a parameter and returns a broken promise of
97 // arbitrary type which simply propagates the exception.
98 public:
99 class Bottom {
100 public:
101 Bottom(Exception&& exception): exception(kj::mv(exception)) {}
102
103 Exception asException() { return kj::mv(exception); }
104
105 private:
106 Exception exception;
107 };
108
109 Bottom operator()(Exception&& e) {
110 return Bottom(kj::mv(e));
111 }
112 Bottom operator()(const Exception& e) {
113 return Bottom(kj::cp(e));
114 }
115 };
116
117 template <typename Func, typename T>
118 struct ReturnType_ { typedef decltype(instance<Func>()(instance<T>())) Type; };
119 template <typename Func>
120 struct ReturnType_<Func, void> { typedef decltype(instance<Func>()()) Type; };
121
122 template <typename Func, typename T>
123 using ReturnType = typename ReturnType_<Func, T>::Type;
124 // The return type of functor Func given a parameter of type T, with the special exception that if
125 // T is void, this is the return type of Func called with no arguments.
126
127 template <typename T> struct SplitTuplePromise_ { typedef Promise<T> Type; };
128 template <typename... T>
129 struct SplitTuplePromise_<kj::_::Tuple<T...>> {
130 typedef kj::Tuple<ReducePromises<T>...> Type;
131 };
132
133 template <typename T>
134 using SplitTuplePromise = typename SplitTuplePromise_<T>::Type;
135 // T -> Promise<T>
136 // Tuple<T> -> Tuple<Promise<T>>
137
138 struct Void {};
139 // Application code should NOT refer to this! See `kj::READY_NOW` instead.
140
141 template <typename T> struct FixVoid_ { typedef T Type; };
142 template <> struct FixVoid_<void> { typedef Void Type; };
143 template <typename T> using FixVoid = typename FixVoid_<T>::Type;
144 // FixVoid<T> is just T unless T is void in which case it is _::Void (an empty struct).
145
146 template <typename T> struct UnfixVoid_ { typedef T Type; };
147 template <> struct UnfixVoid_<Void> { typedef void Type; };
148 template <typename T> using UnfixVoid = typename UnfixVoid_<T>::Type;
149 // UnfixVoid is the opposite of FixVoid.
150
151 template <typename In, typename Out>
152 struct MaybeVoidCaller {
153 // Calls the function converting a Void input to an empty parameter list and a void return
154 // value to a Void output.
155
156 template <typename Func>
157 static inline Out apply(Func& func, In&& in) {
158 return func(kj::mv(in));
159 }
160 };
161 template <typename In, typename Out>
162 struct MaybeVoidCaller<In&, Out> {
163 template <typename Func>
164 static inline Out apply(Func& func, In& in) {
165 return func(in);
166 }
167 };
168 template <typename Out>
169 struct MaybeVoidCaller<Void, Out> {
170 template <typename Func>
171 static inline Out apply(Func& func, Void&& in) {
172 return func();
173 }
174 };
175 template <typename In>
176 struct MaybeVoidCaller<In, Void> {
177 template <typename Func>
178 static inline Void apply(Func& func, In&& in) {
179 func(kj::mv(in));
180 return Void();
181 }
182 };
183 template <typename In>
184 struct MaybeVoidCaller<In&, Void> {
185 template <typename Func>
186 static inline Void apply(Func& func, In& in) {
187 func(in);
188 return Void();
189 }
190 };
191 template <>
192 struct MaybeVoidCaller<Void, Void> {
193 template <typename Func>
194 static inline Void apply(Func& func, Void&& in) {
195 func();
196 return Void();
197 }
198 };
199
200 template <typename T>
201 inline T&& returnMaybeVoid(T&& t) {
202 return kj::fwd<T>(t);
203 }
204 inline void returnMaybeVoid(Void&& v) {}
205
206 class ExceptionOrValue;
207 class PromiseNode;
208 class ChainPromiseNode;
209 template <typename T>
210 class ForkHub;
211 class FiberStack;
212 class FiberBase;
213
214 class Event;
215 class XThreadEvent;
216 class XThreadPaf;
217
218 class PromiseDisposer;
219 using OwnPromiseNode = Own<PromiseNode, PromiseDisposer>;
220 // PromiseNode uses a static disposer.
221
222 class PromiseBase {
223 public:
224 kj::String trace();
225 // Dump debug info about this promise.
226
227 private:
228 OwnPromiseNode node;
229
230 PromiseBase() = default;
231 PromiseBase(OwnPromiseNode&& node): node(kj::mv(node)) {}
232
233 template <typename>
234 friend class kj::Promise;
235 friend class PromiseNode;
236 };
237
238 void detach(kj::Promise<void>&& promise);
239 void waitImpl(_::OwnPromiseNode&& node, _::ExceptionOrValue& result, WaitScope& waitScope,
240 SourceLocation location);
241 bool pollImpl(_::PromiseNode& node, WaitScope& waitScope, SourceLocation location);
242 Promise<void> yield();
243 Promise<void> yieldHarder();
244 OwnPromiseNode readyNow();
245 OwnPromiseNode neverDone();
246
247 class ReadyNow {
248 public:
249 operator Promise<void>() const;
250 };
251
252 class NeverDone {
253 public:
254 template <typename T>
255 operator Promise<T>() const;
256
257 KJ_NORETURN(void wait(WaitScope& waitScope, SourceLocation location = {}) const);
258 };
259
260 } // namespace _ (private)
261 } // namespace kj
262
263 KJ_END_HEADER