Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:53

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // Copyright (c) Lewis Baker
0003 // Licenced under MIT license. See LICENSE.txt for details.
0004 ///////////////////////////////////////////////////////////////////////////////
0005 #ifndef CPPCORO_WHEN_ALL_HPP_INCLUDED
0006 #define CPPCORO_WHEN_ALL_HPP_INCLUDED
0007 
0008 #include <cppcoro/when_all_ready.hpp>
0009 #include <cppcoro/awaitable_traits.hpp>
0010 #include <cppcoro/is_awaitable.hpp>
0011 #include <cppcoro/fmap.hpp>
0012 
0013 #include <cppcoro/detail/unwrap_reference.hpp>
0014 
0015 #include <tuple>
0016 #include <functional>
0017 #include <utility>
0018 #include <vector>
0019 #include <type_traits>
0020 #include <cassert>
0021 
0022 namespace cppcoro
0023 {
0024     //////////
0025     // Variadic when_all()
0026 
0027     template<
0028         typename... AWAITABLES,
0029         std::enable_if_t<
0030             std::conjunction_v<is_awaitable<detail::unwrap_reference_t<std::remove_reference_t<AWAITABLES>>>...>,
0031             int> = 0>
0032     [[nodiscard]] auto when_all(AWAITABLES&&... awaitables)
0033     {
0034         return fmap([](auto&& taskTuple)
0035         {
0036             return std::apply([](auto&&... tasks) {
0037                 return std::make_tuple(static_cast<decltype(tasks)>(tasks).non_void_result()...);
0038             }, static_cast<decltype(taskTuple)>(taskTuple));
0039         }, when_all_ready(std::forward<AWAITABLES>(awaitables)...));
0040     }
0041 
0042     //////////
0043     // when_all() with vector of awaitable
0044 
0045     template<
0046         typename AWAITABLE,
0047         typename RESULT = typename awaitable_traits<detail::unwrap_reference_t<AWAITABLE>>::await_result_t,
0048         std::enable_if_t<std::is_void_v<RESULT>, int> = 0>
0049     [[nodiscard]]
0050     auto when_all(std::vector<AWAITABLE> awaitables)
0051     {
0052         return fmap([](auto&& taskVector) {
0053             for (auto& task : taskVector)
0054             {
0055                 task.result();
0056             }
0057         }, when_all_ready(std::move(awaitables)));
0058     }
0059 
0060     template<
0061         typename AWAITABLE,
0062         typename RESULT = typename awaitable_traits<detail::unwrap_reference_t<AWAITABLE>>::await_result_t,
0063         std::enable_if_t<!std::is_void_v<RESULT>, int> = 0>
0064     [[nodiscard]]
0065     auto when_all(std::vector<AWAITABLE> awaitables)
0066     {
0067         using result_t = std::conditional_t<
0068             std::is_lvalue_reference_v<RESULT>,
0069             std::reference_wrapper<std::remove_reference_t<RESULT>>,
0070             std::remove_reference_t<RESULT>>;
0071 
0072         return fmap([](auto&& taskVector) {
0073             std::vector<result_t> results;
0074             results.reserve(taskVector.size());
0075             for (auto& task : taskVector)
0076             {
0077                 if constexpr (std::is_rvalue_reference_v<decltype(taskVector)>)
0078                 {
0079                     results.emplace_back(std::move(task).result());
0080                 }
0081                 else
0082                 {
0083                     results.emplace_back(task.result());
0084                 }
0085             }
0086             return results;
0087         }, when_all_ready(std::move(awaitables)));
0088     }
0089 }
0090 
0091 #endif