LCOV - code coverage report
Current view: top level - capy - io_result.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 8 8
Test Date: 2026-06-21 16:31:20 Functions: 100.0 % 53 53

           TLA  Line data    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 Whether the payload is meaningful when `ec` is set is
      37                 :         defined by the operation that produced the result. Many I/O
      38                 :         operations report a meaningful partial result alongside `ec`
      39                 :         (for example, the number of bytes transferred before the
      40                 :         condition, as with EOF); others leave it unspecified.
      41                 : 
      42                 :     @tparam Ts Ordered payload types following the leading
      43                 :         `std::error_code`.
      44                 : */
      45                 : template<class... Ts>
      46                 : struct [[nodiscard]] io_result
      47                 : {
      48                 :     /// The error code from the operation.
      49                 :     std::error_code ec;
      50                 : 
      51                 :     /// The payload values. Their meaning when `ec` is set is defined
      52                 :     /// by the producing operation (see the class note).
      53                 :     std::tuple<Ts...> values;
      54                 : 
      55                 :     /// Construct a default io_result.
      56 HIT         759 :     io_result() = default;
      57                 : 
      58                 :     /// Construct from an error code and payload values.
      59            5944 :     io_result(std::error_code ec_, Ts... ts)
      60            5944 :         : ec(ec_)
      61            5603 :         , values(std::move(ts)...)
      62                 :     {
      63            5944 :     }
      64                 : 
      65                 :     /// @cond
      66                 :     template<std::size_t I>
      67                 :     decltype(auto) get() & noexcept
      68                 :     {
      69                 :         static_assert(I < 1 + sizeof...(Ts), "index out of range");
      70                 :         if constexpr (I == 0) return (ec);
      71                 :         else return std::get<I - 1>(values);
      72                 :     }
      73                 : 
      74                 :     template<std::size_t I>
      75                 :     decltype(auto) get() const& noexcept
      76                 :     {
      77                 :         static_assert(I < 1 + sizeof...(Ts), "index out of range");
      78                 :         if constexpr (I == 0) return (ec);
      79                 :         else return std::get<I - 1>(values);
      80                 :     }
      81                 : 
      82                 :     template<std::size_t I>
      83           11622 :     decltype(auto) get() && noexcept
      84                 :     {
      85                 :         static_assert(I < 1 + sizeof...(Ts), "index out of range");
      86            6267 :         if constexpr (I == 0) return std::move(ec);
      87            5355 :         else return std::get<I - 1>(std::move(values));
      88                 :     }
      89                 :     /// @endcond
      90                 : };
      91                 : 
      92                 : /// @cond
      93                 : template<std::size_t I, class... Ts>
      94                 : decltype(auto) get(io_result<Ts...>& r) noexcept
      95                 : {
      96                 :     return r.template get<I>();
      97                 : }
      98                 : 
      99                 : template<std::size_t I, class... Ts>
     100                 : decltype(auto) get(io_result<Ts...> const& r) noexcept
     101                 : {
     102                 :     return r.template get<I>();
     103                 : }
     104                 : 
     105                 : template<std::size_t I, class... Ts>
     106                 : decltype(auto) get(io_result<Ts...>&& r) noexcept
     107                 : {
     108                 :     return std::move(r).template get<I>();
     109                 : }
     110                 : /// @endcond
     111                 : 
     112                 : } // namespace capy
     113                 : } // namespace boost
     114                 : 
     115                 : // Tuple protocol for structured bindings
     116                 : namespace std {
     117                 : 
     118                 : template<class... Ts>
     119                 : struct tuple_size<boost::capy::io_result<Ts...>>
     120                 :     : std::integral_constant<std::size_t, 1 + sizeof...(Ts)> {};
     121                 : 
     122                 : template<class... Ts>
     123                 : struct tuple_element<0, boost::capy::io_result<Ts...>>
     124                 : {
     125                 :     using type = std::error_code;
     126                 : };
     127                 : 
     128                 : template<std::size_t I, class... Ts>
     129                 : struct tuple_element<I, boost::capy::io_result<Ts...>>
     130                 : {
     131                 :     using type = std::tuple_element_t<I - 1, std::tuple<Ts...>>;
     132                 : };
     133                 : 
     134                 : } // namespace std
     135                 : 
     136                 : #endif // BOOST_CAPY_IO_RESULT_HPP
        

Generated by: LCOV version 2.3