mrs_lib
Various reusable classes, functions and utilities for use in MRS projects
Loading...
Searching...
No Matches
runners.hpp
1#ifndef MRS_LIB_CORO_RUNNERS_HPP_
2#define MRS_LIB_CORO_RUNNERS_HPP_
3
4#include <concepts>
5#include <coroutine>
6
7#include <mrs_lib/coro/internal/thread_local_continuation_scheduler.hpp>
8#include <mrs_lib/coro/task.hpp>
9#include <stop_token>
10#include <utility>
11
12
13namespace mrs_lib::coro
14{
15
16 namespace internal
17 {
18
27 {
28 public:
30 {
34 template <typename... Args>
35 promise_type(std::stop_token stop_token, Args&&...) : stop_token_(std::move(stop_token))
36 {
37 }
38
39 AsyncRun get_return_object()
40 {
41 return {};
42 }
43 MoveToThreadLocalContinuationScheduler initial_suspend()
44 {
45 return {};
46 }
47 std::suspend_never final_suspend() noexcept
48 {
49 return {};
50 }
51 void return_void()
52 {
53 }
54 void unhandled_exception()
55 {
56 throw;
57 }
58
59 std::stop_token stop_token_;
60 };
61
62 private:
63 AsyncRun() = default;
64 };
65
66 template <>
68 {
69 static CancellableContinuation release_continuation(std::coroutine_handle<AsyncRun::promise_type>)
70 {
71 return {};
72 };
73
74 static std::stop_token get_token(std::coroutine_handle<AsyncRun::promise_type> handle)
75 {
76 return handle.promise().stop_token_;
77 }
78 };
79
93 template <typename F, typename... Args>
94 requires std::invocable<std::decay_t<F>, std::decay_t<Args>...> && std::same_as<Task<void>, std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>>
95 internal::AsyncRun start_task_impl(std::stop_token, F task, Args... args)
96 {
97 // The `decay-copy` of the arguments ensures that they are copied into
98 // the coroutine frame, preventing dangling references like `std::thread`.
99 co_await std::invoke(std::move(task), std::move(args)...);
100 }
101
116 template <typename F, typename... Args>
117 requires std::invocable<std::decay_t<F>, std::decay_t<Args>...> && std::same_as<Task<void>, std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>>
118 void start_task(F&& task, Args&&... args)
119 {
120 internal::start_task_impl(std::stop_token(), std::forward<F>(task), std::forward<Args>(args)...);
121 }
122
138 template <typename F, typename... Args>
139 requires std::invocable<std::decay_t<F>, std::decay_t<Args>...> && std::same_as<Task<void>, std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>>
140 void start_task(std::stop_token token, F&& task, Args&&... args)
141 {
142 internal::start_task_impl(token, std::forward<F>(task), std::forward<Args>(args)...);
143 }
144
145 } // namespace internal
146
147} // namespace mrs_lib::coro
148
149#endif // MRS_LIB_CORO_RUNNERS_HPP_
Coroutine type used to start asynchronous computation.
Definition runners.hpp:27
Owning coroutine handle supporting cancellation.
Definition continuation.hpp:54
promise_type(std::stop_token stop_token, Args &&...)
Construct the promise type, storing the associated stop token.
Definition runners.hpp:35
Type trait to obtain data necessary for creating CancellableContinuation.
Definition continuation.hpp:37