22#include "util/async/AnyOperation.hpp"
23#include "util/async/AnyStopToken.hpp"
24#include "util/async/AnyStrand.hpp"
25#include "util/async/Concepts.hpp"
26#include "util/async/impl/ErasedOperation.hpp"
51 template <NotSameAs<AnyExecutionContext> CtxType>
65 template <RValueNotSameAs<AnyExecutionContext> CtxType>
68 : pimpl_{std::make_shared<Model<CtxType>>(std::forward<CtxType>(ctx))}
89 using RetType = std::decay_t<std::invoke_result_t<
decltype(fn)>>;
90 static_assert(not std::is_same_v<RetType, std::any>);
93 pimpl_->execute([fn = std::forward<
decltype(fn)>(fn)] mutable -> std::any {
94 if constexpr (std::is_void_v<RetType>) {
95 std::invoke(std::forward<decltype(fn)>(fn));
98 return std::make_any<RetType>(std::invoke(std::forward<decltype(fn)>(fn)));
115 using RetType = std::decay_t<std::invoke_result_t<
decltype(fn),
AnyStopToken>>;
116 static_assert(not std::is_same_v<RetType, std::any>);
119 [fn = std::forward<
decltype(fn)>(fn)](
auto stopToken) mutable -> std::any {
120 if constexpr (std::is_void_v<RetType>) {
121 std::invoke(std::forward<decltype(fn)>(fn), std::move(stopToken));
124 return std::make_any<RetType>(
125 std::invoke(std::forward<decltype(fn)>(fn), std::move(stopToken))
144 using RetType = std::decay_t<std::invoke_result_t<
decltype(fn),
AnyStopToken>>;
145 static_assert(not std::is_same_v<RetType, std::any>);
148 [fn = std::forward<
decltype(fn)>(fn)](
auto stopToken) mutable -> std::any {
149 if constexpr (std::is_void_v<RetType>) {
150 std::invoke(std::forward<decltype(fn)>(fn), std::move(stopToken));
153 return std::make_any<RetType>(
154 std::invoke(std::forward<decltype(fn)>(fn), std::move(stopToken))
158 std::chrono::duration_cast<std::chrono::milliseconds>(timeout)
174 using RetType = std::decay_t<std::invoke_result_t<
decltype(fn),
AnyStopToken>>;
175 static_assert(not std::is_same_v<RetType, std::any>);
177 auto const millis = std::chrono::duration_cast<std::chrono::milliseconds>(delay);
179 millis, [fn = std::forward<
decltype(fn)>(fn)](
auto stopToken) mutable -> std::any {
180 if constexpr (std::is_void_v<RetType>) {
181 std::invoke(std::forward<decltype(fn)>(fn), std::move(stopToken));
184 return std::make_any<RetType>(
185 std::invoke(std::forward<decltype(fn)>(fn), std::move(stopToken))
205 using RetType = std::decay_t<std::invoke_result_t<
decltype(fn),
AnyStopToken,
bool>>;
206 static_assert(not std::is_same_v<RetType, std::any>);
208 auto const millis = std::chrono::duration_cast<std::chrono::milliseconds>(delay);
211 [fn = std::forward<
decltype(fn)>(fn)](
auto stopToken,
auto cancelled) mutable
213 if constexpr (std::is_void_v<RetType>) {
214 std::invoke(std::forward<decltype(fn)>(fn), std::move(stopToken), cancelled);
217 return std::make_any<RetType>(
218 std::invoke(std::forward<decltype(fn)>(fn), std::move(stopToken), cancelled)
235 using RetType = std::decay_t<std::invoke_result_t<
decltype(fn)>>;
236 static_assert(not std::is_same_v<RetType, std::any>);
238 auto const millis = std::chrono::duration_cast<std::chrono::milliseconds>(interval);
240 pimpl_->executeRepeatedly(
241 millis, [fn = std::forward<
decltype(fn)>(fn)] mutable -> std::any {
242 std::invoke(std::forward<decltype(fn)>(fn));
258 pimpl_->submit(std::forward<
decltype(fn)>(fn));
272 return pimpl_->makeStrand();
295 virtual ~Concept() =
default;
300 std::optional<std::chrono::milliseconds> timeout = std::nullopt
304 scheduleAfter(std::chrono::milliseconds, std::function<std::any(
AnyStopToken)>) = 0;
306 std::chrono::milliseconds,
310 executeRepeatedly(std::chrono::milliseconds, std::function<std::any()>) = 0;
311 virtual void submit(std::function<
void()>) = 0;
320 template <
typename CtxType>
321 struct Model : Concept {
324 template <
typename Type>
325 Model(Type&& ctx) : ctx(std::forward<Type>(ctx))
329 impl::ErasedOperation
331 std::function<std::any(AnyStopToken)> fn,
332 std::optional<std::chrono::milliseconds> timeout
335 return ctx.execute(std::move(fn), timeout);
338 impl::ErasedOperation
339 execute(std::function<std::any()> fn)
override
341 return ctx.execute(std::move(fn));
344 impl::ErasedOperation
346 std::chrono::milliseconds delay,
347 std::function<std::any(AnyStopToken)> fn
350 return ctx.scheduleAfter(delay, std::move(fn));
353 impl::ErasedOperation
355 std::chrono::milliseconds delay,
356 std::function<std::any(AnyStopToken,
bool)> fn
359 return ctx.scheduleAfter(delay, std::move(fn));
362 impl::ErasedOperation
363 executeRepeatedly(std::chrono::milliseconds interval, std::function<std::any()> fn)
override
365 return ctx.executeRepeatedly(interval, std::move(fn));
369 submit(std::function<
void()> fn)
override
371 return ctx.submit(std::move(fn));
375 makeStrand()
override
377 return ctx.makeStrand();
381 stop()
const override
387 join()
const override
394 std::shared_ptr<Concept> pimpl_;
A type-erased execution context.
Definition AnyExecutionContext.hpp:41
auto execute(SomeHandlerWith< AnyStopToken > auto &&fn)
Execute a function on the execution context.
Definition AnyExecutionContext.hpp:113
auto execute(SomeHandlerWith< AnyStopToken > auto &&fn, SomeStdDuration auto timeout)
Execute a function with a timeout.
Definition AnyExecutionContext.hpp:142
auto scheduleAfter(SomeStdDuration auto delay, SomeHandlerWith< AnyStopToken > auto &&fn)
Schedule a function for execution.
Definition AnyExecutionContext.hpp:172
auto makeStrand()
Make a strand for this execution context.
Definition AnyExecutionContext.hpp:270
void stop() const
Stop the execution context.
Definition AnyExecutionContext.hpp:279
auto execute(SomeHandlerWithoutStopToken auto &&fn)
Execute a function on the execution context.
Definition AnyExecutionContext.hpp:87
auto scheduleAfter(SomeStdDuration auto delay, SomeHandlerWith< AnyStopToken, bool > auto &&fn)
Schedule a function for execution.
Definition AnyExecutionContext.hpp:203
AnyExecutionContext(CtxType &ctx)
Construct a new type-erased Execution Context object.
Definition AnyExecutionContext.hpp:53
void submit(SomeHandlerWithoutStopToken auto &&fn)
Schedule an operation on the execution context without expectations of a result.
Definition AnyExecutionContext.hpp:256
AnyExecutionContext(CtxType &&ctx)
Construct a new type-erased Execution Context object.
Definition AnyExecutionContext.hpp:67
void join() const
Join the execution context.
Definition AnyExecutionContext.hpp:288
auto executeRepeatedly(SomeStdDuration auto interval, SomeHandlerWithoutStopToken auto &&fn)
Schedule a repeating operation on the execution context.
Definition AnyExecutionContext.hpp:233
A type-erased operation that can be executed via AnyExecutionContext.
Definition AnyOperation.hpp:44
A type-erased stop token.
Definition AnyStopToken.hpp:37
A type-erased execution context.
Definition AnyStrand.hpp:40
Definition ErasedOperation.hpp:34
Specifies the interface for a handler that can be invoked with the specified args.
Definition Concepts.hpp:184
Specifies the interface for a handler that can be stopped.
Definition Concepts.hpp:176
Specifies that the type must be some std::duration.
Definition Concepts.hpp:192
This namespace implements an async framework built on top of execution contexts.
Definition AnyExecutionContext.hpp:36