include/boost/corosio/native/native_tcp_socket.hpp

94.6% Lines (70/0/74) 100.0% List of functions (69/0/69)
native_tcp_socket.hpp
f(x) Functions (69)
Function Calls Lines Blocks
boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::get_impl() :82 17x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::get_impl() :82 16x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::get_impl() :82 16x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::native_read_awaitable(boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>&, boost::capy::mutable_buffer) :96 3x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::native_read_awaitable(boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>&, boost::capy::mutable_buffer) :96 3x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::native_read_awaitable(boost::corosio::native_tcp_socket<boost::corosio::select_t{}>&, boost::capy::mutable_buffer) :96 3x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_ready() const :103 3x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_ready() const :103 3x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_ready() const :103 3x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_resume() const :110 3x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_resume() const :110 3x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_resume() const :110 3x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :117 3x 100.0% 77.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :117 3x 100.0% 77.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :117 3x 100.0% 77.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::native_write_awaitable(boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>&, boost::capy::const_buffer) :135 4x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_write_awaitable<boost::capy::const_buffer>::native_write_awaitable(boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>&, boost::capy::const_buffer) :135 4x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::native_write_awaitable(boost::corosio::native_tcp_socket<boost::corosio::select_t{}>&, boost::capy::const_buffer) :135 4x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_ready() const :142 4x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_ready() const :142 4x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_ready() const :142 4x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_resume() const :149 4x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_resume() const :149 4x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_resume() const :149 4x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :156 4x 100.0% 77.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :156 4x 100.0% 77.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :156 4x 100.0% 77.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>&, boost::corosio::wait_type) :172 2x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>&, boost::corosio::wait_type) :172 2x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_tcp_socket<boost::corosio::select_t{}>&, boost::corosio::wait_type) :172 2x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::await_ready() const :178 2x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_wait_awaitable::await_ready() const :178 2x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_wait_awaitable::await_ready() const :178 2x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::await_resume() const :185 2x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_wait_awaitable::await_resume() const :185 2x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_wait_awaitable::await_resume() const :185 2x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :192 2x 100.0% 82.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_wait_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :192 2x 100.0% 82.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_wait_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :192 2x 100.0% 82.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::native_connect_awaitable(boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>&, boost::corosio::endpoint) :208 8x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_connect_awaitable::native_connect_awaitable(boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>&, boost::corosio::endpoint) :208 7x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_connect_awaitable::native_connect_awaitable(boost::corosio::native_tcp_socket<boost::corosio::select_t{}>&, boost::corosio::endpoint) :208 7x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::await_ready() const :214 8x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_connect_awaitable::await_ready() const :214 7x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_connect_awaitable::await_ready() const :214 7x 100.0% 88.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::await_resume() const :221 8x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_connect_awaitable::await_resume() const :221 7x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_connect_awaitable::await_resume() const :221 7x 75.0% 57.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :228 8x 100.0% 82.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_connect_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :228 7x 100.0% 82.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_connect_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :228 7x 100.0% 82.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_tcp_socket(boost::capy::execution_context&) :242 19x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_tcp_socket(boost::capy::execution_context&) :242 16x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_tcp_socket(boost::capy::execution_context&) :242 16x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::native_tcp_socket(boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>&&) :268 9x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::native_tcp_socket(boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>&&) :268 7x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::native_tcp_socket(boost::corosio::native_tcp_socket<boost::corosio::select_t{}>&&) :268 7x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::operator=(boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>&&) :281 2x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::operator=(boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>&&) :281 1x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::operator=(boost::corosio::native_tcp_socket<boost::corosio::select_t{}>&&) :281 1x 100.0% 100.0% auto boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :300 3x 100.0% 100.0% auto boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :300 3x 100.0% 100.0% auto boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :300 3x 100.0% 100.0% auto boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::write_some<boost::capy::const_buffer>(boost::capy::const_buffer const&) :319 4x 100.0% 100.0% auto boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::write_some<boost::capy::const_buffer>(boost::capy::const_buffer const&) :319 4x 100.0% 100.0% auto boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::write_some<boost::capy::const_buffer>(boost::capy::const_buffer const&) :319 4x 100.0% 100.0% boost::corosio::native_tcp_socket<boost::corosio::epoll_t{}>::connect(boost::corosio::endpoint) :339 3x 100.0% 90.0% boost::corosio::native_tcp_socket<boost::corosio::io_uring_t{}>::connect(boost::corosio::endpoint) :339 2x 100.0% 90.0% boost::corosio::native_tcp_socket<boost::corosio::select_t{}>::connect(boost::corosio::endpoint) :339 2x 100.0% 90.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
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_NATIVE_NATIVE_TCP_SOCKET_HPP
11 #define BOOST_COROSIO_NATIVE_NATIVE_TCP_SOCKET_HPP
12
13 #include <boost/corosio/tcp_socket.hpp>
14 #include <boost/corosio/backend.hpp>
15
16 #ifndef BOOST_COROSIO_MRDOCS
17 #if BOOST_COROSIO_HAS_EPOLL
18 #include <boost/corosio/native/detail/epoll/epoll_types.hpp>
19 #endif
20
21 #if BOOST_COROSIO_HAS_SELECT
22 #include <boost/corosio/native/detail/select/select_types.hpp>
23 #endif
24
25 #if BOOST_COROSIO_HAS_KQUEUE
26 #include <boost/corosio/native/detail/kqueue/kqueue_types.hpp>
27 #endif
28
29 #if BOOST_COROSIO_HAS_IOCP
30 #include <boost/corosio/native/detail/iocp/win_tcp_acceptor_service.hpp>
31 #endif
32
33 #if BOOST_COROSIO_HAS_IO_URING
34 #include <boost/corosio/native/detail/io_uring/io_uring_types.hpp>
35 #endif
36 #endif // !BOOST_COROSIO_MRDOCS
37
38 namespace boost::corosio {
39
40 /** An asynchronous TCP socket with devirtualized I/O operations.
41
42 This class template inherits from @ref tcp_socket and shadows
43 the async operations (`read_some`, `write_some`, `connect`) with
44 versions that call the backend implementation directly, allowing
45 the compiler to inline through the entire call chain.
46
47 Non-async operations (`open`, `close`, `cancel`, socket options)
48 remain unchanged and dispatch through the compiled library.
49
50 A `native_tcp_socket` IS-A `tcp_socket` and can be passed to
51 any function expecting `tcp_socket&` or `io_stream&`, in which
52 case virtual dispatch is used transparently.
53
54 @tparam Backend A backend tag value (e.g., `epoll`,
55 `iocp`) whose type provides the concrete implementation
56 types.
57
58 @par Thread Safety
59 Same as @ref tcp_socket.
60
61 @par Example
62 @code
63 #include <boost/corosio/native/native_tcp_socket.hpp>
64
65 native_io_context<epoll> ctx;
66 native_tcp_socket<epoll> s(ctx);
67 auto [ec] = co_await s.connect(ep);
68 if (ec)
69 co_return;
70 auto [ec2, n] = co_await s.read_some(buf);
71 @endcode
72
73 @see tcp_socket, epoll_t, iocp_t
74 */
75 template<auto Backend>
76 class native_tcp_socket : public tcp_socket
77 {
78 using backend_type = decltype(Backend);
79 using impl_type = typename backend_type::tcp_socket_type;
80 using service_type = typename backend_type::tcp_service_type;
81
82 49x impl_type& get_impl() noexcept
83 {
84 49x return *static_cast<impl_type*>(h_.get());
85 }
86
87 template<class MutableBufferSequence>
88 struct native_read_awaitable
89 {
90 native_tcp_socket& self_;
91 MutableBufferSequence buffers_;
92 std::stop_token token_;
93 mutable std::error_code ec_;
94 mutable std::size_t bytes_transferred_ = 0;
95
96 9x native_read_awaitable(
97 native_tcp_socket& self, MutableBufferSequence buffers) noexcept
98 9x : self_(self)
99 9x , buffers_(std::move(buffers))
100 {
101 9x }
102
103 9x bool await_ready() const noexcept
104 {
105 // A pre-set ec_ means the initiator failed before
106 // dispatch (e.g. a closed object).
107 9x return static_cast<bool>(ec_) || token_.stop_requested();
108 }
109
110 9x [[nodiscard]] capy::io_result<std::size_t> await_resume() const noexcept
111 {
112 9x if (token_.stop_requested())
113 return {make_error_code(std::errc::operation_canceled), 0};
114 9x return {ec_, bytes_transferred_};
115 }
116
117 9x auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
118 -> std::coroutine_handle<>
119 {
120 9x token_ = env->stop_token;
121 27x return self_.get_impl().read_some(
122 27x h, env->executor, buffers_, token_, &ec_, &bytes_transferred_);
123 }
124 };
125
126 template<class ConstBufferSequence>
127 struct native_write_awaitable
128 {
129 native_tcp_socket& self_;
130 ConstBufferSequence buffers_;
131 std::stop_token token_;
132 mutable std::error_code ec_;
133 mutable std::size_t bytes_transferred_ = 0;
134
135 12x native_write_awaitable(
136 native_tcp_socket& self, ConstBufferSequence buffers) noexcept
137 12x : self_(self)
138 12x , buffers_(std::move(buffers))
139 {
140 12x }
141
142 12x bool await_ready() const noexcept
143 {
144 // A pre-set ec_ means the initiator failed before
145 // dispatch (e.g. a closed object).
146 12x return static_cast<bool>(ec_) || token_.stop_requested();
147 }
148
149 12x [[nodiscard]] capy::io_result<std::size_t> await_resume() const noexcept
150 {
151 12x if (token_.stop_requested())
152 return {make_error_code(std::errc::operation_canceled), 0};
153 12x return {ec_, bytes_transferred_};
154 }
155
156 12x auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
157 -> std::coroutine_handle<>
158 {
159 12x token_ = env->stop_token;
160 36x return self_.get_impl().write_some(
161 36x h, env->executor, buffers_, token_, &ec_, &bytes_transferred_);
162 }
163 };
164
165 struct native_wait_awaitable
166 {
167 native_tcp_socket& self_;
168 wait_type w_;
169 std::stop_token token_;
170 mutable std::error_code ec_;
171
172 6x native_wait_awaitable(native_tcp_socket& self, wait_type w) noexcept
173 6x : self_(self)
174 6x , w_(w)
175 {
176 6x }
177
178 6x bool await_ready() const noexcept
179 {
180 // A pre-set ec_ means the initiator failed before
181 // dispatch (e.g. a closed object).
182 6x return static_cast<bool>(ec_) || token_.stop_requested();
183 }
184
185 6x [[nodiscard]] capy::io_result<> await_resume() const noexcept
186 {
187 6x if (token_.stop_requested())
188 return {make_error_code(std::errc::operation_canceled)};
189 6x return {ec_};
190 }
191
192 6x auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
193 -> std::coroutine_handle<>
194 {
195 6x token_ = env->stop_token;
196 18x return self_.get_impl().wait(
197 18x h, env->executor, w_, token_, &ec_);
198 }
199 };
200
201 struct native_connect_awaitable
202 {
203 native_tcp_socket& self_;
204 endpoint endpoint_;
205 std::stop_token token_;
206 mutable std::error_code ec_;
207
208 22x native_connect_awaitable(native_tcp_socket& self, endpoint ep) noexcept
209 22x : self_(self)
210 22x , endpoint_(ep)
211 {
212 22x }
213
214 22x bool await_ready() const noexcept
215 {
216 // A pre-set ec_ means the initiator failed before
217 // dispatch (e.g. a closed object).
218 22x return static_cast<bool>(ec_) || token_.stop_requested();
219 }
220
221 22x [[nodiscard]] capy::io_result<> await_resume() const noexcept
222 {
223 22x if (token_.stop_requested())
224 return {make_error_code(std::errc::operation_canceled)};
225 22x return {ec_};
226 }
227
228 22x auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
229 -> std::coroutine_handle<>
230 {
231 22x token_ = env->stop_token;
232 66x return self_.get_impl().connect(
233 66x h, env->executor, endpoint_, token_, &ec_);
234 }
235 };
236
237 public:
238 /** Construct a native socket from an execution context.
239
240 @param ctx The execution context that will own this socket.
241 */
242 51x explicit native_tcp_socket(capy::execution_context& ctx)
243 51x : io_object(create_handle<service_type>(ctx))
244 {
245 51x }
246
247 /** Construct a native socket from an executor.
248
249 @param ex The executor whose context will own the socket.
250 */
251 template<class Ex>
252 requires(!std::same_as<std::remove_cvref_t<Ex>, native_tcp_socket>) &&
253 capy::Executor<Ex>
254 explicit native_tcp_socket(Ex const& ex) : native_tcp_socket(ex.context())
255 {
256 }
257
258 /** Move construct.
259
260 @param other The socket to move from.
261
262 @pre No awaitables returned by @p other's methods exist.
263 @pre @p other is not referenced as a peer in any outstanding
264 accept awaitable.
265 @pre The execution context associated with @p other must
266 outlive this socket.
267 */
268 23x native_tcp_socket(native_tcp_socket&&) noexcept = default;
269
270 /** Move assign.
271
272 @param other The socket to move from.
273
274 @pre No awaitables returned by either `*this` or @p other's
275 methods exist.
276 @pre Neither `*this` nor @p other is referenced as a peer in
277 any outstanding accept awaitable.
278 @pre The execution context associated with @p other must
279 outlive this socket.
280 */
281 4x native_tcp_socket& operator=(native_tcp_socket&&) noexcept = default;
282
283 native_tcp_socket(native_tcp_socket const&) = delete;
284 native_tcp_socket& operator=(native_tcp_socket const&) = delete;
285
286 /** Asynchronously read data from the socket.
287
288 Calls the backend implementation directly, bypassing virtual
289 dispatch. Otherwise identical to @ref io_stream::read_some.
290
291 @param buffers The buffer sequence to read into.
292
293 @return An awaitable yielding `(error_code, std::size_t)`.
294
295 This socket must outlive the returned awaitable. The memory
296 referenced by @p buffers must remain valid until the operation
297 completes.
298 */
299 template<capy::MutableBufferSequence MB>
300 9x [[nodiscard]] auto read_some(MB const& buffers)
301 {
302 9x return native_read_awaitable<MB>(*this, buffers);
303 }
304
305 /** Asynchronously write data to the socket.
306
307 Calls the backend implementation directly, bypassing virtual
308 dispatch. Otherwise identical to @ref io_stream::write_some.
309
310 @param buffers The buffer sequence to write from.
311
312 @return An awaitable yielding `(error_code, std::size_t)`.
313
314 This socket must outlive the returned awaitable. The memory
315 referenced by @p buffers must remain valid until the operation
316 completes.
317 */
318 template<capy::ConstBufferSequence CB>
319 12x [[nodiscard]] auto write_some(CB const& buffers)
320 {
321 12x return native_write_awaitable<CB>(*this, buffers);
322 }
323
324 /** Asynchronously connect to a remote endpoint.
325
326 Calls the backend implementation directly, bypassing virtual
327 dispatch. Otherwise identical to @ref tcp_socket::connect.
328
329 If the socket is not open, it is opened automatically using
330 the protocol matching the endpoint's address family. An open
331 failure surfaces through the connect completion.
332
333 @param ep The remote endpoint to connect to.
334
335 @return An awaitable yielding `io_result<>`.
336
337 This socket must outlive the returned awaitable.
338 */
339 22x [[nodiscard]] auto connect(endpoint ep)
340 {
341 22x native_connect_awaitable aw(*this, ep);
342 22x if (!is_open())
343 3x aw.ec_ = open(ep.is_v6() ? tcp::v6() : tcp::v4());
344 22x return aw;
345 }
346
347 /** Asynchronously wait for the socket to be ready.
348
349 Calls the backend implementation directly, bypassing virtual
350 dispatch. Otherwise identical to @ref tcp_socket::wait.
351
352 @param w The wait direction (read, write, or error).
353
354 @return An awaitable yielding `io_result<>`.
355 */
356 6x [[nodiscard]] auto wait(wait_type w)
357 {
358 6x return native_wait_awaitable(*this, w);
359 }
360 };
361
362 } // namespace boost::corosio
363
364 #endif
365