13
13
#include " coro/coro.hpp"
14
14
15
15
namespace jam {
16
- void coroSpawn (auto &&executor, Coro<void > &&coro) {
16
+ template <typename T>
17
+ concept CoroSpawnExecutor =
18
+ boost::asio::is_executor<T>::value
19
+ || boost::asio::execution::is_executor<T>::value
20
+ || std::is_convertible_v<T, boost::asio::execution_context &>;
21
+
22
+ void coroSpawn (CoroSpawnExecutor auto &&executor, Coro<void > &&coro) {
17
23
boost::asio::co_spawn (std::forward<decltype (executor)>(executor),
18
24
std::move (coro),
19
25
[](std::exception_ptr e) {
@@ -24,7 +30,7 @@ namespace jam {
24
30
}
25
31
26
32
template <typename T>
27
- void coroSpawn (auto &&executor, Coro<T> &&coro) {
33
+ void coroSpawn (CoroSpawnExecutor auto &&executor, Coro<T> &&coro) {
28
34
coroSpawn (std::forward<decltype (executor)>(executor),
29
35
[coro{std::move (coro)}]() mutable -> Coro<void > {
30
36
std::ignore = co_await std::move (coro);
@@ -41,7 +47,7 @@ namespace jam {
41
47
* `co_spawn([](args){ ... }(capture))`
42
48
* works because arguments are stored in coroutine state.
43
49
*/
44
- void coroSpawn (auto &&executor, auto &&f) {
50
+ void coroSpawn (CoroSpawnExecutor auto &&executor, auto &&f) {
45
51
coroSpawn (std::forward<decltype (executor)>(executor),
46
52
[](std::remove_cvref_t <decltype (f)> f) -> Coro<void > {
47
53
if constexpr (std::is_void_v<decltype (f ().await_resume ())>) {
0 commit comments