Corium 1.1.0
High-Performance Zero-Heap C++20 MPSC Application Runtime
Loading...
Searching...
No Matches
WhenAny.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include <cstddef>
10#include <type_traits>
11#include <utility>
12#include <variant>
13
14#include "corium/async/Task.hpp"
15
16namespace corium::async {
17
18namespace detail {
19
20template <typename T>
21struct WrapVoid {
22 using type = T;
23};
24
25template <>
26struct WrapVoid<void> {
27 using type = std::monostate;
28};
29
30template <typename T>
32
33} // namespace detail
34
36template <typename... ResultTypes>
38 std::size_t index{0};
39 std::variant<detail::wrap_void_t<ResultTypes>...> result{};
40};
41
42namespace detail {
43
44template <size_t Index, typename TaskType, typename ResultVariant>
45bool checkTaskDone(TaskType& task, size_t& winnerIndex, ResultVariant& resultVariant)
46{
47 if (task.done()) {
48 winnerIndex = Index;
49 if constexpr (!std::is_void_v<typename TaskType::ValueType>) {
50 resultVariant.template emplace<Index>(task.await_resume());
51 } else {
52 task.await_resume();
53 resultVariant.template emplace<Index>(std::monostate{});
54 }
55 return true;
56 }
57 return false;
58}
59
60template <size_t Index, typename TaskType>
61void resumeTask(TaskType& task)
62{
63 if (!task.done()) {
64 task.resume();
65 }
66}
67
68template <typename... Tasks, size_t... Is>
69Task<WhenAnyResult<typename std::decay_t<Tasks>::ValueType...>> whenAnyImpl(std::index_sequence<Is...>, Tasks... tasks)
70{
72 ResultType res{};
73
74 // Initial resume pass
75 (resumeTask<Is>(tasks), ...);
76
77 while (true) {
78 bool winnerFound = (checkTaskDone<Is>(tasks, res.index, res.result) || ...);
79 if (winnerFound) {
80 break;
81 }
82 (resumeTask<Is>(tasks), ...);
83 }
84
85 co_return res;
86}
87
88} // namespace detail
89
93template <typename... Tasks>
94auto whenAny(Tasks&&... tasks)
95{
97 std::index_sequence_for<Tasks...>{},
98 std::forward<Tasks>(tasks)...
99 );
100}
101
102} // namespace corium::async
Lazy awaitable C++20 coroutine task with zero dynamic heap allocation.
Lightweight C++20 coroutine task with zero-heap resumption chaining and configurable frame allocator.
Definition Task.hpp:22
auto whenAny(Tasks &&... tasks)
Awaits the first task among multiple tasks to complete.
Definition WhenAny.hpp:94
typename WrapVoid< T >::type wrap_void_t
Definition WhenAny.hpp:31
bool checkTaskDone(TaskType &task, size_t &winnerIndex, ResultVariant &resultVariant)
Definition WhenAny.hpp:45
Task< WhenAnyResult< typename std::decay_t< Tasks >::ValueType... > > whenAnyImpl(std::index_sequence< Is... >, Tasks... tasks)
Definition WhenAny.hpp:69
void resumeTask(TaskType &task)
Definition WhenAny.hpp:61
Definition AsyncEvent.hpp:14
Result container for whenAny combinator.
Definition WhenAny.hpp:37
std::variant< detail::wrap_void_t< ResultTypes >... > result
Definition WhenAny.hpp:39
std::size_t index
Definition WhenAny.hpp:38
std::monostate type
Definition WhenAny.hpp:27
Definition WhenAny.hpp:21
T type
Definition WhenAny.hpp:22