LCOV - code coverage report
Current view: top level - boost/capy - io_result.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 5 5
Test Date: 2026-01-23 10:17:56 Functions: 100.0 % 9 9

            Line data    Source code
       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
        

Generated by: LCOV version 2.3