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 % 42 42
Test Date: 2026-10-20 22:34:27 Functions: 100.0 % 427 427

           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/continuation.hpp>
      15                 : #include <boost/capy/results.hpp>
      16                 : #include <boost/capy/ex/executor_ref.hpp>
      17                 : #include <boost/capy/ex/await_context.hpp>
      18                 : 
      19                 : #include <coroutine>
      20                 : #include <cstddef>
      21                 : #include <stop_token>
      22                 : #include <system_error>
      23                 : 
      24                 : namespace boost::corosio::detail {
      25                 : 
      26                 : /* CRTP base for awaitables that return results<std::size_t>.
      27                 : 
      28                 :    Derived classes must provide:
      29                 : 
      30                 :      std::coroutine_handle<> dispatch(
      31                 :          capy::continuation& cont,
      32                 :          capy::executor_ref ex) const;
      33                 : 
      34                 :    which forwards to the backend implementation method, passing
      35                 :    token_, &ec_, and &bytes_ as the cancellation/output parameters.
      36                 : */
      37                 : template<class Derived>
      38                 : class bytes_op_base
      39                 : {
      40                 :     friend Derived;
      41 HIT      466655 :     bytes_op_base() = default;
      42                 : 
      43                 : public:
      44                 :     std::stop_token token_;
      45                 :     mutable std::error_code ec_;
      46                 :     mutable std::size_t bytes_ = 0;
      47                 :     // Lives in the awaiting frame until resumption, so a completion
      48                 :     // posted through an executor never shares the object's state.
      49                 :     mutable capy::continuation cont_;
      50                 : 
      51          466655 :     bool await_ready() const noexcept
      52                 :     {
      53                 :         // A pre-set ec_ means the initiator failed before dispatch
      54                 :         // (e.g. a closed object); complete immediately with that error.
      55          466655 :         return static_cast<bool>(ec_);
      56                 :     }
      57                 : 
      58          466186 :     [[nodiscard]] capy::results<std::size_t> await_resume() const noexcept
      59                 :     {
      60          466186 :         return {ec_, bytes_};
      61                 :     }
      62                 : 
      63          466619 :     auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env)
      64                 :         -> std::coroutine_handle<>
      65                 :     {
      66          466619 :         token_ = env->stop_token;
      67                 :         // A pre-stopped token short-circuits before dispatch so no I/O
      68                 :         // is performed. A stop landing after dispatch is decoded by the
      69                 :         // backend, and a completed transfer is reported verbatim: the
      70                 :         // stream contracts forbid discarding the byte count.
      71          466619 :         if (token_.stop_requested())
      72                 :         {
      73             129 :             ec_ = capy::error::canceled;
      74             129 :             return h;
      75                 :         }
      76          466490 :         cont_.h = h;
      77          466490 :         cont_.owner = env->owner;
      78          466490 :         return static_cast<Derived const*>(this)->dispatch(
      79          466490 :             cont_, env->executor);
      80                 :     }
      81                 : };
      82                 : 
      83                 : /* CRTP base for awaitables that return results<Value> for a
      84                 :    moved-out result object (e.g. the resolver's result lists).
      85                 : 
      86                 :    Derived classes must provide:
      87                 : 
      88                 :      std::coroutine_handle<> dispatch(
      89                 :          capy::continuation& cont,
      90                 :          capy::executor_ref ex) const;
      91                 : 
      92                 :    which forwards to the backend implementation method, passing
      93                 :    token_, &ec_, and &value_ as the cancellation/output parameters.
      94                 : */
      95                 : template<class Derived, class Value>
      96                 : class value_op_base
      97                 : {
      98                 :     friend Derived;
      99          206171 :     value_op_base() = default;
     100                 : 
     101                 : public:
     102                 :     std::stop_token token_;
     103                 :     mutable std::error_code ec_;
     104                 :     mutable Value value_{};
     105                 :     // See bytes_op_base::cont_.
     106                 :     mutable capy::continuation cont_;
     107                 : 
     108          206171 :     bool await_ready() const noexcept
     109                 :     {
     110                 :         // A pre-set ec_ means the initiator failed before dispatch;
     111                 :         // complete immediately with that error.
     112          206171 :         return static_cast<bool>(ec_);
     113                 :     }
     114                 : 
     115          202943 :     [[nodiscard]] capy::results<Value> await_resume() const noexcept
     116                 :     {
     117          202943 :         return {ec_, std::move(value_)};
     118                 :     }
     119                 : 
     120          206171 :     auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env)
     121                 :         -> std::coroutine_handle<>
     122                 :     {
     123          206171 :         token_ = env->stop_token;
     124                 :         // A pre-stopped token short-circuits before dispatch; a stop
     125                 :         // landing after dispatch leaves the completed result intact.
     126          206171 :         if (token_.stop_requested())
     127                 :         {
     128              31 :             ec_ = capy::error::canceled;
     129              31 :             return h;
     130                 :         }
     131          206140 :         cont_.h = h;
     132          206140 :         cont_.owner = env->owner;
     133          206140 :         return static_cast<Derived const*>(this)->dispatch(
     134          206140 :             cont_, env->executor);
     135                 :     }
     136                 : };
     137                 : 
     138                 : /* CRTP base for awaitables that return results<>.
     139                 : 
     140                 :    Derived classes must provide:
     141                 : 
     142                 :      std::coroutine_handle<> dispatch(
     143                 :          capy::continuation& cont,
     144                 :          capy::executor_ref ex) const;
     145                 : 
     146                 :    which forwards to the backend implementation method, passing
     147                 :    token_ and &ec_ as the cancellation/output parameters.
     148                 : */
     149                 : template<class Derived>
     150                 : class void_op_base
     151                 : {
     152                 :     friend Derived;
     153           16628 :     void_op_base() = default;
     154                 : 
     155                 : public:
     156                 :     std::stop_token token_;
     157                 :     mutable std::error_code ec_;
     158                 :     // See bytes_op_base::cont_.
     159                 :     mutable capy::continuation cont_;
     160                 : 
     161           16628 :     bool await_ready() const noexcept
     162                 :     {
     163                 :         // A pre-set ec_ means the initiator failed before dispatch
     164                 :         // (e.g. auto-open); complete immediately with that error.
     165           16628 :         return static_cast<bool>(ec_);
     166                 :     }
     167                 : 
     168            9290 :     [[nodiscard]] capy::results<> await_resume() const noexcept
     169                 :     {
     170            9290 :         return {ec_};
     171                 :     }
     172                 : 
     173           16606 :     auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env)
     174                 :         -> std::coroutine_handle<>
     175                 :     {
     176           16606 :         token_ = env->stop_token;
     177                 :         // A pre-stopped token short-circuits before dispatch; a stop
     178                 :         // landing after dispatch leaves the completed result intact.
     179           16606 :         if (token_.stop_requested())
     180                 :         {
     181            1059 :             ec_ = capy::error::canceled;
     182            1059 :             return h;
     183                 :         }
     184           15547 :         cont_.h = h;
     185           15547 :         cont_.owner = env->owner;
     186           15547 :         return static_cast<Derived const*>(this)->dispatch(
     187           15547 :             cont_, env->executor);
     188                 :     }
     189                 : };
     190                 : 
     191                 : } // namespace boost::corosio::detail
     192                 : 
     193                 : #endif // BOOST_COROSIO_DETAIL_OP_BASE_HPP
        

Generated by: LCOV version 2.3