39when_all(std::vector<std::future<T>>& futures) -> std::vector<T>
41 std::vector<T> results;
42 results.reserve(futures.size());
43 std::exception_ptr first_error;
45 for (
auto& f : futures)
49 results.push_back(f.get());
54 first_error = std::current_exception();
59 std::rethrow_exception(first_error);
101when_all_settled(std::vector<std::future<T>>& futures) -> std::vector<expected<T, std::exception_ptr>>
103 std::vector<expected<T, std::exception_ptr>> results;
104 results.reserve(futures.size());
106 for (
auto& f : futures)
110 results.push_back(f.get());
114 results.push_back(
unexpected(std::current_exception()));
126when_all_settled(std::vector<std::future<void>>& futures) -> std::vector<expected<void, std::exception_ptr>>
128 std::vector<expected<void, std::exception_ptr>> results;
129 results.reserve(futures.size());
131 for (
auto& f : futures)
136 results.emplace_back();
140 results.push_back(
unexpected(std::current_exception()));
163when_any(std::vector<std::future<T>>& futures) -> std::pair<size_t, T>
166 throw std::invalid_argument(
"when_any: empty futures vector");
168 thread_local std::mt19937 rng{ std::random_device{}() };
169 std::uniform_int_distribution<size_t> dist(0, futures.size() - 1);
170 size_t const start = dist(rng);
171 unsigned backoff_ms = 1;
175 size_t deferred = futures.size();
176 for (
size_t k = 0; k < futures.size(); ++k)
178 size_t const i = (start + k) % futures.size();
179 auto const status = futures[i].wait_for(std::chrono::milliseconds(1));
180 if (status == std::future_status::ready)
181 return { i, futures[i].get() };
182 if (status == std::future_status::deferred && deferred == futures.size())
185 if (deferred != futures.size())
186 return { deferred, futures[deferred].get() };
187 std::this_thread::sleep_for(std::chrono::milliseconds(backoff_ms));
200when_any(std::vector<std::future<void>>& futures) ->
size_t
203 throw std::invalid_argument(
"when_any: empty futures vector");
205 thread_local std::mt19937 rng{ std::random_device{}() };
206 std::uniform_int_distribution<size_t> dist(0, futures.size() - 1);
207 size_t const start = dist(rng);
208 unsigned backoff_ms = 1;
212 size_t deferred = futures.size();
213 for (
size_t k = 0; k < futures.size(); ++k)
215 size_t const i = (start + k) % futures.size();
216 auto const status = futures[i].wait_for(std::chrono::milliseconds(1));
217 if (status == std::future_status::ready)
222 if (status == std::future_status::deferred && deferred == futures.size())
225 if (deferred != futures.size())
227 futures[deferred].get();
230 std::this_thread::sleep_for(std::chrono::milliseconds(backoff_ms));