include/boost/capy/ex/immediate.hpp

100.0% Lines (22/0/22) 84.0% List of functions (21/0/25)
immediate.hpp
f(x) Functions (25)
Function Calls Lines Blocks
boost::capy::immediate<boost::capy::io_result<> >::await_ready() const :85 5x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<int, double> >::await_ready() const :85 2x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<int, int, int> >::await_ready() const :85 2x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<unsigned long> >::await_ready() const :85 9x 100.0% 100.0% boost::capy::immediate<int>::await_ready() const :85 3x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :102 0 0.0% 0.0% boost::capy::immediate<boost::capy::io_result<int, double> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :102 0 0.0% 0.0% boost::capy::immediate<boost::capy::io_result<int, int, int> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :102 0 0.0% 0.0% boost::capy::immediate<boost::capy::io_result<unsigned long> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :102 0 0.0% 0.0% boost::capy::immediate<int>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) const :102 1x 100.0% 100.0% boost::capy::immediate<boost::capy::immediate_test::testMoveSemantics()::move_only>::await_resume() :116 1x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<> >::await_resume() :116 5x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<int, double> >::await_resume() :116 3x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<int, int, int> >::await_resume() :116 3x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<unsigned long> >::await_resume() :116 9x 100.0% 100.0% boost::capy::immediate<int>::await_resume() :116 2x 100.0% 100.0% boost::capy::immediate<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::await_resume() :116 1x 100.0% 100.0% boost::capy::ready() :161 3x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<unsigned long> > boost::capy::ready<unsigned long>(unsigned long) :174 4x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<int, double> > boost::capy::ready<int, double>(int, double) :188 2x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<int, int, int> > boost::capy::ready<int, int, int>(int, int, int) :203 2x 100.0% 100.0% boost::capy::ready(std::error_code) :233 1x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<unsigned long> > boost::capy::ready<unsigned long>(std::error_code, unsigned long) :247 2x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<int, double> > boost::capy::ready<int, double>(std::error_code, int, double) :262 1x 100.0% 100.0% boost::capy::immediate<boost::capy::io_result<int, int, int> > boost::capy::ready<int, int, int>(std::error_code, int, int, int) :278 1x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2026 Michael Vandeberg
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/capy
9 //
10
11 #ifndef BOOST_CAPY_EX_IMMEDIATE_HPP
12 #define BOOST_CAPY_EX_IMMEDIATE_HPP
13
14 #include <boost/capy/detail/config.hpp>
15 #include <boost/capy/ex/io_env.hpp>
16 #include <boost/capy/io_result.hpp>
17
18 #include <coroutine>
19 #include <stop_token>
20 #include <utility>
21
22 namespace boost {
23 namespace capy {
24
25 /** An awaitable that completes immediately with a value.
26
27 This awaitable wraps a synchronous result so it can be used in
28 contexts that require an awaitable type. It never suspends -
29 `await_ready()` always returns `true`, so the coroutine machinery
30 is optimized away by the compiler.
31
32 Use this to adapt synchronous operations to satisfy async concepts
33 like @ref IoAwaitable without the overhead of a full coroutine frame.
34
35 @tparam T The result type to wrap.
36
37 @par Example
38 @code
39 // Wrap a sync operation as an awaitable
40 immediate<int> get_value()
41 {
42 return {42};
43 }
44
45 task<void> example()
46 {
47 int x = co_await get_value(); // No suspension, returns 42
48 }
49 @endcode
50
51 @par Building synchronous I/O operations
52 @code
53 struct my_sync_sink
54 {
55 template<ConstBufferSequence CB>
56 immediate<io_result<std::size_t>>
57 write(CB buffers)
58 {
59 auto n = process_sync(buffers);
60 return {{{}, n}};
61 }
62
63 immediate<io_result<>>
64 write_eof()
65 {
66 return {{}};
67 }
68 };
69 @endcode
70
71 @see ready, io_result
72 */
73 template<class T>
74 struct immediate
75 {
76 /** The wrapped value. */
77 T value_;
78
79 /** Always returns true - this awaitable never suspends.
80
81 @return Always `true`, so the awaiting coroutine does not suspend
82 and `await_suspend` is never called.
83 */
84 constexpr bool
85 21x await_ready() const noexcept
86 {
87 21x return true;
88 }
89
90 /** IoAwaitable protocol overload.
91
92 This overload allows `immediate` to satisfy the @ref IoAwaitable
93 concept. Since the result is already available, the environment
94 is unused.
95
96 @param h The coroutine handle (unused).
97 @param env The execution environment (unused).
98
99 @return `std::noop_coroutine()` to indicate no suspension.
100 */
101 std::coroutine_handle<>
102 1x await_suspend(
103 std::coroutine_handle<> h,
104 io_env const* env) const noexcept
105 {
106 (void)h;
107 (void)env;
108 1x return std::noop_coroutine();
109 }
110
111 /** Returns the wrapped value.
112
113 @return The stored value, moved if non-const.
114 */
115 constexpr T
116 24x await_resume() noexcept
117 {
118 24x return std::move(value_);
119 }
120
121 /** Returns the wrapped value (const overload).
122
123 @return A reference to the stored value. Nothing is moved, so the
124 reference is valid only while the `immediate` is alive.
125 */
126 constexpr T const&
127 await_resume() const noexcept
128 {
129 return value_;
130 }
131 };
132
133 /** Create an immediate awaitable for a successful io_result.
134
135 This helper creates an @ref immediate wrapping an @ref io_result
136 with no error and the provided values.
137
138 @par Example
139 @code
140 immediate<io_result<std::size_t>>
141 write(const_buffer buf)
142 {
143 auto n = write_sync(buf);
144 return ready(n); // success with n bytes
145 }
146
147 immediate<io_result<>>
148 connect()
149 {
150 connect_sync();
151 return ready(); // void success
152 }
153 @endcode
154
155 @return An immediate awaitable containing a successful io_result.
156
157 @see immediate, io_result
158 */
159 inline
160 immediate<io_result<>>
161 3x ready() noexcept
162 {
163 3x return {{}};
164 }
165
166 /** Create an immediate awaitable for a successful io_result with one value.
167
168 @param t1 The result value.
169
170 @return An immediate awaitable containing `io_result<T1>{{}, t1}`.
171 */
172 template<class T1>
173 immediate<io_result<T1>>
174 4x ready(T1 t1)
175 {
176 4x return {{{}, std::move(t1)}};
177 }
178
179 /** Create an immediate awaitable for a successful io_result with two values.
180
181 @param t1 The first result value.
182 @param t2 The second result value.
183
184 @return An immediate awaitable containing `io_result<T1,T2>{{}, t1, t2}`.
185 */
186 template<class T1, class T2>
187 immediate<io_result<T1, T2>>
188 2x ready(T1 t1, T2 t2)
189 {
190 2x return {{{}, std::move(t1), std::move(t2)}};
191 }
192
193 /** Create an immediate awaitable for a successful io_result with three values.
194
195 @param t1 The first result value.
196 @param t2 The second result value.
197 @param t3 The third result value.
198
199 @return An immediate awaitable containing `io_result<T1,T2,T3>{{}, t1, t2, t3}`.
200 */
201 template<class T1, class T2, class T3>
202 immediate<io_result<T1, T2, T3>>
203 2x ready(T1 t1, T2 t2, T3 t3)
204 {
205 2x return {{{}, std::move(t1), std::move(t2), std::move(t3)}};
206 }
207
208 /** Create an immediate awaitable for a failed io_result.
209
210 This helper creates an @ref immediate wrapping an @ref io_result
211 with an error code.
212
213 @par Example
214 @code
215 immediate<io_result<std::size_t>>
216 write(const_buffer buf)
217 {
218 auto ec = write_sync(buf);
219 if(ec)
220 return ready(ec, std::size_t{0});
221 return ready(buffer_size(buf));
222 }
223 @endcode
224
225 @param ec The error code.
226
227 @return An immediate awaitable containing a failed io_result.
228
229 @see immediate, io_result
230 */
231 inline
232 immediate<io_result<>>
233 1x ready(std::error_code ec) noexcept
234 {
235 1x return {{ec}};
236 }
237
238 /** Create an immediate awaitable for an io_result with error and one value.
239
240 @param ec The error code.
241 @param t1 The result value.
242
243 @return An immediate awaitable containing `io_result<T1>{ec, t1}`.
244 */
245 template<class T1>
246 immediate<io_result<T1>>
247 2x ready(std::error_code ec, T1 t1)
248 {
249 2x return {{ec, std::move(t1)}};
250 }
251
252 /** Create an immediate awaitable for an io_result with error and two values.
253
254 @param ec The error code.
255 @param t1 The first result value.
256 @param t2 The second result value.
257
258 @return An immediate awaitable containing `io_result<T1,T2>{ec, t1, t2}`.
259 */
260 template<class T1, class T2>
261 immediate<io_result<T1, T2>>
262 1x ready(std::error_code ec, T1 t1, T2 t2)
263 {
264 1x return {{ec, std::move(t1), std::move(t2)}};
265 }
266
267 /** Create an immediate awaitable for an io_result with error and three values.
268
269 @param ec The error code.
270 @param t1 The first result value.
271 @param t2 The second result value.
272 @param t3 The third result value.
273
274 @return An immediate awaitable containing `io_result<T1,T2,T3>{ec, t1, t2, t3}`.
275 */
276 template<class T1, class T2, class T3>
277 immediate<io_result<T1, T2, T3>>
278 1x ready(std::error_code ec, T1 t1, T2 t2, T3 t3)
279 {
280 1x return {{ec, std::move(t1), std::move(t2), std::move(t3)}};
281 }
282
283 } // namespace capy
284 } // namespace boost
285
286 #endif
287