GCC Code Coverage Report


Directory: ./
File: libs/capy/include/boost/capy/io_result.hpp
Date: 2026-01-23 10:17:56
Exec Total Coverage
Lines: 5 5 100.0%
Functions: 0 0 -%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
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_IO_RESULT_HPP
11 #define BOOST_CAPY_IO_RESULT_HPP
12
13 #include <boost/capy/detail/config.hpp>
14 #include <boost/system/error_code.hpp>
15
16 #include <cstddef>
17 #include <tuple>
18 #include <type_traits>
19
20 namespace boost {
21 namespace capy {
22
23 /** Result type for asynchronous I/O operations.
24
25 This template provides a unified result type for async operations,
26 always containing a `system::error_code` plus optional additional
27 values. It supports structured bindings.
28
29 @tparam Args Additional value types beyond the error code.
30
31 @par Usage
32 @code
33 // Error code path (default)
34 auto [ec, n] = co_await s.read_some(buf);
35 if (ec) { ... }
36
37 // Exception path (opt-in)
38 auto n = (co_await s.read_some(buf)).value();
39 @endcode
40 */
41 template<class... Args>
42 struct io_result
43 {
44 static_assert("io_result only supports upt to 3 template arguments");
45 };
46
47 /** Result type for void operations.
48
49 Used by operations like `connect()` that don't return a value
50 beyond success/failure.
51
52 @par Example
53 @code
54 auto [ec] = co_await s.connect(ep);
55 if (ec) { ... }
56
57 // Or with exceptions:
58 (co_await s.connect(ep)).value();
59 @endcode
60 */
61 template<>
62 struct io_result<>
63 {
64 /** The error code from the operation. */
65 system::error_code ec;
66 };
67
68 /** Result type for byte transfer operations.
69
70 Used by operations like `read_some()` and `write_some()` that
71 return the number of bytes transferred.
72
73 @par Example
74 @code
75 auto [ec, n] = co_await s.read_some(buf);
76 if (ec) { ... }
77
78 // Or with exceptions:
79 auto n = (co_await s.read_some(buf)).value();
80 @endcode
81 */
82 template<typename T1>
83 struct io_result<T1>
84 {
85 system::error_code ec;
86 T1 t1{};
87 };
88
89 template<typename T1, typename T2>
90 struct io_result<T1, T2>
91 {
92 system::error_code ec;
93 T1 t1{};
94 T2 t2{};
95 };
96
97 template<typename T1, typename T2, typename T3>
98 struct io_result<T1, T2, T3>
99 {
100 system::error_code ec;
101 T1 t1{};
102 T2 t2{};
103 T3 t3{};
104 };
105
106 //----------------------------------------------------------
107
108 template<std::size_t I, class... Args>
109 constexpr auto&
110 get(io_result<Args...>& r) noexcept
111 {
112 if constexpr(I == 0)
113 return r.ec;
114 else if constexpr(I == 1)
115 return r.t1;
116 else if constexpr(I == 2)
117 return r.t2;
118 else
119 return r.t3;
120 }
121
122 template<std::size_t I, class... Args>
123 constexpr auto const&
124 get(io_result<Args...> const& r) noexcept
125 {
126 if constexpr(I == 0)
127 return r.ec;
128 else if constexpr(I == 1)
129 return r.t1;
130 else if constexpr(I == 2)
131 return r.t2;
132 else
133 return r.t3;
134 }
135
136 template<std::size_t I, class... Args>
137 constexpr auto&&
138 41 get(io_result<Args...>&& r) noexcept
139 {
140 if constexpr(I == 0)
141 20 return std::move(r.ec);
142 else if constexpr(I == 1)
143 19 return std::move(r.t1);
144 else if constexpr(I == 2)
145 1 return std::move(r.t2);
146 else
147 1 return std::move(r.t3);
148 }
149
150 } // namespace capy
151 } // namespace boost
152
153 template<class... Args>
154 struct std::tuple_size<boost::capy::io_result<Args...>>
155 : std::integral_constant<std::size_t, 1 + sizeof...(Args)> {};
156
157 template<class... Args>
158 struct std::tuple_element<0, boost::capy::io_result<Args...>>
159 {
160 using type = boost::system::error_code;
161 };
162
163 template<std::size_t I, class... Args>
164 struct std::tuple_element<I, boost::capy::io_result<Args...>>
165 {
166 using type = std::tuple_element_t<I - 1, std::tuple<Args...>>;
167 };
168
169 #endif
170