LCOV - code coverage report
Current view: top level - corosio/detail - op_base.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 33 33
Test Date: 2026-09-25 22:49:29 Functions: 100.0 % 399 399

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2026 Michael Vandeberg
       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/corosio
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_COROSIO_DETAIL_OP_BASE_HPP
      11                 : #define BOOST_COROSIO_DETAIL_OP_BASE_HPP
      12                 : 
      13                 : #include <boost/capy/error.hpp>
      14                 : #include <boost/capy/io_result.hpp>
      15                 : #include <boost/capy/ex/executor_ref.hpp>
      16                 : #include <boost/capy/ex/io_env.hpp>
      17                 : 
      18                 : #include <coroutine>
      19                 : #include <cstddef>
      20                 : #include <stop_token>
      21                 : #include <system_error>
      22                 : 
      23                 : namespace boost::corosio::detail {
      24                 : 
      25                 : /* CRTP base for awaitables that return io_result<std::size_t>.
      26                 : 
      27                 :    Derived classes must provide:
      28                 : 
      29                 :      std::coroutine_handle<> dispatch(
      30                 :          std::coroutine_handle<> h,
      31                 :          capy::executor_ref ex) const;
      32                 : 
      33                 :    which forwards to the backend implementation method, passing
      34                 :    token_, &ec_, and &bytes_ as the cancellation/output parameters.
      35                 : */
      36                 : template<class Derived>
      37                 : class bytes_op_base
      38                 : {
      39                 :     friend Derived;
      40 HIT      441972 :     bytes_op_base() = default;
      41                 : 
      42                 : public:
      43                 :     std::stop_token token_;
      44                 :     mutable std::error_code ec_;
      45                 :     mutable std::size_t bytes_ = 0;
      46                 : 
      47          441972 :     bool await_ready() const noexcept
      48                 :     {
      49                 :         // A pre-set ec_ means the initiator failed before dispatch
      50                 :         // (e.g. a closed object); complete immediately with that error.
      51          441972 :         return static_cast<bool>(ec_);
      52                 :     }
      53                 : 
      54          441937 :     [[nodiscard]] capy::io_result<std::size_t> await_resume() const noexcept
      55                 :     {
      56          441937 :         return {ec_, bytes_};
      57                 :     }
      58                 : 
      59          441936 :     auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
      60                 :         -> std::coroutine_handle<>
      61                 :     {
      62          441936 :         token_ = env->stop_token;
      63                 :         // A pre-stopped token short-circuits before dispatch so no I/O
      64                 :         // is performed. A stop landing after dispatch is decoded by the
      65                 :         // backend, and a completed transfer is reported verbatim: the
      66                 :         // stream contracts forbid discarding the byte count.
      67          441936 :         if (token_.stop_requested())
      68                 :         {
      69              73 :             ec_ = capy::error::canceled;
      70              73 :             return h;
      71                 :         }
      72          441863 :         return static_cast<Derived const*>(this)->dispatch(h, env->executor);
      73                 :     }
      74                 : };
      75                 : 
      76                 : /* CRTP base for awaitables that return io_result<Value> for a
      77                 :    moved-out result object (e.g. the resolver's result lists).
      78                 : 
      79                 :    Derived classes must provide:
      80                 : 
      81                 :      std::coroutine_handle<> dispatch(
      82                 :          std::coroutine_handle<> h,
      83                 :          capy::executor_ref ex) const;
      84                 : 
      85                 :    which forwards to the backend implementation method, passing
      86                 :    token_, &ec_, and &value_ as the cancellation/output parameters.
      87                 : */
      88                 : template<class Derived, class Value>
      89                 : class value_op_base
      90                 : {
      91                 :     friend Derived;
      92            1202 :     value_op_base() = default;
      93                 : 
      94                 : public:
      95                 :     std::stop_token token_;
      96                 :     mutable std::error_code ec_;
      97                 :     mutable Value value_{};
      98                 : 
      99            1202 :     bool await_ready() const noexcept
     100                 :     {
     101                 :         // A pre-set ec_ means the initiator failed before dispatch;
     102                 :         // complete immediately with that error.
     103            1202 :         return static_cast<bool>(ec_);
     104                 :     }
     105                 : 
     106            1188 :     [[nodiscard]] capy::io_result<Value> await_resume() const noexcept
     107                 :     {
     108            1188 :         return {ec_, std::move(value_)};
     109                 :     }
     110                 : 
     111            1202 :     auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
     112                 :         -> std::coroutine_handle<>
     113                 :     {
     114            1202 :         token_ = env->stop_token;
     115                 :         // A pre-stopped token short-circuits before dispatch; a stop
     116                 :         // landing after dispatch leaves the completed result intact.
     117            1202 :         if (token_.stop_requested())
     118                 :         {
     119              42 :             ec_ = capy::error::canceled;
     120              42 :             return h;
     121                 :         }
     122            1160 :         return static_cast<Derived const*>(this)->dispatch(h, env->executor);
     123                 :     }
     124                 : };
     125                 : 
     126                 : /* CRTP base for awaitables that return io_result<>.
     127                 : 
     128                 :    Derived classes must provide:
     129                 : 
     130                 :      std::coroutine_handle<> dispatch(
     131                 :          std::coroutine_handle<> h,
     132                 :          capy::executor_ref ex) const;
     133                 : 
     134                 :    which forwards to the backend implementation method, passing
     135                 :    token_ and &ec_ as the cancellation/output parameters.
     136                 : */
     137                 : template<class Derived>
     138                 : class void_op_base
     139                 : {
     140                 :     friend Derived;
     141            9130 :     void_op_base() = default;
     142                 : 
     143                 : public:
     144                 :     std::stop_token token_;
     145                 :     mutable std::error_code ec_;
     146                 : 
     147            9130 :     bool await_ready() const noexcept
     148                 :     {
     149                 :         // A pre-set ec_ means the initiator failed before dispatch
     150                 :         // (e.g. auto-open); complete immediately with that error.
     151            9130 :         return static_cast<bool>(ec_);
     152                 :     }
     153                 : 
     154            4643 :     [[nodiscard]] capy::io_result<> await_resume() const noexcept
     155                 :     {
     156            4643 :         return {ec_};
     157                 :     }
     158                 : 
     159            9108 :     auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
     160                 :         -> std::coroutine_handle<>
     161                 :     {
     162            9108 :         token_ = env->stop_token;
     163                 :         // A pre-stopped token short-circuits before dispatch; a stop
     164                 :         // landing after dispatch leaves the completed result intact.
     165            9108 :         if (token_.stop_requested())
     166                 :         {
     167              51 :             ec_ = capy::error::canceled;
     168              51 :             return h;
     169                 :         }
     170            9057 :         return static_cast<Derived const*>(this)->dispatch(h, env->executor);
     171                 :     }
     172                 : };
     173                 : 
     174                 : } // namespace boost::corosio::detail
     175                 : 
     176                 : #endif // BOOST_COROSIO_DETAIL_OP_BASE_HPP
        

Generated by: LCOV version 2.3