@@ -58,48 +58,54 @@ struct NonVoid<C<Ts...>>
5858template <typename T>
5959using NonVoid = typename internal::NonVoid<T>::Type;
6060
61- template <Executor E, TaskResult... Rs>
62- TaskHandle<NonVoid<std::variant<Rs...>>, E> AnyOf (TaskHandle<Rs, E>... ts)
61+ struct AnyOfFn
6362{
64- using ThisTaskHandle = TaskHandle<NonVoid<std::variant<Rs...>>, E>;
65-
66- std::optional<NonVoid<std::variant<Rs...>>> ret;
67- stdcr::coroutine_handle<> continuation = nullptr ;
68-
69- auto TaskWrapper = [&]<size_t I, typename R>(std::in_place_index_t <I> i,
70- TaskHandle<R, E> task) -> TaskHandle<void , E> {
71- if (ret.has_value ())
72- co_return ;
73-
74- if constexpr (std::is_same_v<R, void >) {
75- co_await std::move (task);
76- ret.emplace (i, internal::TypeConverter<void >::Type{});
77- } else {
78- R tmp = co_await std::move (task);
79- ret.emplace (i, std::move (tmp));
80- }
81- if (continuation)
82- continuation.resume ();
83- };
84-
85- auto handles = internal::CreateArray (std::make_index_sequence<sizeof ...(Rs)>{},
86- std::forward_as_tuple (std::move (ts)...),
87- TaskWrapper);
63+ template <Executor E, TaskResult... Rs>
64+ using HandleType = TaskHandle<NonVoid<std::variant<Rs...>>, E>;
8865
89- auto thisHandle =
90- co_await internal::CurrentHandleRetriever<typename ThisTaskHandle::promise_type>{};
91- const auto & thisPromise = thisHandle.promise ();
92-
93- for (auto & h : handles)
94- h.Run (thisPromise.Executor (), &thisPromise.CancelationFlag ());
66+ template <Executor E, TaskResult... Rs>
67+ HandleType<E, Rs...> operator ()(TaskHandle<Rs, E>... ts) const
68+ {
69+ std::optional<NonVoid<std::variant<Rs...>>> ret;
70+ stdcr::coroutine_handle<> continuation = nullptr ;
71+
72+ auto TaskWrapper = [&]<size_t I, typename R>(std::in_place_index_t <I> i,
73+ TaskHandle<R, E> task) -> TaskHandle<void , E> {
74+ if (ret.has_value ())
75+ co_return ;
76+
77+ if constexpr (std::is_same_v<R, void >) {
78+ co_await std::move (task);
79+ ret.emplace (i, internal::TypeConverter<void >::Type{});
80+ } else {
81+ R tmp = co_await std::move (task);
82+ ret.emplace (i, std::move (tmp));
83+ }
84+ if (continuation)
85+ continuation.resume ();
86+ };
87+
88+ auto tasks = internal::CreateArray (std::make_index_sequence<sizeof ...(Rs)>{},
89+ std::forward_as_tuple (std::move (ts)...),
90+ TaskWrapper);
91+
92+ auto thisHandle =
93+ co_await internal::CurrentHandleRetriever<typename HandleType<E, Rs...>::promise_type>{};
94+ const auto & thisPromise = thisHandle.promise ();
95+
96+ for (auto & h : tasks)
97+ h.Run (thisPromise.Executor (), &thisPromise.CancelationFlag ());
98+
99+ if (!ret.has_value ()) {
100+ continuation = thisHandle;
101+ co_await stdcr::suspend_always{};
102+ }
95103
96- if (!ret.has_value ()) {
97- continuation = thisHandle;
98- co_await stdcr::suspend_always{};
104+ co_return *ret;
99105 }
106+ };
100107
101- co_return *ret;
102- }
108+ inline constexpr AnyOfFn AnyOf;
103109
104110} // namespace cr
105111
0 commit comments