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