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 +
    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 +
    bool await_ready() const noexcept
 
47 +
    {
 
48 +
        return token_.stop_requested();
 
49 +
    }
 
50 +

 
51 +
    capy::io_result<std::size_t> await_resume() const noexcept
 
52 +
    {
 
53 +
        if (token_.stop_requested())
 
54 +
            return {make_error_code(std::errc::operation_canceled), 0};
 
55 +
        return {ec_, bytes_};
 
56 +
    }
 
57 +

 
58 +
    auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
 
59 +
        -> std::coroutine_handle<>
 
60 +
    {
 
61 +
        token_ = env->stop_token;
 
62 +
        return static_cast<Derived const*>(this)->dispatch(
 
63 +
            h, env->executor);
 
64 +
    }
 
65 +
};
 
66 +

 
67 +
/* CRTP base for awaitables that return io_result<>.
 
68 +

 
69 +
   Derived classes must provide:
 
70 +

 
71 +
     std::coroutine_handle<> dispatch(
 
72 +
         std::coroutine_handle<> h,
 
73 +
         capy::executor_ref ex) const;
 
74 +

 
75 +
   which forwards to the backend implementation method, passing
 
76 +
   token_ and &ec_ as the cancellation/output parameters.
 
77 +
*/
 
78 +
template<class Derived>
 
79 +
class void_op_base
 
80 +
{
 
81 +
    friend Derived;
 
82 +
    void_op_base() = default;
 
83 +

 
84 +
public:
 
85 +
    std::stop_token token_;
 
86 +
    mutable std::error_code ec_;
 
87 +

 
88 +
    bool await_ready() const noexcept
 
89 +
    {
 
90 +
        return token_.stop_requested();
 
91 +
    }
 
92 +

 
93 +
    capy::io_result<> await_resume() const noexcept
 
94 +
    {
 
95 +
        if (token_.stop_requested())
 
96 +
            return {make_error_code(std::errc::operation_canceled)};
 
97 +
        return {ec_};
 
98 +
    }
 
99 +

 
100 +
    auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
 
101 +
        -> std::coroutine_handle<>
 
102 +
    {
 
103 +
        token_ = env->stop_token;
 
104 +
        return static_cast<Derived const*>(this)->dispatch(
 
105 +
            h, env->executor);
 
106 +
    }
 
107 +
};
 
108 +

 
109 +
} // namespace boost::corosio::detail
 
110 +

 
111 +
#endif // BOOST_COROSIO_DETAIL_OP_BASE_HPP