100.00% Lines (42/42) 100.00% Functions (12/12)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2026 Michael Vandeberg 2   // Copyright (c) 2026 Michael Vandeberg
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 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) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/cppalliance/corosio 7   // Official repository: https://github.com/cppalliance/corosio
8   // 8   //
9   9  
10   #ifndef BOOST_COROSIO_DETAIL_OP_BASE_HPP 10   #ifndef BOOST_COROSIO_DETAIL_OP_BASE_HPP
11   #define BOOST_COROSIO_DETAIL_OP_BASE_HPP 11   #define BOOST_COROSIO_DETAIL_OP_BASE_HPP
12   12  
13   #include <boost/capy/error.hpp> 13   #include <boost/capy/error.hpp>
14   #include <boost/capy/continuation.hpp> 14   #include <boost/capy/continuation.hpp>
15   #include <boost/capy/results.hpp> 15   #include <boost/capy/results.hpp>
16   #include <boost/capy/ex/executor_ref.hpp> 16   #include <boost/capy/ex/executor_ref.hpp>
17   #include <boost/capy/ex/await_context.hpp> 17   #include <boost/capy/ex/await_context.hpp>
18   18  
19   #include <coroutine> 19   #include <coroutine>
20   #include <cstddef> 20   #include <cstddef>
21   #include <stop_token> 21   #include <stop_token>
22   #include <system_error> 22   #include <system_error>
23   23  
24   namespace boost::corosio::detail { 24   namespace boost::corosio::detail {
25   25  
26   /* CRTP base for awaitables that return results<std::size_t>. 26   /* CRTP base for awaitables that return results<std::size_t>.
27   27  
28   Derived classes must provide: 28   Derived classes must provide:
29   29  
30   std::coroutine_handle<> dispatch( 30   std::coroutine_handle<> dispatch(
31   capy::continuation& cont, 31   capy::continuation& cont,
32   capy::executor_ref ex) const; 32   capy::executor_ref ex) const;
33   33  
34   which forwards to the backend implementation method, passing 34   which forwards to the backend implementation method, passing
35   token_, &ec_, and &bytes_ as the cancellation/output parameters. 35   token_, &ec_, and &bytes_ as the cancellation/output parameters.
36   */ 36   */
37   template<class Derived> 37   template<class Derived>
38   class bytes_op_base 38   class bytes_op_base
39   { 39   {
40   friend Derived; 40   friend Derived;
HITCBC 41   455592 bytes_op_base() = default; 41   444806 bytes_op_base() = default;
42   42  
43   public: 43   public:
44   std::stop_token token_; 44   std::stop_token token_;
45   mutable std::error_code ec_; 45   mutable std::error_code ec_;
46   mutable std::size_t bytes_ = 0; 46   mutable std::size_t bytes_ = 0;
47   // Lives in the awaiting frame until resumption, so a completion 47   // Lives in the awaiting frame until resumption, so a completion
48   // posted through an executor never shares the object's state. 48   // posted through an executor never shares the object's state.
49   mutable capy::continuation cont_; 49   mutable capy::continuation cont_;
50   50  
HITCBC 51   455592 bool await_ready() const noexcept 51   444806 bool await_ready() const noexcept
52   { 52   {
53   // A pre-set ec_ means the initiator failed before dispatch 53   // A pre-set ec_ means the initiator failed before dispatch
54   // (e.g. a closed object); complete immediately with that error. 54   // (e.g. a closed object); complete immediately with that error.
HITCBC 55   455592 return static_cast<bool>(ec_); 55   444806 return static_cast<bool>(ec_);
56   } 56   }
57   57  
HITCBC 58   455123 [[nodiscard]] capy::results<std::size_t> await_resume() const noexcept 58   444337 [[nodiscard]] capy::results<std::size_t> await_resume() const noexcept
59   { 59   {
HITCBC 60   455123 return {ec_, bytes_}; 60   444337 return {ec_, bytes_};
61   } 61   }
62   62  
HITCBC 63   455556 auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env) 63   444770 auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env)
64   -> std::coroutine_handle<> 64   -> std::coroutine_handle<>
65   { 65   {
HITCBC 66   455556 token_ = env->stop_token; 66   444770 token_ = env->stop_token;
67   // A pre-stopped token short-circuits before dispatch so no I/O 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 68   // is performed. A stop landing after dispatch is decoded by the
69   // backend, and a completed transfer is reported verbatim: the 69   // backend, and a completed transfer is reported verbatim: the
70   // stream contracts forbid discarding the byte count. 70   // stream contracts forbid discarding the byte count.
HITCBC 71   455556 if (token_.stop_requested()) 71   444770 if (token_.stop_requested())
72   { 72   {
HITCBC 73   128 ec_ = capy::error::canceled; 73   136 ec_ = capy::error::canceled;
HITCBC 74   128 return h; 74   136 return h;
75   } 75   }
HITCBC 76   455428 cont_.h = h; 76   444634 cont_.h = h;
HITCBC 77   455428 cont_.owner = env->owner; 77   444634 cont_.owner = env->owner;
HITCBC 78   455428 return static_cast<Derived const*>(this)->dispatch( 78   444634 return static_cast<Derived const*>(this)->dispatch(
HITCBC 79   455428 cont_, env->executor); 79   444634 cont_, env->executor);
80   } 80   }
81   }; 81   };
82   82  
83   /* CRTP base for awaitables that return results<Value> for a 83   /* CRTP base for awaitables that return results<Value> for a
84   moved-out result object (e.g. the resolver's result lists). 84   moved-out result object (e.g. the resolver's result lists).
85   85  
86   Derived classes must provide: 86   Derived classes must provide:
87   87  
88   std::coroutine_handle<> dispatch( 88   std::coroutine_handle<> dispatch(
89   capy::continuation& cont, 89   capy::continuation& cont,
90   capy::executor_ref ex) const; 90   capy::executor_ref ex) const;
91   91  
92   which forwards to the backend implementation method, passing 92   which forwards to the backend implementation method, passing
93   token_, &ec_, and &value_ as the cancellation/output parameters. 93   token_, &ec_, and &value_ as the cancellation/output parameters.
94   */ 94   */
95   template<class Derived, class Value> 95   template<class Derived, class Value>
96   class value_op_base 96   class value_op_base
97   { 97   {
98   friend Derived; 98   friend Derived;
HITCBC 99   206036 value_op_base() = default; 99   205950 value_op_base() = default;
100   100  
101   public: 101   public:
102   std::stop_token token_; 102   std::stop_token token_;
103   mutable std::error_code ec_; 103   mutable std::error_code ec_;
104   mutable Value value_{}; 104   mutable Value value_{};
105   // See bytes_op_base::cont_. 105   // See bytes_op_base::cont_.
106   mutable capy::continuation cont_; 106   mutable capy::continuation cont_;
107   107  
HITCBC 108   206036 bool await_ready() const noexcept 108   205950 bool await_ready() const noexcept
109   { 109   {
110   // A pre-set ec_ means the initiator failed before dispatch; 110   // A pre-set ec_ means the initiator failed before dispatch;
111   // complete immediately with that error. 111   // complete immediately with that error.
HITCBC 112   206036 return static_cast<bool>(ec_); 112   205950 return static_cast<bool>(ec_);
113   } 113   }
114   114  
HITCBC 115   202808 [[nodiscard]] capy::results<Value> await_resume() const noexcept 115   202722 [[nodiscard]] capy::results<Value> await_resume() const noexcept
116   { 116   {
HITCBC 117   202808 return {ec_, std::move(value_)}; 117   202722 return {ec_, std::move(value_)};
118   } 118   }
119   119  
HITCBC 120   206036 auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env) 120   205950 auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env)
121   -> std::coroutine_handle<> 121   -> std::coroutine_handle<>
122   { 122   {
HITCBC 123   206036 token_ = env->stop_token; 123   205950 token_ = env->stop_token;
124   // A pre-stopped token short-circuits before dispatch; a stop 124   // A pre-stopped token short-circuits before dispatch; a stop
125   // landing after dispatch leaves the completed result intact. 125   // landing after dispatch leaves the completed result intact.
HITCBC 126   206036 if (token_.stop_requested()) 126   205950 if (token_.stop_requested())
127   { 127   {
HITCBC 128   60 ec_ = capy::error::canceled; 128   46 ec_ = capy::error::canceled;
HITCBC 129   60 return h; 129   46 return h;
130   } 130   }
HITCBC 131   205976 cont_.h = h; 131   205904 cont_.h = h;
HITCBC 132   205976 cont_.owner = env->owner; 132   205904 cont_.owner = env->owner;
HITCBC 133   205976 return static_cast<Derived const*>(this)->dispatch( 133   205904 return static_cast<Derived const*>(this)->dispatch(
HITCBC 134   205976 cont_, env->executor); 134   205904 cont_, env->executor);
135   } 135   }
136   }; 136   };
137   137  
138   /* CRTP base for awaitables that return results<>. 138   /* CRTP base for awaitables that return results<>.
139   139  
140   Derived classes must provide: 140   Derived classes must provide:
141   141  
142   std::coroutine_handle<> dispatch( 142   std::coroutine_handle<> dispatch(
143   capy::continuation& cont, 143   capy::continuation& cont,
144   capy::executor_ref ex) const; 144   capy::executor_ref ex) const;
145   145  
146   which forwards to the backend implementation method, passing 146   which forwards to the backend implementation method, passing
147   token_ and &ec_ as the cancellation/output parameters. 147   token_ and &ec_ as the cancellation/output parameters.
148   */ 148   */
149   template<class Derived> 149   template<class Derived>
150   class void_op_base 150   class void_op_base
151   { 151   {
152   friend Derived; 152   friend Derived;
HITCBC 153   16683 void_op_base() = default; 153   16598 void_op_base() = default;
154   154  
155   public: 155   public:
156   std::stop_token token_; 156   std::stop_token token_;
157   mutable std::error_code ec_; 157   mutable std::error_code ec_;
158   // See bytes_op_base::cont_. 158   // See bytes_op_base::cont_.
159   mutable capy::continuation cont_; 159   mutable capy::continuation cont_;
160   160  
HITCBC 161   16683 bool await_ready() const noexcept 161   16598 bool await_ready() const noexcept
162   { 162   {
163   // A pre-set ec_ means the initiator failed before dispatch 163   // A pre-set ec_ means the initiator failed before dispatch
164   // (e.g. auto-open); complete immediately with that error. 164   // (e.g. auto-open); complete immediately with that error.
HITCBC 165   16683 return static_cast<bool>(ec_); 165   16598 return static_cast<bool>(ec_);
166   } 166   }
167   167  
HITCBC 168   9403 [[nodiscard]] capy::results<> await_resume() const noexcept 168   9235 [[nodiscard]] capy::results<> await_resume() const noexcept
169   { 169   {
HITCBC 170   9403 return {ec_}; 170   9235 return {ec_};
171   } 171   }
172   172  
HITCBC 173   16661 auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env) 173   16576 auto await_suspend(std::coroutine_handle<> h, capy::await_context const* env)
174   -> std::coroutine_handle<> 174   -> std::coroutine_handle<>
175   { 175   {
HITCBC 176   16661 token_ = env->stop_token; 176   16576 token_ = env->stop_token;
177   // A pre-stopped token short-circuits before dispatch; a stop 177   // A pre-stopped token short-circuits before dispatch; a stop
178   // landing after dispatch leaves the completed result intact. 178   // landing after dispatch leaves the completed result intact.
HITCBC 179   16661 if (token_.stop_requested()) 179   16576 if (token_.stop_requested())
180   { 180   {
HITCBC 181   1055 ec_ = capy::error::canceled; 181   972 ec_ = capy::error::canceled;
HITCBC 182   1055 return h; 182   972 return h;
183   } 183   }
HITCBC 184   15606 cont_.h = h; 184   15604 cont_.h = h;
HITCBC 185   15606 cont_.owner = env->owner; 185   15604 cont_.owner = env->owner;
HITCBC 186   15606 return static_cast<Derived const*>(this)->dispatch( 186   15604 return static_cast<Derived const*>(this)->dispatch(
HITCBC 187   15606 cont_, env->executor); 187   15604 cont_, env->executor);
188   } 188   }
189   }; 189   };
190   190  
191   } // namespace boost::corosio::detail 191   } // namespace boost::corosio::detail
192   192  
193   #endif // BOOST_COROSIO_DETAIL_OP_BASE_HPP 193   #endif // BOOST_COROSIO_DETAIL_OP_BASE_HPP