include/boost/capy/io_result.hpp

100.0% Lines (101/101) 100.0% List of functions (26/26)
f(x) Functions (26)
Function Calls Lines Blocks
boost::capy::io_result<>::io_result() :52 674x 100.0% 100.0% boost::capy::io_result<int, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool>::io_result() :52 1x 100.0% 100.0% boost::capy::io_result<int>::io_result() :52 3x 100.0% 100.0% boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::io_result() :52 1x 100.0% 100.0% boost::capy::io_result<unsigned long>::io_result() :52 71x 100.0% 100.0% boost::capy::io_result<>::io_result(std::error_code) :55 337x 100.0% 100.0% boost::capy::io_result<boost::capy::async_mutex::lock_guard>::io_result(std::error_code, boost::capy::async_mutex::lock_guard) :55 4x 100.0% 100.0% boost::capy::io_result<int, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::io_result(std::error_code, int, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) :55 1x 100.0% 100.0% boost::capy::io_result<int, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool>::io_result(std::error_code, int, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool) :55 1x 100.0% 100.0% boost::capy::io_result<int, double>::io_result(std::error_code, int, double) :55 4x 100.0% 100.0% boost::capy::io_result<int, int, int>::io_result(std::error_code, int, int, int) :55 3x 100.0% 100.0% boost::capy::io_result<int>::io_result(std::error_code, int) :55 3x 100.0% 100.0% boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::io_result(std::error_code, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) :55 8x 100.0% 100.0% boost::capy::io_result<std::span<boost::capy::const_buffer, 18446744073709551615ul> >::io_result(std::error_code, std::span<boost::capy::const_buffer, 18446744073709551615ul>) :55 550x 100.0% 100.0% boost::capy::io_result<std::tuple<>, std::tuple<> >::io_result(std::error_code, std::tuple<>, std::tuple<>) :55 18x 100.0% 100.0% boost::capy::io_result<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::io_result(std::error_code, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) :55 1x 100.0% 100.0% boost::capy::io_result<std::vector<unsigned long, std::allocator<unsigned long> > >::io_result(std::error_code, std::vector<unsigned long, std::allocator<unsigned long> >) :55 8x 100.0% 100.0% boost::capy::io_result<std::vector<unsigned long, std::allocator<unsigned long> >, unsigned long>::io_result(std::error_code, std::vector<unsigned long, std::allocator<unsigned long> >, unsigned long) :55 1x 100.0% 100.0% boost::capy::io_result<unsigned long, int>::io_result(std::error_code, unsigned long, int) :55 1x 100.0% 100.0% boost::capy::io_result<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::io_result(std::error_code, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) :55 1x 100.0% 100.0% boost::capy::io_result<unsigned long, std::tuple<> >::io_result(std::error_code, unsigned long, std::tuple<>) :55 1x 100.0% 100.0% boost::capy::io_result<unsigned long, std::tuple<unsigned long, int> >::io_result(std::error_code, unsigned long, std::tuple<unsigned long, int>) :55 1x 100.0% 100.0% boost::capy::io_result<unsigned long, unsigned long, unsigned long>::io_result(std::error_code, unsigned long, unsigned long, unsigned long) :55 2x 100.0% 100.0% boost::capy::io_result<unsigned long, unsigned long>::io_result(std::error_code, unsigned long, unsigned long) :55 7x 100.0% 100.0% boost::capy::io_result<unsigned long>::io_result(std::error_code, unsigned long) :55 4906x 100.0% 100.0% decltype(auto) boost::capy::io_result<>::get<0ul>() && :79 72x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.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 <system_error>
15
16 #include <cstddef>
17 #include <tuple>
18 #include <type_traits>
19 #include <utility>
20
21 namespace boost {
22 namespace capy {
23
24 /** Result type for asynchronous I/O operations.
25
26 This template provides a unified result type for async operations,
27 always containing a `std::error_code` plus optional additional
28 values. It supports structured bindings via the tuple protocol.
29
30 @par Example
31 @code
32 auto [ec, n] = co_await s.read_some(buf);
33 if (ec) { ... }
34 @endcode
35
36 @note Payload members are only meaningful when
37 `ec` does not indicate an error.
38
39 @tparam Ts Ordered payload types following the leading
40 `std::error_code`.
41 */
42 template<class... Ts>
43 struct [[nodiscard]] io_result
44 {
45 /// The error code from the operation.
46 std::error_code ec;
47
48 /// The payload values. Unspecified when `ec` is set.
49 std::tuple<Ts...> values;
50
51 /// Construct a default io_result.
52 750x io_result() = default;
53
54 /// Construct from an error code and payload values.
55 5858x io_result(std::error_code ec_, Ts... ts)
56 5858x : ec(ec_)
57 5521x , values(std::move(ts)...)
58 {
59 5858x }
60
61 /// @cond
62 template<std::size_t I>
63 decltype(auto) get() & noexcept
64 {
65 static_assert(I < 1 + sizeof...(Ts), "index out of range");
66 if constexpr (I == 0) return (ec);
67 else return std::get<I - 1>(values);
68 }
69
70 template<std::size_t I>
71 decltype(auto) get() const& noexcept
72 {
73 static_assert(I < 1 + sizeof...(Ts), "index out of range");
74 if constexpr (I == 0) return (ec);
75 else return std::get<I - 1>(values);
76 }
77
78 template<std::size_t I>
79 11471x decltype(auto) get() && noexcept
80 {
81 static_assert(I < 1 + sizeof...(Ts), "index out of range");
82 6188x if constexpr (I == 0) return std::move(ec);
83 5283x else return std::get<I - 1>(std::move(values));
84 }
85 /// @endcond
86 };
87
88 /// @cond
89 template<std::size_t I, class... Ts>
90 decltype(auto) get(io_result<Ts...>& r) noexcept
91 {
92 return r.template get<I>();
93 }
94
95 template<std::size_t I, class... Ts>
96 decltype(auto) get(io_result<Ts...> const& r) noexcept
97 {
98 return r.template get<I>();
99 }
100
101 template<std::size_t I, class... Ts>
102 decltype(auto) get(io_result<Ts...>&& r) noexcept
103 {
104 return std::move(r).template get<I>();
105 }
106 /// @endcond
107
108 } // namespace capy
109 } // namespace boost
110
111 // Tuple protocol for structured bindings
112 namespace std {
113
114 template<class... Ts>
115 struct tuple_size<boost::capy::io_result<Ts...>>
116 : std::integral_constant<std::size_t, 1 + sizeof...(Ts)> {};
117
118 template<class... Ts>
119 struct tuple_element<0, boost::capy::io_result<Ts...>>
120 {
121 using type = std::error_code;
122 };
123
124 template<std::size_t I, class... Ts>
125 struct tuple_element<I, boost::capy::io_result<Ts...>>
126 {
127 using type = std::tuple_element_t<I - 1, std::tuple<Ts...>>;
128 };
129
130 } // namespace std
131
132 #endif // BOOST_CAPY_IO_RESULT_HPP
133