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/io_result.hpp>
14 : #include <boost/capy/ex/executor_ref.hpp>
15 : #include <boost/capy/ex/io_env.hpp>
16 :
17 : #include <coroutine>
18 : #include <cstddef>
19 : #include <stop_token>
20 : #include <system_error>
21 :
22 : namespace boost::corosio::detail {
23 :
24 : /* CRTP base for awaitables that return io_result<std::size_t>.
25 :
26 : Derived classes must provide:
27 :
28 : std::coroutine_handle<> dispatch(
29 : std::coroutine_handle<> h,
30 : capy::executor_ref ex) const;
31 :
32 : which forwards to the backend implementation method, passing
33 : token_, &ec_, and &bytes_ as the cancellation/output parameters.
34 : */
35 : template<class Derived>
36 : class bytes_op_base
37 : {
38 : friend Derived;
39 HIT 675383 : bytes_op_base() = default;
40 :
41 : public:
42 : std::stop_token token_;
43 : mutable std::error_code ec_;
44 : mutable std::size_t bytes_ = 0;
45 :
46 675383 : bool await_ready() const noexcept
47 : {
48 : // A pre-set ec_ means the initiator failed before dispatch
49 : // (e.g. a closed object); complete immediately with that error.
50 675383 : return static_cast<bool>(ec_) || token_.stop_requested();
51 : }
52 :
53 675371 : [[nodiscard]] capy::io_result<std::size_t> await_resume() const noexcept
54 : {
55 675371 : if (token_.stop_requested())
56 250 : return {make_error_code(std::errc::operation_canceled), 0};
57 675121 : return {ec_, bytes_};
58 : }
59 :
60 675367 : auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
61 : -> std::coroutine_handle<>
62 : {
63 675367 : token_ = env->stop_token;
64 675367 : return static_cast<Derived const*>(this)->dispatch(
65 675367 : h, env->executor);
66 : }
67 : };
68 :
69 : /* CRTP base for awaitables that return io_result<>.
70 :
71 : Derived classes must provide:
72 :
73 : std::coroutine_handle<> dispatch(
74 : std::coroutine_handle<> h,
75 : capy::executor_ref ex) const;
76 :
77 : which forwards to the backend implementation method, passing
78 : token_ and &ec_ as the cancellation/output parameters.
79 : */
80 : template<class Derived>
81 : class void_op_base
82 : {
83 : friend Derived;
84 7165 : void_op_base() = default;
85 :
86 : public:
87 : std::stop_token token_;
88 : mutable std::error_code ec_;
89 :
90 7165 : bool await_ready() const noexcept
91 : {
92 : // A pre-set ec_ means the initiator failed before dispatch
93 : // (e.g. auto-open); complete immediately with that error.
94 7165 : return static_cast<bool>(ec_) || token_.stop_requested();
95 : }
96 :
97 7165 : [[nodiscard]] capy::io_result<> await_resume() const noexcept
98 : {
99 7165 : if (token_.stop_requested())
100 32 : return {make_error_code(std::errc::operation_canceled)};
101 7133 : return {ec_};
102 : }
103 :
104 7161 : auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
105 : -> std::coroutine_handle<>
106 : {
107 7161 : token_ = env->stop_token;
108 7161 : return static_cast<Derived const*>(this)->dispatch(
109 7161 : h, env->executor);
110 : }
111 : };
112 :
113 : } // namespace boost::corosio::detail
114 :
115 : #endif // BOOST_COROSIO_DETAIL_OP_BASE_HPP
|