include/boost/capy/detail/io_result_combinators.hpp

89.2% Lines (66/74) 100.0% List of functions (14/15)
f(x) Functions (15)
Function Calls Lines Blocks
<unknown function 78> :78 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > boost::capy::detail::extract_io_payload<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) :78 4x 100.0% 100.0% std::vector<unsigned long, std::allocator<unsigned long> > boost::capy::detail::extract_io_payload<std::vector<unsigned long, std::allocator<unsigned long> > >(boost::capy::io_result<std::vector<unsigned long, std::allocator<unsigned long> > >&&) :78 1x 100.0% 100.0% unsigned long boost::capy::detail::extract_io_payload<unsigned long>(boost::capy::io_result<unsigned long>&&) :78 42x 100.0% 100.0% std::tuple<> boost::capy::detail::extract_io_payload<>(boost::capy::io_result<>&&) :85 37x 100.0% 100.0% std::tuple<unsigned long, int> boost::capy::detail::extract_io_payload<unsigned long, int>(boost::capy::io_result<unsigned long, int>&&) :85 1x 100.0% 100.0% boost::capy::io_result<std::tuple<>, std::tuple<> > boost::capy::detail::build_when_all_io_result_impl<boost::capy::io_result<std::tuple<>, std::tuple<> >, std::tuple<boost::capy::io_result<>, boost::capy::io_result<> >, 0ul, 1ul>(std::tuple<boost::capy::io_result<>, boost::capy::io_result<> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :117 18x 100.0% 86.0% boost::capy::io_result<std::vector<unsigned long, std::allocator<unsigned long> >, unsigned long> boost::capy::detail::build_when_all_io_result_impl<boost::capy::io_result<std::vector<unsigned long, std::allocator<unsigned long> >, unsigned long>, std::tuple<boost::capy::io_result<std::vector<unsigned long, std::allocator<unsigned long> > >, boost::capy::io_result<unsigned long> >, 0ul, 1ul>(std::tuple<boost::capy::io_result<std::vector<unsigned long, std::allocator<unsigned long> > >, boost::capy::io_result<unsigned long> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :117 1x 71.4% 61.0% boost::capy::io_result<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > boost::capy::detail::build_when_all_io_result_impl<boost::capy::io_result<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, 0ul, 1ul>(std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :117 1x 71.4% 61.0% boost::capy::io_result<unsigned long, std::tuple<> > boost::capy::detail::build_when_all_io_result_impl<boost::capy::io_result<unsigned long, std::tuple<> >, std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<> >, 0ul, 1ul>(std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :117 1x 75.0% 68.0% boost::capy::io_result<unsigned long, std::tuple<unsigned long, int> > boost::capy::detail::build_when_all_io_result_impl<boost::capy::io_result<unsigned long, std::tuple<unsigned long, int> >, std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<unsigned long, int> >, 0ul, 1ul>(std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<unsigned long, int> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :117 1x 71.4% 64.0% boost::capy::io_result<unsigned long, unsigned long, unsigned long> boost::capy::detail::build_when_all_io_result_impl<boost::capy::io_result<unsigned long, unsigned long, unsigned long>, std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<unsigned long>, boost::capy::io_result<unsigned long> >, 0ul, 1ul, 2ul>(std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<unsigned long>, boost::capy::io_result<unsigned long> >&&, std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>) :117 2x 100.0% 79.0% boost::capy::io_result<unsigned long, unsigned long> boost::capy::detail::build_when_all_io_result_impl<boost::capy::io_result<unsigned long, unsigned long>, std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<unsigned long> >, 0ul, 1ul>(std::tuple<boost::capy::io_result<unsigned long>, boost::capy::io_result<unsigned long> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :117 7x 100.0% 86.0% boost::capy::io_result<unsigned long> boost::capy::detail::build_when_all_io_result_impl<boost::capy::io_result<unsigned long>, std::tuple<boost::capy::io_result<unsigned long> >, 0ul>(std::tuple<boost::capy::io_result<unsigned long> >&&, std::integer_sequence<unsigned long, 0ul>) :117 5x 100.0% 100.0% boost::capy::io_result<std::tuple<>, std::tuple<> > boost::capy::detail::build_when_all_io_result<boost::capy::io_result<std::tuple<>, std::tuple<> >, boost::capy::io_result<>, boost::capy::io_result<> >(std::tuple<boost::capy::io_result<>, boost::capy::io_result<> >&&) :130 17x 100.0% 100.0%
Line TLA Hits Source 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 template<typename T>
26 struct is_io_result : std::false_type {};
27
28 template<typename... Args>
29 struct is_io_result<io_result<Args...>> : std::true_type {};
30
31 template<typename T>
32 inline constexpr bool is_io_result_v = is_io_result<T>::value;
33
34 /// True when every awaitable in the pack returns an io_result.
35 template<typename... As>
36 concept all_io_result_awaitables =
37 (is_io_result_v<awaitable_result_t<As>> && ...);
38
39 /// True when the io_result-aware when_all overload should be used.
40 template<typename... As>
41 concept when_all_io_eligible =
42 (sizeof...(As) > 0)
43 && all_io_result_awaitables<As...>;
44
45 /// True when the io_result-aware when_any overload should be used.
46 template<typename... As>
47 concept when_any_io_eligible =
48 (sizeof...(As) > 0)
49 && all_io_result_awaitables<As...>;
50
51 /// Map an io_result specialization to its contributed payload type.
52 ///
53 /// io_result<T> -> T (unwrap single)
54 /// io_result<Ts...> -> tuple<Ts...> (zero, two, or more)
55 template<typename IoResult>
56 struct io_result_payload;
57
58 template<typename T>
59 struct io_result_payload<io_result<T>>
60 {
61 using type = T;
62 };
63
64 template<typename... Ts>
65 struct io_result_payload<io_result<Ts...>>
66 {
67 using type = std::tuple<Ts...>;
68 };
69
70 template<typename IoResult>
71 using io_result_payload_t =
72 typename io_result_payload<IoResult>::type;
73
74 /// Extract the payload value(s) from an io_result,
75 /// matching the type produced by io_result_payload_t.
76 template<typename T>
77 T
78 66x extract_io_payload(io_result<T>&& r)
79 {
80 66x return std::get<0>(std::move(r.values));
81 }
82
83 template<typename... Ts>
84 std::tuple<Ts...>
85 38x extract_io_payload(io_result<Ts...>&& r)
86 {
87 38x return std::move(r.values);
88 }
89
90 /// Reconstruct a success io_result from a payload extracted by when_any.
91 template<typename IoResult>
92 struct io_result_from_payload;
93
94 template<typename T>
95 struct io_result_from_payload<io_result<T>>
96 {
97 static io_result<T> apply(T t)
98 {
99 return io_result<T>{{}, std::move(t)};
100 }
101 };
102
103 template<typename... Ts>
104 struct io_result_from_payload<io_result<Ts...>>
105 {
106 static io_result<Ts...> apply(std::tuple<Ts...> t)
107 {
108 return std::apply([](auto&&... args) {
109 return io_result<Ts...>{{}, std::move(args)...};
110 }, std::move(t));
111 }
112 };
113
114 /// Build the outer io_result for when_all from a tuple of child io_results.
115 template<typename ResultType, typename Tuple, std::size_t... Is>
116 ResultType
117 36x build_when_all_io_result_impl(Tuple&& results, std::index_sequence<Is...>)
118 {
119 36x std::error_code ec;
120 71x (void)((std::get<Is>(results).ec && !ec
121 20x ? (ec = std::get<Is>(results).ec, true)
122 15x : false) || ...);
123
124 37x return ResultType{ec, extract_io_payload(
125 106x std::move(std::get<Is>(results)))...};
126 17x }
127
128 template<typename ResultType, typename... IoResults>
129 ResultType
130 36x build_when_all_io_result(std::tuple<IoResults...>&& results)
131 {
132 return build_when_all_io_result_impl<ResultType>(
133 36x std::move(results),
134 36x std::index_sequence_for<IoResults...>{});
135 }
136
137 } // namespace detail
138 } // namespace capy
139 } // namespace boost
140
141 #endif
142