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-17 04:01:32 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      476006 :     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          476006 :     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          476006 :         return static_cast<bool>(ec_);
      56                 :     }
      57                 : 
      58          475543 :     [[nodiscard]] capy::results<std::size_t> await_resume() const noexcept
      59                 :     {
      60          475543 :         return {ec_, bytes_};
      61                 :     }
      62                 : 
      63          475970 :     auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env)
      64                 :         -> std::coroutine_handle<>
      65                 :     {
      66          475970 :         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          475970 :         if (token_.stop_requested())
      72                 :         {
      73             119 :             ec_ = capy::error::canceled;
      74             119 :             return h;
      75                 :         }
      76          475851 :         cont_.h = h;
      77          475851 :         cont_.owner = env->owner;
      78          475851 :         return static_cast<Derived const*>(this)->dispatch(
      79          475851 :             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          206085 :     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          206085 :     bool await_ready() const noexcept
     109                 :     {
     110                 :         // A pre-set ec_ means the initiator failed before dispatch;
     111                 :         // complete immediately with that error.
     112          206085 :         return static_cast<bool>(ec_);
     113                 :     }
     114                 : 
     115          202861 :     [[nodiscard]] capy::results<Value> await_resume() const noexcept
     116                 :     {
     117          202861 :         return {ec_, std::move(value_)};
     118                 :     }
     119                 : 
     120          206085 :     auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env)
     121                 :         -> std::coroutine_handle<>
     122                 :     {
     123          206085 :         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          206085 :         if (token_.stop_requested())
     127                 :         {
     128              34 :             ec_ = capy::error::canceled;
     129              34 :             return h;
     130                 :         }
     131          206051 :         cont_.h = h;
     132          206051 :         cont_.owner = env->owner;
     133          206051 :         return static_cast<Derived const*>(this)->dispatch(
     134          206051 :             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           17039 :     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           17039 :     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           17039 :         return static_cast<bool>(ec_);
     166                 :     }
     167                 : 
     168            9487 :     [[nodiscard]] capy::results<> await_resume() const noexcept
     169                 :     {
     170            9487 :         return {ec_};
     171                 :     }
     172                 : 
     173           17017 :     auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env)
     174                 :         -> std::coroutine_handle<>
     175                 :     {
     176           17017 :         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           17017 :         if (token_.stop_requested())
     180                 :         {
     181            1064 :             ec_ = capy::error::canceled;
     182            1064 :             return h;
     183                 :         }
     184           15953 :         cont_.h = h;
     185           15953 :         cont_.owner = env->owner;
     186           15953 :         return static_cast<Derived const*>(this)->dispatch(
     187           15953 :             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