79 -> std::future<std::tuple<detail::future_value_type_t<std::decay_t<Futures>>...>>
81 using result_tuple = std::tuple<detail::future_value_type_t<std::decay_t<Futures>>...>;
83 auto promise = std::make_shared<std::promise<result_tuple>>();
84 auto result_future = promise->get_future();
87 auto futures_tuple = std::make_shared<std::tuple<std::decay_t<Futures>...>>(
88 std::forward<Futures>(futures)...);
91 std::thread([promise, futures_tuple]()
mutable {
95 std::make_index_sequence<
sizeof...(Futures)>{},
98 promise->set_value(std::move(results));
100 promise->set_exception(std::current_exception());
104 return result_future;
141auto when_any(std::vector<std::future<T>>&& futures)
144 if (futures.empty()) {
145 std::promise<T> promise;
146 promise.set_exception(
147 std::make_exception_ptr(std::invalid_argument(
"Empty futures vector"))
149 return promise.get_future();
152 auto promise = std::make_shared<std::promise<T>>();
153 auto result_future = promise->get_future();
154 auto completed = std::make_shared<std::atomic<bool>>(
false);
155 auto futures_ptr = std::make_shared<std::vector<std::future<T>>>(std::move(futures));
158 for (std::size_t i = 0; i < futures_ptr->size(); ++i) {
159 std::thread([promise,
completed, futures_ptr, i]() {
161 auto& future = (*futures_ptr)[i];
164 bool expected =
false;
165 if (
completed->compare_exchange_strong(expected,
true)) {
166 promise->set_value(std::move(
result));
169 bool expected =
false;
170 if (
completed->compare_exchange_strong(expected,
true)) {
171 promise->set_exception(std::current_exception());
177 return result_future;
183inline auto when_any(std::vector<std::future<void>>&& futures)
186 if (futures.empty()) {
187 std::promise<void> promise;
188 promise.set_exception(
189 std::make_exception_ptr(std::invalid_argument(
"Empty futures vector"))
191 return promise.get_future();
194 auto promise = std::make_shared<std::promise<void>>();
195 auto result_future = promise->get_future();
196 auto completed = std::make_shared<std::atomic<bool>>(
false);
197 auto futures_ptr = std::make_shared<std::vector<std::future<void>>>(std::move(futures));
199 for (std::size_t i = 0; i < futures_ptr->size(); ++i) {
200 std::thread([promise,
completed, futures_ptr, i]() {
202 (*futures_ptr)[i].get();
204 bool expected =
false;
205 if (
completed->compare_exchange_strong(expected,
true)) {
206 promise->set_value();
209 bool expected =
false;
210 if (
completed->compare_exchange_strong(expected,
true)) {
211 promise->set_exception(std::current_exception());
217 return result_future;
241 -> std::future<std::pair<std::size_t, T>>
243 if (futures.empty()) {
244 std::promise<std::pair<std::size_t, T>> promise;
245 promise.set_exception(
246 std::make_exception_ptr(std::invalid_argument(
"Empty futures vector"))
248 return promise.get_future();
251 auto promise = std::make_shared<std::promise<std::pair<std::size_t, T>>>();
252 auto result_future = promise->get_future();
253 auto completed = std::make_shared<std::atomic<bool>>(
false);
254 auto futures_ptr = std::make_shared<std::vector<std::future<T>>>(std::move(futures));
256 for (std::size_t i = 0; i < futures_ptr->size(); ++i) {
257 std::thread([promise,
completed, futures_ptr, i]() {
259 auto& future = (*futures_ptr)[i];
262 bool expected =
false;
263 if (
completed->compare_exchange_strong(expected,
true)) {
264 promise->set_value(std::make_pair(i, std::move(
result)));
267 bool expected =
false;
268 if (
completed->compare_exchange_strong(expected,
true)) {
269 promise->set_exception(std::current_exception());
275 return result_future;