include/boost/capy/detail/io_result_combinators.hpp

100.0% Lines (17/0/17) 96.2% List of functions (25/1/27)
io_result_combinators.hpp
f(x) Functions (27)
Function Calls Lines Blocks
<unknown function 69> :69 int boost::capy::detail::extract_io_payload<int>(std::tuple<std::error_code, int>&&) :69 19x 100.0% 100.0% long long boost::capy::detail::extract_io_payload<long long>(std::tuple<std::error_code, long long>&&) :69 4x 100.0% 100.0% 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> > >(std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&&) :69 9x 100.0% 100.0% std::error_code boost::capy::detail::extract_io_payload<std::error_code>(std::tuple<std::error_code, std::error_code>&&) :69 1x 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> > >(std::tuple<std::error_code, std::vector<unsigned long, std::allocator<unsigned long> > >&&) :69 1x 100.0% 100.0% unsigned long boost::capy::detail::extract_io_payload<unsigned long>(std::tuple<std::error_code, unsigned long>&&) :69 45x 100.0% 100.0% std::tuple<> boost::capy::detail::extract_io_payload<>(std::tuple<std::error_code>&&) :76 52x 100.0% 100.0% std::tuple<unsigned long, int> boost::capy::detail::extract_io_payload<unsigned long, int>(std::tuple<std::error_code, unsigned long, int>&&) :76 1x 100.0% 100.0% auto boost::capy::detail::extract_io_payload<>(std::tuple<std::error_code>&&)::{lambda<unsigned long... $N0>(std::integer_sequence<unsigned long, ($N0)...>)#1}::operator()<>(std::integer_sequence<unsigned long>) const :78 47x 100.0% 100.0% std::tuple<std::error_code, int, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, int, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tuple<std::tuple<std::error_code, int>, std::tuple<std::error_code, int>, std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, 0ul, 1ul, 2ul>(std::tuple<std::tuple<std::error_code, int>, std::tuple<std::error_code, int>, std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&, std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>) :109 2x 75.0% 63.0% std::tuple<std::error_code, int, int> boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, int, int>, std::tuple<std::tuple<std::error_code, int>, std::tuple<std::error_code, int> >, 0ul, 1ul>(std::tuple<std::tuple<std::error_code, int>, std::tuple<std::error_code, int> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :109 3x 100.0% 83.0% std::tuple<std::error_code, int, std::tuple<>, int> boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, int, std::tuple<>, int>, std::tuple<std::tuple<std::error_code, int>, std::tuple<std::error_code>, std::tuple<std::error_code, int> >, 0ul, 1ul, 2ul>(std::tuple<std::tuple<std::error_code, int>, std::tuple<std::error_code>, std::tuple<std::error_code, int> >&&, std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>) :109 2x 75.0% 62.0% std::tuple<std::error_code, long long, long long, long long, long long> boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, long long, long long, long long, long long>, std::tuple<std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long> >, 0ul, 1ul, 2ul, 3ul>(std::tuple<std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long> >&&, std::integer_sequence<unsigned long, 0ul, 1ul, 2ul, 3ul>) :109 1x 75.0% 61.0% std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tuple<std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, 0ul, 1ul, 2ul>(std::tuple<std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&, std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>) :109 1x 71.4% 64.0% std::tuple<std::error_code, std::tuple<>, std::tuple<> > boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, std::tuple<>, std::tuple<> >, std::tuple<std::tuple<std::error_code>, std::tuple<std::error_code> >, 0ul, 1ul>(std::tuple<std::tuple<std::error_code>, std::tuple<std::error_code> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :109 22x 100.0% 83.0% std::tuple<std::error_code, std::tuple<>, std::tuple<>, std::tuple<> > boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, std::tuple<>, std::tuple<>, std::tuple<> >, std::tuple<std::tuple<std::error_code>, std::tuple<std::error_code>, std::tuple<std::error_code> >, 0ul, 1ul, 2ul>(std::tuple<std::tuple<std::error_code>, std::tuple<std::error_code>, std::tuple<std::error_code> >&&, std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>) :109 1x 75.0% 62.0% std::tuple<std::error_code, std::vector<unsigned long, std::allocator<unsigned long> >, unsigned long> boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, std::vector<unsigned long, std::allocator<unsigned long> >, unsigned long>, std::tuple<std::tuple<std::error_code, std::vector<unsigned long, std::allocator<unsigned long> > >, std::tuple<std::error_code, unsigned long> >, 0ul, 1ul>(std::tuple<std::tuple<std::error_code, std::vector<unsigned long, std::allocator<unsigned long> > >, std::tuple<std::error_code, unsigned long> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :109 1x 75.0% 65.0% std::tuple<std::error_code, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, 0ul, 1ul>(std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :109 1x 75.0% 65.0% std::tuple<std::error_code, unsigned long, std::tuple<> > boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, unsigned long, std::tuple<> >, std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code> >, 0ul, 1ul>(std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :109 1x 75.0% 63.0% std::tuple<std::error_code, unsigned long, std::tuple<unsigned long, int> > boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, unsigned long, std::tuple<unsigned long, int> >, std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long, int> >, 0ul, 1ul>(std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long, int> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :109 1x 75.0% 61.0% std::tuple<std::error_code, unsigned long, unsigned long, unsigned long> boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, unsigned long, unsigned long, unsigned long>, std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long> >, 0ul, 1ul, 2ul>(std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long> >&&, std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>) :109 2x 100.0% 76.0% std::tuple<std::error_code, unsigned long, unsigned long> boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, unsigned long, unsigned long>, std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long> >, 0ul, 1ul>(std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long> >&&, std::integer_sequence<unsigned long, 0ul, 1ul>) :109 7x 100.0% 83.0% std::tuple<std::error_code, unsigned long> boost::capy::detail::build_when_all_io_result_impl<std::tuple<std::error_code, unsigned long>, std::tuple<std::tuple<std::error_code, unsigned long> >, 0ul>(std::tuple<std::tuple<std::error_code, unsigned long> >&&, std::integer_sequence<unsigned long, 0ul>) :109 5x 100.0% 100.0% std::tuple<std::error_code, long long, long long, long long, long long> boost::capy::detail::build_when_all_io_result<std::tuple<std::error_code, long long, long long, long long, long long>, std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long> >(std::tuple<std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long>, std::tuple<std::error_code, long long> >&&) :122 1x 100.0% 100.0% std::tuple<std::error_code, std::tuple<>, std::tuple<> > boost::capy::detail::build_when_all_io_result<std::tuple<std::error_code, std::tuple<>, std::tuple<> >, std::tuple<std::error_code>, std::tuple<std::error_code> >(std::tuple<std::tuple<std::error_code>, std::tuple<std::error_code> >&&) :122 17x 100.0% 100.0% std::tuple<std::error_code, unsigned long, unsigned long> boost::capy::detail::build_when_all_io_result<std::tuple<std::error_code, unsigned long, unsigned long>, std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long> >(std::tuple<std::tuple<std::error_code, unsigned long>, std::tuple<std::error_code, unsigned long> >&&) :122 0 0.0% 0.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 /// 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
69 99x extract_io_payload(io_result<T>&& r)
70 {
71 99x return std::get<1>(std::move(r));
72 }
73
74 template<typename... Ts>
75 std::tuple<Ts...>
76 53x extract_io_payload(io_result<Ts...>&& r)
77 {
78 53x return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
79 47x return std::tuple<Ts...>(std::get<Is + 1>(std::move(r))...);
80 54x }(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
109 50x build_when_all_io_result_impl(Tuple&& results, std::index_sequence<Is...>)
110 {
111 50x std::error_code ec;
112 109x (void)((std::get<0>(std::get<Is>(results)) && !ec
113 23x ? (ec = std::get<0>(std::get<Is>(results)), true)
114 36x : false) || ...);
115
116 141x return ResultType{ec, extract_io_payload(
117 147x std::move(std::get<Is>(results)))...};
118 20x }
119
120 template<typename ResultType, typename... IoResults>
121 ResultType
122 50x build_when_all_io_result(std::tuple<IoResults...>&& results)
123 {
124 return build_when_all_io_result_impl<ResultType>(
125 50x std::move(results),
126 50x std::index_sequence_for<IoResults...>{});
127 }
128
129 } // namespace detail
130 } // namespace capy
131 } // namespace boost
132
133 #endif
134