0.00% Lines (0/0)
0.00% Functions (0/0)
| TLA | Baseline | Branch | ||||||
|---|---|---|---|---|---|---|---|---|
| Line | Hits | Code | Line | Hits | Code | |||
| 1 | - | // | ||||||
| 2 | - | // Copyright (c) 2026 Steve Gerbino | ||||||
| 3 | - | // | ||||||
| 4 | - | // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||||
| 5 | - | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||||
| 6 | - | // | ||||||
| 7 | - | // Official repository: https://github.com/cppalliance/capy | ||||||
| 8 | - | // | ||||||
| 9 | - | |||||||
| 10 | - | #ifndef BOOST_CAPY_DETAIL_IO_RESULT_COMBINATORS_HPP | ||||||
| 11 | - | #define BOOST_CAPY_DETAIL_IO_RESULT_COMBINATORS_HPP | ||||||
| 12 | - | |||||||
| 13 | - | #include <boost/capy/concept/io_awaitable.hpp> | ||||||
| 14 | - | #include <boost/capy/io_result.hpp> | ||||||
| 15 | - | |||||||
| 16 | - | #include <system_error> | ||||||
| 17 | - | #include <tuple> | ||||||
| 18 | - | #include <type_traits> | ||||||
| 19 | - | #include <utility> | ||||||
| 20 | - | |||||||
| 21 | - | namespace boost { | ||||||
| 22 | - | namespace capy { | ||||||
| 23 | - | namespace detail { | ||||||
| 24 | - | |||||||
| 25 | - | /// True when every awaitable in the pack returns an io_result. | ||||||
| 26 | - | template<typename... As> | ||||||
| 27 | - | concept all_io_result_awaitables = | ||||||
| 28 | - | (is_io_result_v<awaitable_result_t<As>> && ...); | ||||||
| 29 | - | |||||||
| 30 | - | /// True when the io_result-aware when_all overload should be used. | ||||||
| 31 | - | template<typename... As> | ||||||
| 32 | - | concept when_all_io_eligible = | ||||||
| 33 | - | (sizeof...(As) > 0) | ||||||
| 34 | - | && all_io_result_awaitables<As...>; | ||||||
| 35 | - | |||||||
| 36 | - | /// True when the io_result-aware when_any overload should be used. | ||||||
| 37 | - | template<typename... As> | ||||||
| 38 | - | concept when_any_io_eligible = | ||||||
| 39 | - | (sizeof...(As) > 0) | ||||||
| 40 | - | && all_io_result_awaitables<As...>; | ||||||
| 41 | - | |||||||
| 42 | - | /// Map an io_result specialization to its contributed payload type. | ||||||
| 43 | - | /// | ||||||
| 44 | - | /// io_result<T> -> T (unwrap single) | ||||||
| 45 | - | /// io_result<Ts...> -> tuple<Ts...> (zero, two, or more) | ||||||
| 46 | - | template<typename IoResult> | ||||||
| 47 | - | struct io_result_payload; | ||||||
| 48 | - | |||||||
| 49 | - | template<typename T> | ||||||
| 50 | - | struct io_result_payload<io_result<T>> | ||||||
| 51 | - | { | ||||||
| 52 | - | using type = T; | ||||||
| 53 | - | }; | ||||||
| 54 | - | |||||||
| 55 | - | template<typename... Ts> | ||||||
| 56 | - | struct io_result_payload<io_result<Ts...>> | ||||||
| 57 | - | { | ||||||
| 58 | - | using type = std::tuple<Ts...>; | ||||||
| 59 | - | }; | ||||||
| 60 | - | |||||||
| 61 | - | template<typename IoResult> | ||||||
| 62 | - | using io_result_payload_t = | ||||||
| 63 | - | typename io_result_payload<IoResult>::type; | ||||||
| 64 | - | |||||||
| 65 | - | /// Extract the payload value(s) from an io_result, | ||||||
| 66 | - | /// matching the type produced by io_result_payload_t. | ||||||
| 67 | - | template<typename T> | ||||||
| 68 | - | T | ||||||
| DCB | 69 | - | 107 | extract_io_payload(io_result<T>&& r) | ||||
| 70 | - | { | ||||||
| DCB | 71 | - | 107 | return std::get<1>(std::move(r)); | ||||
| 72 | - | } | ||||||
| 73 | - | |||||||
| 74 | - | template<typename... Ts> | ||||||
| 75 | - | std::tuple<Ts...> | ||||||
| DCB | 76 | - | 55 | extract_io_payload(io_result<Ts...>&& r) | ||||
| 77 | - | { | ||||||
| DCB | 78 | - | 61 | return [&]<std::size_t... Is>(std::index_sequence<Is...>) { | ||||
| DCB | 79 | - | 55 | return std::tuple<Ts...>(std::get<Is + 1>(std::move(r))...); | ||||
| DCB | 80 | - | 56 | }(std::index_sequence_for<Ts...>{}); | ||||
| 81 | - | } | ||||||
| 82 | - | |||||||
| 83 | - | /// Reconstruct a success io_result from a payload extracted by when_any. | ||||||
| 84 | - | template<typename IoResult> | ||||||
| 85 | - | struct io_result_from_payload; | ||||||
| 86 | - | |||||||
| 87 | - | template<typename T> | ||||||
| 88 | - | struct io_result_from_payload<io_result<T>> | ||||||
| 89 | - | { | ||||||
| 90 | - | static io_result<T> apply(T t) | ||||||
| 91 | - | { | ||||||
| 92 | - | return io_result<T>{std::error_code(), std::move(t)}; | ||||||
| 93 | - | } | ||||||
| 94 | - | }; | ||||||
| 95 | - | |||||||
| 96 | - | template<typename... Ts> | ||||||
| 97 | - | struct io_result_from_payload<io_result<Ts...>> | ||||||
| 98 | - | { | ||||||
| 99 | - | static io_result<Ts...> apply(std::tuple<Ts...> t) | ||||||
| 100 | - | { | ||||||
| 101 | - | return std::tuple_cat( | ||||||
| 102 | - | std::tuple<std::error_code>(), std::move(t)); | ||||||
| 103 | - | } | ||||||
| 104 | - | }; | ||||||
| 105 | - | |||||||
| 106 | - | /// Build the outer io_result for when_all from a tuple of child io_results. | ||||||
| 107 | - | template<typename ResultType, typename Tuple, std::size_t... Is> | ||||||
| 108 | - | ResultType | ||||||
| DCB | 109 | - | 50 | build_when_all_io_result_impl(Tuple&& results, std::index_sequence<Is...>) | ||||
| 110 | - | { | ||||||
| DCB | 111 | - | 50 | std::error_code ec; | ||||
| DCB | 112 | - | 109 | (void)((std::get<0>(std::get<Is>(results)) && !ec | ||||
| DCB | 113 | - | 23 | ? (ec = std::get<0>(std::get<Is>(results)), true) | ||||
| DCB | 114 | - | 36 | : false) || ...); | ||||
| 115 | - | |||||||
| DCB | 116 | - | 141 | return ResultType{ec, extract_io_payload( | ||||
| DCB | 117 | - | 147 | std::move(std::get<Is>(results)))...}; | ||||
| DCB | 118 | - | 20 | } | ||||
| 119 | - | |||||||
| 120 | - | template<typename ResultType, typename... IoResults> | ||||||
| 121 | - | ResultType | ||||||
| DCB | 122 | - | 50 | build_when_all_io_result(std::tuple<IoResults...>&& results) | ||||
| 123 | - | { | ||||||
| 124 | - | return build_when_all_io_result_impl<ResultType>( | ||||||
| DCB | 125 | - | 50 | std::move(results), | ||||
| DCB | 126 | - | 50 | std::index_sequence_for<IoResults...>{}); | ||||
| 127 | - | } | ||||||
| 128 | - | |||||||
| 129 | - | } // namespace detail | ||||||
| 130 | - | } // namespace capy | ||||||
| 131 | - | } // namespace boost | ||||||
| 132 | - | |||||||
| 133 | - | #endif | ||||||