]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/basic_datagram_socket.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / asio / basic_datagram_socket.hpp
CommitLineData
7c673cae
FG
1//
2// basic_datagram_socket.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~
4//
f67539c2 5// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP
12#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19#include <cstddef>
20#include <boost/asio/basic_socket.hpp>
7c673cae 21#include <boost/asio/detail/handler_type_requirements.hpp>
92f5a8d4 22#include <boost/asio/detail/non_const_lvalue.hpp>
7c673cae
FG
23#include <boost/asio/detail/throw_error.hpp>
24#include <boost/asio/detail/type_traits.hpp>
25#include <boost/asio/error.hpp>
26
27#include <boost/asio/detail/push_options.hpp>
28
29namespace boost {
30namespace asio {
31
92f5a8d4
TL
32#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
33#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL
34
35// Forward declaration with defaulted arguments.
20effc67 36template <typename Protocol, typename Executor = any_io_executor>
92f5a8d4
TL
37class basic_datagram_socket;
38
39#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
40
7c673cae
FG
41/// Provides datagram-oriented socket functionality.
42/**
43 * The basic_datagram_socket class template provides asynchronous and blocking
44 * datagram-oriented socket functionality.
45 *
46 * @par Thread Safety
47 * @e Distinct @e objects: Safe.@n
48 * @e Shared @e objects: Unsafe.
49 */
92f5a8d4 50template <typename Protocol, typename Executor>
7c673cae 51class basic_datagram_socket
92f5a8d4 52 : public basic_socket<Protocol, Executor>
7c673cae
FG
53{
54public:
92f5a8d4
TL
55 /// The type of the executor associated with the object.
56 typedef Executor executor_type;
57
58 /// Rebinds the socket type to another executor.
59 template <typename Executor1>
60 struct rebind_executor
61 {
62 /// The socket type when rebound to the specified executor.
63 typedef basic_datagram_socket<Protocol, Executor1> other;
64 };
65
7c673cae 66 /// The native representation of a socket.
b32b8144
FG
67#if defined(GENERATING_DOCUMENTATION)
68 typedef implementation_defined native_handle_type;
69#else
92f5a8d4
TL
70 typedef typename basic_socket<Protocol,
71 Executor>::native_handle_type native_handle_type;
b32b8144 72#endif
7c673cae
FG
73
74 /// The protocol type.
75 typedef Protocol protocol_type;
76
77 /// The endpoint type.
78 typedef typename Protocol::endpoint endpoint_type;
79
80 /// Construct a basic_datagram_socket without opening it.
81 /**
82 * This constructor creates a datagram socket without opening it. The open()
83 * function must be called before data can be sent or received on the socket.
84 *
92f5a8d4
TL
85 * @param ex The I/O executor that the socket will use, by default, to
86 * dispatch handlers for any asynchronous operations performed on the socket.
7c673cae 87 */
92f5a8d4
TL
88 explicit basic_datagram_socket(const executor_type& ex)
89 : basic_socket<Protocol, Executor>(ex)
90 {
91 }
92
93 /// Construct a basic_datagram_socket without opening it.
94 /**
95 * This constructor creates a datagram socket without opening it. The open()
96 * function must be called before data can be sent or received on the socket.
97 *
98 * @param context An execution context which provides the I/O executor that
99 * the socket will use, by default, to dispatch handlers for any asynchronous
100 * operations performed on the socket.
101 */
102 template <typename ExecutionContext>
103 explicit basic_datagram_socket(ExecutionContext& context,
104 typename enable_if<
105 is_convertible<ExecutionContext&, execution_context&>::value
106 >::type* = 0)
107 : basic_socket<Protocol, Executor>(context)
7c673cae
FG
108 {
109 }
110
111 /// Construct and open a basic_datagram_socket.
112 /**
113 * This constructor creates and opens a datagram socket.
114 *
92f5a8d4
TL
115 * @param ex The I/O executor that the socket will use, by default, to
116 * dispatch handlers for any asynchronous operations performed on the socket.
7c673cae
FG
117 *
118 * @param protocol An object specifying protocol parameters to be used.
119 *
120 * @throws boost::system::system_error Thrown on failure.
121 */
92f5a8d4
TL
122 basic_datagram_socket(const executor_type& ex, const protocol_type& protocol)
123 : basic_socket<Protocol, Executor>(ex, protocol)
124 {
125 }
126
127 /// Construct and open a basic_datagram_socket.
128 /**
129 * This constructor creates and opens a datagram socket.
130 *
131 * @param context An execution context which provides the I/O executor that
132 * the socket will use, by default, to dispatch handlers for any asynchronous
133 * operations performed on the socket.
134 *
135 * @param protocol An object specifying protocol parameters to be used.
136 *
137 * @throws boost::system::system_error Thrown on failure.
138 */
139 template <typename ExecutionContext>
140 basic_datagram_socket(ExecutionContext& context,
141 const protocol_type& protocol,
142 typename enable_if<
143 is_convertible<ExecutionContext&, execution_context&>::value
144 >::type* = 0)
145 : basic_socket<Protocol, Executor>(context, protocol)
7c673cae
FG
146 {
147 }
148
149 /// Construct a basic_datagram_socket, opening it and binding it to the given
150 /// local endpoint.
151 /**
152 * This constructor creates a datagram socket and automatically opens it bound
153 * to the specified endpoint on the local machine. The protocol used is the
154 * protocol associated with the given endpoint.
155 *
92f5a8d4
TL
156 * @param ex The I/O executor that the socket will use, by default, to
157 * dispatch handlers for any asynchronous operations performed on the socket.
158 *
159 * @param endpoint An endpoint on the local machine to which the datagram
160 * socket will be bound.
161 *
162 * @throws boost::system::system_error Thrown on failure.
163 */
164 basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint)
165 : basic_socket<Protocol, Executor>(ex, endpoint)
166 {
167 }
168
169 /// Construct a basic_datagram_socket, opening it and binding it to the given
170 /// local endpoint.
171 /**
172 * This constructor creates a datagram socket and automatically opens it bound
173 * to the specified endpoint on the local machine. The protocol used is the
174 * protocol associated with the given endpoint.
175 *
176 * @param context An execution context which provides the I/O executor that
177 * the socket will use, by default, to dispatch handlers for any asynchronous
178 * operations performed on the socket.
7c673cae
FG
179 *
180 * @param endpoint An endpoint on the local machine to which the datagram
181 * socket will be bound.
182 *
183 * @throws boost::system::system_error Thrown on failure.
184 */
92f5a8d4
TL
185 template <typename ExecutionContext>
186 basic_datagram_socket(ExecutionContext& context,
187 const endpoint_type& endpoint,
188 typename enable_if<
189 is_convertible<ExecutionContext&, execution_context&>::value
190 >::type* = 0)
191 : basic_socket<Protocol, Executor>(context, endpoint)
7c673cae
FG
192 {
193 }
194
195 /// Construct a basic_datagram_socket on an existing native socket.
196 /**
197 * This constructor creates a datagram socket object to hold an existing
198 * native socket.
199 *
92f5a8d4
TL
200 * @param ex The I/O executor that the socket will use, by default, to
201 * dispatch handlers for any asynchronous operations performed on the socket.
7c673cae
FG
202 *
203 * @param protocol An object specifying protocol parameters to be used.
204 *
205 * @param native_socket The new underlying socket implementation.
206 *
207 * @throws boost::system::system_error Thrown on failure.
208 */
92f5a8d4 209 basic_datagram_socket(const executor_type& ex,
7c673cae 210 const protocol_type& protocol, const native_handle_type& native_socket)
92f5a8d4
TL
211 : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
212 {
213 }
214
215 /// Construct a basic_datagram_socket on an existing native socket.
216 /**
217 * This constructor creates a datagram socket object to hold an existing
218 * native socket.
219 *
220 * @param context An execution context which provides the I/O executor that
221 * the socket will use, by default, to dispatch handlers for any asynchronous
222 * operations performed on the socket.
223 *
224 * @param protocol An object specifying protocol parameters to be used.
225 *
226 * @param native_socket The new underlying socket implementation.
227 *
228 * @throws boost::system::system_error Thrown on failure.
229 */
230 template <typename ExecutionContext>
231 basic_datagram_socket(ExecutionContext& context,
232 const protocol_type& protocol, const native_handle_type& native_socket,
233 typename enable_if<
234 is_convertible<ExecutionContext&, execution_context&>::value
235 >::type* = 0)
236 : basic_socket<Protocol, Executor>(context, protocol, native_socket)
7c673cae
FG
237 {
238 }
239
240#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
241 /// Move-construct a basic_datagram_socket from another.
242 /**
243 * This constructor moves a datagram socket from one object to another.
244 *
245 * @param other The other basic_datagram_socket object from which the move
246 * will occur.
247 *
248 * @note Following the move, the moved-from object is in the same state as if
92f5a8d4
TL
249 * constructed using the @c basic_datagram_socket(const executor_type&)
250 * constructor.
7c673cae 251 */
92f5a8d4
TL
252 basic_datagram_socket(basic_datagram_socket&& other) BOOST_ASIO_NOEXCEPT
253 : basic_socket<Protocol, Executor>(std::move(other))
7c673cae
FG
254 {
255 }
256
257 /// Move-assign a basic_datagram_socket from another.
258 /**
259 * This assignment operator moves a datagram socket from one object to
260 * another.
261 *
262 * @param other The other basic_datagram_socket object from which the move
263 * will occur.
264 *
265 * @note Following the move, the moved-from object is in the same state as if
92f5a8d4
TL
266 * constructed using the @c basic_datagram_socket(const executor_type&)
267 * constructor.
7c673cae
FG
268 */
269 basic_datagram_socket& operator=(basic_datagram_socket&& other)
270 {
92f5a8d4 271 basic_socket<Protocol, Executor>::operator=(std::move(other));
7c673cae
FG
272 return *this;
273 }
274
275 /// Move-construct a basic_datagram_socket from a socket of another protocol
276 /// type.
277 /**
278 * This constructor moves a datagram socket from one object to another.
279 *
280 * @param other The other basic_datagram_socket object from which the move
281 * will occur.
282 *
283 * @note Following the move, the moved-from object is in the same state as if
92f5a8d4
TL
284 * constructed using the @c basic_datagram_socket(const executor_type&)
285 * constructor.
7c673cae 286 */
92f5a8d4
TL
287 template <typename Protocol1, typename Executor1>
288 basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
289 typename enable_if<
290 is_convertible<Protocol1, Protocol>::value
291 && is_convertible<Executor1, Executor>::value
292 >::type* = 0)
293 : basic_socket<Protocol, Executor>(std::move(other))
7c673cae
FG
294 {
295 }
296
297 /// Move-assign a basic_datagram_socket from a socket of another protocol
298 /// type.
299 /**
300 * This assignment operator moves a datagram socket from one object to
301 * another.
302 *
303 * @param other The other basic_datagram_socket object from which the move
304 * will occur.
305 *
306 * @note Following the move, the moved-from object is in the same state as if
92f5a8d4
TL
307 * constructed using the @c basic_datagram_socket(const executor_type&)
308 * constructor.
7c673cae 309 */
92f5a8d4
TL
310 template <typename Protocol1, typename Executor1>
311 typename enable_if<
312 is_convertible<Protocol1, Protocol>::value
313 && is_convertible<Executor1, Executor>::value,
314 basic_datagram_socket&
315 >::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)
7c673cae 316 {
92f5a8d4 317 basic_socket<Protocol, Executor>::operator=(std::move(other));
7c673cae
FG
318 return *this;
319 }
320#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
321
b32b8144
FG
322 /// Destroys the socket.
323 /**
324 * This function destroys the socket, cancelling any outstanding asynchronous
325 * operations associated with the socket as if by calling @c cancel.
326 */
327 ~basic_datagram_socket()
328 {
329 }
330
7c673cae
FG
331 /// Send some data on a connected socket.
332 /**
333 * This function is used to send data on the datagram socket. The function
334 * call will block until the data has been sent successfully or an error
335 * occurs.
336 *
337 * @param buffers One ore more data buffers to be sent on the socket.
338 *
339 * @returns The number of bytes sent.
340 *
341 * @throws boost::system::system_error Thrown on failure.
342 *
343 * @note The send operation can only be used with a connected socket. Use
344 * the send_to function to send data on an unconnected datagram socket.
345 *
346 * @par Example
347 * To send a single data buffer use the @ref buffer function as follows:
348 * @code socket.send(boost::asio::buffer(data, size)); @endcode
349 * See the @ref buffer documentation for information on sending multiple
350 * buffers in one go, and how to use it with arrays, boost::array or
351 * std::vector.
352 */
353 template <typename ConstBufferSequence>
354 std::size_t send(const ConstBufferSequence& buffers)
355 {
356 boost::system::error_code ec;
92f5a8d4
TL
357 std::size_t s = this->impl_.get_service().send(
358 this->impl_.get_implementation(), buffers, 0, ec);
7c673cae
FG
359 boost::asio::detail::throw_error(ec, "send");
360 return s;
361 }
362
363 /// Send some data on a connected socket.
364 /**
365 * This function is used to send data on the datagram socket. The function
366 * call will block until the data has been sent successfully or an error
367 * occurs.
368 *
369 * @param buffers One ore more data buffers to be sent on the socket.
370 *
371 * @param flags Flags specifying how the send call is to be made.
372 *
373 * @returns The number of bytes sent.
374 *
375 * @throws boost::system::system_error Thrown on failure.
376 *
377 * @note The send operation can only be used with a connected socket. Use
378 * the send_to function to send data on an unconnected datagram socket.
379 */
380 template <typename ConstBufferSequence>
381 std::size_t send(const ConstBufferSequence& buffers,
382 socket_base::message_flags flags)
383 {
384 boost::system::error_code ec;
92f5a8d4
TL
385 std::size_t s = this->impl_.get_service().send(
386 this->impl_.get_implementation(), buffers, flags, ec);
7c673cae
FG
387 boost::asio::detail::throw_error(ec, "send");
388 return s;
389 }
390
391 /// Send some data on a connected socket.
392 /**
393 * This function is used to send data on the datagram socket. The function
394 * call will block until the data has been sent successfully or an error
395 * occurs.
396 *
397 * @param buffers One or more data buffers to be sent on the socket.
398 *
399 * @param flags Flags specifying how the send call is to be made.
400 *
401 * @param ec Set to indicate what error occurred, if any.
402 *
403 * @returns The number of bytes sent.
404 *
405 * @note The send operation can only be used with a connected socket. Use
406 * the send_to function to send data on an unconnected datagram socket.
407 */
408 template <typename ConstBufferSequence>
409 std::size_t send(const ConstBufferSequence& buffers,
410 socket_base::message_flags flags, boost::system::error_code& ec)
411 {
92f5a8d4
TL
412 return this->impl_.get_service().send(
413 this->impl_.get_implementation(), buffers, flags, ec);
7c673cae
FG
414 }
415
416 /// Start an asynchronous send on a connected socket.
417 /**
418 * This function is used to asynchronously send data on the datagram socket.
419 * The function call always returns immediately.
420 *
421 * @param buffers One or more data buffers to be sent on the socket. Although
422 * the buffers object may be copied as necessary, ownership of the underlying
423 * memory blocks is retained by the caller, which must guarantee that they
424 * remain valid until the handler is called.
425 *
426 * @param handler The handler to be called when the send operation completes.
427 * Copies will be made of the handler as required. The function signature of
428 * the handler must be:
429 * @code void handler(
430 * const boost::system::error_code& error, // Result of operation.
431 * std::size_t bytes_transferred // Number of bytes sent.
432 * ); @endcode
433 * Regardless of whether the asynchronous operation completes immediately or
92f5a8d4
TL
434 * not, the handler will not be invoked from within this function. On
435 * immediate completion, invocation of the handler will be performed in a
436 * manner equivalent to using boost::asio::post().
7c673cae
FG
437 *
438 * @note The async_send operation can only be used with a connected socket.
439 * Use the async_send_to function to send data on an unconnected datagram
440 * socket.
441 *
442 * @par Example
443 * To send a single data buffer use the @ref buffer function as follows:
444 * @code
445 * socket.async_send(boost::asio::buffer(data, size), handler);
446 * @endcode
447 * See the @ref buffer documentation for information on sending multiple
448 * buffers in one go, and how to use it with arrays, boost::array or
449 * std::vector.
450 */
92f5a8d4
TL
451 template <typename ConstBufferSequence,
452 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
453 std::size_t)) WriteHandler
454 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
455 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
7c673cae
FG
456 void (boost::system::error_code, std::size_t))
457 async_send(const ConstBufferSequence& buffers,
92f5a8d4
TL
458 BOOST_ASIO_MOVE_ARG(WriteHandler) handler
459 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 460 {
92f5a8d4
TL
461 return async_initiate<WriteHandler,
462 void (boost::system::error_code, std::size_t)>(
463 initiate_async_send(this), handler,
464 buffers, socket_base::message_flags(0));
7c673cae
FG
465 }
466
467 /// Start an asynchronous send on a connected socket.
468 /**
469 * This function is used to asynchronously send data on the datagram socket.
470 * The function call always returns immediately.
471 *
472 * @param buffers One or more data buffers to be sent on the socket. Although
473 * the buffers object may be copied as necessary, ownership of the underlying
474 * memory blocks is retained by the caller, which must guarantee that they
475 * remain valid until the handler is called.
476 *
477 * @param flags Flags specifying how the send call is to be made.
478 *
479 * @param handler The handler to be called when the send operation completes.
480 * Copies will be made of the handler as required. The function signature of
481 * the handler must be:
482 * @code void handler(
483 * const boost::system::error_code& error, // Result of operation.
484 * std::size_t bytes_transferred // Number of bytes sent.
485 * ); @endcode
486 * Regardless of whether the asynchronous operation completes immediately or
92f5a8d4
TL
487 * not, the handler will not be invoked from within this function. On
488 * immediate completion, invocation of the handler will be performed in a
489 * manner equivalent to using boost::asio::post().
7c673cae
FG
490 *
491 * @note The async_send operation can only be used with a connected socket.
492 * Use the async_send_to function to send data on an unconnected datagram
493 * socket.
494 */
92f5a8d4
TL
495 template <typename ConstBufferSequence,
496 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
497 std::size_t)) WriteHandler
498 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
499 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
7c673cae
FG
500 void (boost::system::error_code, std::size_t))
501 async_send(const ConstBufferSequence& buffers,
502 socket_base::message_flags flags,
92f5a8d4
TL
503 BOOST_ASIO_MOVE_ARG(WriteHandler) handler
504 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 505 {
92f5a8d4
TL
506 return async_initiate<WriteHandler,
507 void (boost::system::error_code, std::size_t)>(
508 initiate_async_send(this), handler, buffers, flags);
7c673cae
FG
509 }
510
511 /// Send a datagram to the specified endpoint.
512 /**
513 * This function is used to send a datagram to the specified remote endpoint.
514 * The function call will block until the data has been sent successfully or
515 * an error occurs.
516 *
517 * @param buffers One or more data buffers to be sent to the remote endpoint.
518 *
519 * @param destination The remote endpoint to which the data will be sent.
520 *
521 * @returns The number of bytes sent.
522 *
523 * @throws boost::system::system_error Thrown on failure.
524 *
525 * @par Example
526 * To send a single data buffer use the @ref buffer function as follows:
527 * @code
528 * boost::asio::ip::udp::endpoint destination(
529 * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
530 * socket.send_to(boost::asio::buffer(data, size), destination);
531 * @endcode
532 * See the @ref buffer documentation for information on sending multiple
533 * buffers in one go, and how to use it with arrays, boost::array or
534 * std::vector.
535 */
536 template <typename ConstBufferSequence>
537 std::size_t send_to(const ConstBufferSequence& buffers,
538 const endpoint_type& destination)
539 {
540 boost::system::error_code ec;
92f5a8d4
TL
541 std::size_t s = this->impl_.get_service().send_to(
542 this->impl_.get_implementation(), buffers, destination, 0, ec);
7c673cae
FG
543 boost::asio::detail::throw_error(ec, "send_to");
544 return s;
545 }
546
547 /// Send a datagram to the specified endpoint.
548 /**
549 * This function is used to send a datagram to the specified remote endpoint.
550 * The function call will block until the data has been sent successfully or
551 * an error occurs.
552 *
553 * @param buffers One or more data buffers to be sent to the remote endpoint.
554 *
555 * @param destination The remote endpoint to which the data will be sent.
556 *
557 * @param flags Flags specifying how the send call is to be made.
558 *
559 * @returns The number of bytes sent.
560 *
561 * @throws boost::system::system_error Thrown on failure.
562 */
563 template <typename ConstBufferSequence>
564 std::size_t send_to(const ConstBufferSequence& buffers,
565 const endpoint_type& destination, socket_base::message_flags flags)
566 {
567 boost::system::error_code ec;
92f5a8d4
TL
568 std::size_t s = this->impl_.get_service().send_to(
569 this->impl_.get_implementation(), buffers, destination, flags, ec);
7c673cae
FG
570 boost::asio::detail::throw_error(ec, "send_to");
571 return s;
572 }
573
574 /// Send a datagram to the specified endpoint.
575 /**
576 * This function is used to send a datagram to the specified remote endpoint.
577 * The function call will block until the data has been sent successfully or
578 * an error occurs.
579 *
580 * @param buffers One or more data buffers to be sent to the remote endpoint.
581 *
582 * @param destination The remote endpoint to which the data will be sent.
583 *
584 * @param flags Flags specifying how the send call is to be made.
585 *
586 * @param ec Set to indicate what error occurred, if any.
587 *
588 * @returns The number of bytes sent.
589 */
590 template <typename ConstBufferSequence>
591 std::size_t send_to(const ConstBufferSequence& buffers,
592 const endpoint_type& destination, socket_base::message_flags flags,
593 boost::system::error_code& ec)
594 {
92f5a8d4 595 return this->impl_.get_service().send_to(this->impl_.get_implementation(),
7c673cae
FG
596 buffers, destination, flags, ec);
597 }
598
599 /// Start an asynchronous send.
600 /**
601 * This function is used to asynchronously send a datagram to the specified
602 * remote endpoint. The function call always returns immediately.
603 *
604 * @param buffers One or more data buffers to be sent to the remote endpoint.
605 * Although the buffers object may be copied as necessary, ownership of the
606 * underlying memory blocks is retained by the caller, which must guarantee
607 * that they remain valid until the handler is called.
608 *
609 * @param destination The remote endpoint to which the data will be sent.
610 * Copies will be made of the endpoint as required.
611 *
612 * @param handler The handler to be called when the send operation completes.
613 * Copies will be made of the handler as required. The function signature of
614 * the handler must be:
615 * @code void handler(
616 * const boost::system::error_code& error, // Result of operation.
617 * std::size_t bytes_transferred // Number of bytes sent.
618 * ); @endcode
619 * Regardless of whether the asynchronous operation completes immediately or
92f5a8d4
TL
620 * not, the handler will not be invoked from within this function. On
621 * immediate completion, invocation of the handler will be performed in a
622 * manner equivalent to using boost::asio::post().
7c673cae
FG
623 *
624 * @par Example
625 * To send a single data buffer use the @ref buffer function as follows:
626 * @code
627 * boost::asio::ip::udp::endpoint destination(
628 * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
629 * socket.async_send_to(
630 * boost::asio::buffer(data, size), destination, handler);
631 * @endcode
632 * See the @ref buffer documentation for information on sending multiple
633 * buffers in one go, and how to use it with arrays, boost::array or
634 * std::vector.
635 */
92f5a8d4
TL
636 template <typename ConstBufferSequence,
637 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
638 std::size_t)) WriteHandler
639 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
640 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
7c673cae
FG
641 void (boost::system::error_code, std::size_t))
642 async_send_to(const ConstBufferSequence& buffers,
643 const endpoint_type& destination,
92f5a8d4
TL
644 BOOST_ASIO_MOVE_ARG(WriteHandler) handler
645 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 646 {
92f5a8d4
TL
647 return async_initiate<WriteHandler,
648 void (boost::system::error_code, std::size_t)>(
649 initiate_async_send_to(this), handler, buffers,
650 destination, socket_base::message_flags(0));
7c673cae
FG
651 }
652
653 /// Start an asynchronous send.
654 /**
655 * This function is used to asynchronously send a datagram to the specified
656 * remote endpoint. The function call always returns immediately.
657 *
658 * @param buffers One or more data buffers to be sent to the remote endpoint.
659 * Although the buffers object may be copied as necessary, ownership of the
660 * underlying memory blocks is retained by the caller, which must guarantee
661 * that they remain valid until the handler is called.
662 *
663 * @param flags Flags specifying how the send call is to be made.
664 *
665 * @param destination The remote endpoint to which the data will be sent.
666 * Copies will be made of the endpoint as required.
667 *
668 * @param handler The handler to be called when the send operation completes.
669 * Copies will be made of the handler as required. The function signature of
670 * the handler must be:
671 * @code void handler(
672 * const boost::system::error_code& error, // Result of operation.
673 * std::size_t bytes_transferred // Number of bytes sent.
674 * ); @endcode
675 * Regardless of whether the asynchronous operation completes immediately or
92f5a8d4
TL
676 * not, the handler will not be invoked from within this function. On
677 * immediate completion, invocation of the handler will be performed in a
678 * manner equivalent to using boost::asio::post().
7c673cae 679 */
92f5a8d4
TL
680 template <typename ConstBufferSequence,
681 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
682 std::size_t)) WriteHandler
683 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
684 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
7c673cae
FG
685 void (boost::system::error_code, std::size_t))
686 async_send_to(const ConstBufferSequence& buffers,
687 const endpoint_type& destination, socket_base::message_flags flags,
92f5a8d4
TL
688 BOOST_ASIO_MOVE_ARG(WriteHandler) handler
689 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 690 {
92f5a8d4
TL
691 return async_initiate<WriteHandler,
692 void (boost::system::error_code, std::size_t)>(
693 initiate_async_send_to(this), handler, buffers, destination, flags);
7c673cae
FG
694 }
695
696 /// Receive some data on a connected socket.
697 /**
698 * This function is used to receive data on the datagram socket. The function
699 * call will block until data has been received successfully or an error
700 * occurs.
701 *
702 * @param buffers One or more buffers into which the data will be received.
703 *
704 * @returns The number of bytes received.
705 *
706 * @throws boost::system::system_error Thrown on failure.
707 *
708 * @note The receive operation can only be used with a connected socket. Use
709 * the receive_from function to receive data on an unconnected datagram
710 * socket.
711 *
712 * @par Example
713 * To receive into a single data buffer use the @ref buffer function as
714 * follows:
715 * @code socket.receive(boost::asio::buffer(data, size)); @endcode
716 * See the @ref buffer documentation for information on receiving into
717 * multiple buffers in one go, and how to use it with arrays, boost::array or
718 * std::vector.
719 */
720 template <typename MutableBufferSequence>
721 std::size_t receive(const MutableBufferSequence& buffers)
722 {
723 boost::system::error_code ec;
92f5a8d4
TL
724 std::size_t s = this->impl_.get_service().receive(
725 this->impl_.get_implementation(), buffers, 0, ec);
7c673cae
FG
726 boost::asio::detail::throw_error(ec, "receive");
727 return s;
728 }
729
730 /// Receive some data on a connected socket.
731 /**
732 * This function is used to receive data on the datagram socket. The function
733 * call will block until data has been received successfully or an error
734 * occurs.
735 *
736 * @param buffers One or more buffers into which the data will be received.
737 *
738 * @param flags Flags specifying how the receive call is to be made.
739 *
740 * @returns The number of bytes received.
741 *
742 * @throws boost::system::system_error Thrown on failure.
743 *
744 * @note The receive operation can only be used with a connected socket. Use
745 * the receive_from function to receive data on an unconnected datagram
746 * socket.
747 */
748 template <typename MutableBufferSequence>
749 std::size_t receive(const MutableBufferSequence& buffers,
750 socket_base::message_flags flags)
751 {
752 boost::system::error_code ec;
92f5a8d4
TL
753 std::size_t s = this->impl_.get_service().receive(
754 this->impl_.get_implementation(), buffers, flags, ec);
7c673cae
FG
755 boost::asio::detail::throw_error(ec, "receive");
756 return s;
757 }
758
759 /// Receive some data on a connected socket.
760 /**
761 * This function is used to receive data on the datagram socket. The function
762 * call will block until data has been received successfully or an error
763 * occurs.
764 *
765 * @param buffers One or more buffers into which the data will be received.
766 *
767 * @param flags Flags specifying how the receive call is to be made.
768 *
769 * @param ec Set to indicate what error occurred, if any.
770 *
771 * @returns The number of bytes received.
772 *
773 * @note The receive operation can only be used with a connected socket. Use
774 * the receive_from function to receive data on an unconnected datagram
775 * socket.
776 */
777 template <typename MutableBufferSequence>
778 std::size_t receive(const MutableBufferSequence& buffers,
779 socket_base::message_flags flags, boost::system::error_code& ec)
780 {
92f5a8d4
TL
781 return this->impl_.get_service().receive(
782 this->impl_.get_implementation(), buffers, flags, ec);
7c673cae
FG
783 }
784
785 /// Start an asynchronous receive on a connected socket.
786 /**
787 * This function is used to asynchronously receive data from the datagram
788 * socket. The function call always returns immediately.
789 *
790 * @param buffers One or more buffers into which the data will be received.
791 * Although the buffers object may be copied as necessary, ownership of the
792 * underlying memory blocks is retained by the caller, which must guarantee
793 * that they remain valid until the handler is called.
794 *
795 * @param handler The handler to be called when the receive operation
796 * completes. Copies will be made of the handler as required. The function
797 * signature of the handler must be:
798 * @code void handler(
799 * const boost::system::error_code& error, // Result of operation.
800 * std::size_t bytes_transferred // Number of bytes received.
801 * ); @endcode
802 * Regardless of whether the asynchronous operation completes immediately or
92f5a8d4
TL
803 * not, the handler will not be invoked from within this function. On
804 * immediate completion, invocation of the handler will be performed in a
805 * manner equivalent to using boost::asio::post().
7c673cae
FG
806 *
807 * @note The async_receive operation can only be used with a connected socket.
808 * Use the async_receive_from function to receive data on an unconnected
809 * datagram socket.
810 *
811 * @par Example
812 * To receive into a single data buffer use the @ref buffer function as
813 * follows:
814 * @code
815 * socket.async_receive(boost::asio::buffer(data, size), handler);
816 * @endcode
817 * See the @ref buffer documentation for information on receiving into
818 * multiple buffers in one go, and how to use it with arrays, boost::array or
819 * std::vector.
820 */
92f5a8d4
TL
821 template <typename MutableBufferSequence,
822 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
823 std::size_t)) ReadHandler
824 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
825 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
7c673cae
FG
826 void (boost::system::error_code, std::size_t))
827 async_receive(const MutableBufferSequence& buffers,
92f5a8d4
TL
828 BOOST_ASIO_MOVE_ARG(ReadHandler) handler
829 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 830 {
92f5a8d4
TL
831 return async_initiate<ReadHandler,
832 void (boost::system::error_code, std::size_t)>(
833 initiate_async_receive(this), handler,
834 buffers, socket_base::message_flags(0));
7c673cae
FG
835 }
836
837 /// Start an asynchronous receive on a connected socket.
838 /**
839 * This function is used to asynchronously receive data from the datagram
840 * socket. The function call always returns immediately.
841 *
842 * @param buffers One or more buffers into which the data will be received.
843 * Although the buffers object may be copied as necessary, ownership of the
844 * underlying memory blocks is retained by the caller, which must guarantee
845 * that they remain valid until the handler is called.
846 *
847 * @param flags Flags specifying how the receive call is to be made.
848 *
849 * @param handler The handler to be called when the receive operation
850 * completes. Copies will be made of the handler as required. The function
851 * signature of the handler must be:
852 * @code void handler(
853 * const boost::system::error_code& error, // Result of operation.
854 * std::size_t bytes_transferred // Number of bytes received.
855 * ); @endcode
856 * Regardless of whether the asynchronous operation completes immediately or
92f5a8d4
TL
857 * not, the handler will not be invoked from within this function. On
858 * immediate completion, invocation of the handler will be performed in a
859 * manner equivalent to using boost::asio::post().
7c673cae
FG
860 *
861 * @note The async_receive operation can only be used with a connected socket.
862 * Use the async_receive_from function to receive data on an unconnected
863 * datagram socket.
864 */
92f5a8d4
TL
865 template <typename MutableBufferSequence,
866 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
867 std::size_t)) ReadHandler
868 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
869 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
7c673cae
FG
870 void (boost::system::error_code, std::size_t))
871 async_receive(const MutableBufferSequence& buffers,
872 socket_base::message_flags flags,
92f5a8d4
TL
873 BOOST_ASIO_MOVE_ARG(ReadHandler) handler
874 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 875 {
92f5a8d4
TL
876 return async_initiate<ReadHandler,
877 void (boost::system::error_code, std::size_t)>(
878 initiate_async_receive(this), handler, buffers, flags);
7c673cae
FG
879 }
880
881 /// Receive a datagram with the endpoint of the sender.
882 /**
883 * This function is used to receive a datagram. The function call will block
884 * until data has been received successfully or an error occurs.
885 *
886 * @param buffers One or more buffers into which the data will be received.
887 *
888 * @param sender_endpoint An endpoint object that receives the endpoint of
889 * the remote sender of the datagram.
890 *
891 * @returns The number of bytes received.
892 *
893 * @throws boost::system::system_error Thrown on failure.
894 *
895 * @par Example
896 * To receive into a single data buffer use the @ref buffer function as
897 * follows:
898 * @code
899 * boost::asio::ip::udp::endpoint sender_endpoint;
900 * socket.receive_from(
901 * boost::asio::buffer(data, size), sender_endpoint);
902 * @endcode
903 * See the @ref buffer documentation for information on receiving into
904 * multiple buffers in one go, and how to use it with arrays, boost::array or
905 * std::vector.
906 */
907 template <typename MutableBufferSequence>
908 std::size_t receive_from(const MutableBufferSequence& buffers,
909 endpoint_type& sender_endpoint)
910 {
911 boost::system::error_code ec;
92f5a8d4
TL
912 std::size_t s = this->impl_.get_service().receive_from(
913 this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
7c673cae
FG
914 boost::asio::detail::throw_error(ec, "receive_from");
915 return s;
916 }
917
918 /// Receive a datagram with the endpoint of the sender.
919 /**
920 * This function is used to receive a datagram. The function call will block
921 * until data has been received successfully or an error occurs.
922 *
923 * @param buffers One or more buffers into which the data will be received.
924 *
925 * @param sender_endpoint An endpoint object that receives the endpoint of
926 * the remote sender of the datagram.
927 *
928 * @param flags Flags specifying how the receive call is to be made.
929 *
930 * @returns The number of bytes received.
931 *
932 * @throws boost::system::system_error Thrown on failure.
933 */
934 template <typename MutableBufferSequence>
935 std::size_t receive_from(const MutableBufferSequence& buffers,
936 endpoint_type& sender_endpoint, socket_base::message_flags flags)
937 {
938 boost::system::error_code ec;
92f5a8d4
TL
939 std::size_t s = this->impl_.get_service().receive_from(
940 this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
7c673cae
FG
941 boost::asio::detail::throw_error(ec, "receive_from");
942 return s;
943 }
944
945 /// Receive a datagram with the endpoint of the sender.
946 /**
947 * This function is used to receive a datagram. The function call will block
948 * until data has been received successfully or an error occurs.
949 *
950 * @param buffers One or more buffers into which the data will be received.
951 *
952 * @param sender_endpoint An endpoint object that receives the endpoint of
953 * the remote sender of the datagram.
954 *
955 * @param flags Flags specifying how the receive call is to be made.
956 *
957 * @param ec Set to indicate what error occurred, if any.
958 *
959 * @returns The number of bytes received.
960 */
961 template <typename MutableBufferSequence>
962 std::size_t receive_from(const MutableBufferSequence& buffers,
963 endpoint_type& sender_endpoint, socket_base::message_flags flags,
964 boost::system::error_code& ec)
965 {
92f5a8d4
TL
966 return this->impl_.get_service().receive_from(
967 this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
7c673cae
FG
968 }
969
970 /// Start an asynchronous receive.
971 /**
972 * This function is used to asynchronously receive a datagram. The function
973 * call always returns immediately.
974 *
975 * @param buffers One or more buffers into which the data will be received.
976 * Although the buffers object may be copied as necessary, ownership of the
977 * underlying memory blocks is retained by the caller, which must guarantee
978 * that they remain valid until the handler is called.
979 *
980 * @param sender_endpoint An endpoint object that receives the endpoint of
981 * the remote sender of the datagram. Ownership of the sender_endpoint object
982 * is retained by the caller, which must guarantee that it is valid until the
983 * handler is called.
984 *
985 * @param handler The handler to be called when the receive operation
986 * completes. Copies will be made of the handler as required. The function
987 * signature of the handler must be:
988 * @code void handler(
989 * const boost::system::error_code& error, // Result of operation.
990 * std::size_t bytes_transferred // Number of bytes received.
991 * ); @endcode
992 * Regardless of whether the asynchronous operation completes immediately or
92f5a8d4
TL
993 * not, the handler will not be invoked from within this function. On
994 * immediate completion, invocation of the handler will be performed in a
995 * manner equivalent to using boost::asio::post().
7c673cae
FG
996 *
997 * @par Example
998 * To receive into a single data buffer use the @ref buffer function as
999 * follows:
1000 * @code socket.async_receive_from(
1001 * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode
1002 * See the @ref buffer documentation for information on receiving into
1003 * multiple buffers in one go, and how to use it with arrays, boost::array or
1004 * std::vector.
1005 */
92f5a8d4
TL
1006 template <typename MutableBufferSequence,
1007 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1008 std::size_t)) ReadHandler
1009 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1010 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
7c673cae
FG
1011 void (boost::system::error_code, std::size_t))
1012 async_receive_from(const MutableBufferSequence& buffers,
1013 endpoint_type& sender_endpoint,
92f5a8d4
TL
1014 BOOST_ASIO_MOVE_ARG(ReadHandler) handler
1015 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 1016 {
92f5a8d4
TL
1017 return async_initiate<ReadHandler,
1018 void (boost::system::error_code, std::size_t)>(
1019 initiate_async_receive_from(this), handler, buffers,
1020 &sender_endpoint, socket_base::message_flags(0));
7c673cae
FG
1021 }
1022
1023 /// Start an asynchronous receive.
1024 /**
1025 * This function is used to asynchronously receive a datagram. The function
1026 * call always returns immediately.
1027 *
1028 * @param buffers One or more buffers into which the data will be received.
1029 * Although the buffers object may be copied as necessary, ownership of the
1030 * underlying memory blocks is retained by the caller, which must guarantee
1031 * that they remain valid until the handler is called.
1032 *
1033 * @param sender_endpoint An endpoint object that receives the endpoint of
1034 * the remote sender of the datagram. Ownership of the sender_endpoint object
1035 * is retained by the caller, which must guarantee that it is valid until the
1036 * handler is called.
1037 *
1038 * @param flags Flags specifying how the receive call is to be made.
1039 *
1040 * @param handler The handler to be called when the receive operation
1041 * completes. Copies will be made of the handler as required. The function
1042 * signature of the handler must be:
1043 * @code void handler(
1044 * const boost::system::error_code& error, // Result of operation.
1045 * std::size_t bytes_transferred // Number of bytes received.
1046 * ); @endcode
1047 * Regardless of whether the asynchronous operation completes immediately or
92f5a8d4
TL
1048 * not, the handler will not be invoked from within this function. On
1049 * immediate completion, invocation of the handler will be performed in a
1050 * manner equivalent to using boost::asio::post().
7c673cae 1051 */
92f5a8d4
TL
1052 template <typename MutableBufferSequence,
1053 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1054 std::size_t)) ReadHandler
1055 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1056 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
7c673cae
FG
1057 void (boost::system::error_code, std::size_t))
1058 async_receive_from(const MutableBufferSequence& buffers,
1059 endpoint_type& sender_endpoint, socket_base::message_flags flags,
92f5a8d4
TL
1060 BOOST_ASIO_MOVE_ARG(ReadHandler) handler
1061 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
7c673cae 1062 {
92f5a8d4
TL
1063 return async_initiate<ReadHandler,
1064 void (boost::system::error_code, std::size_t)>(
1065 initiate_async_receive_from(this), handler,
1066 buffers, &sender_endpoint, flags);
7c673cae 1067 }
92f5a8d4
TL
1068
1069private:
20effc67
TL
1070 // Disallow copying and assignment.
1071 basic_datagram_socket(const basic_datagram_socket&) BOOST_ASIO_DELETED;
1072 basic_datagram_socket& operator=(
1073 const basic_datagram_socket&) BOOST_ASIO_DELETED;
1074
92f5a8d4
TL
1075 class initiate_async_send
1076 {
1077 public:
1078 typedef Executor executor_type;
1079
1080 explicit initiate_async_send(basic_datagram_socket* self)
1081 : self_(self)
1082 {
1083 }
1084
1085 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
1086 {
1087 return self_->get_executor();
1088 }
1089
1090 template <typename WriteHandler, typename ConstBufferSequence>
1091 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1092 const ConstBufferSequence& buffers,
1093 socket_base::message_flags flags) const
1094 {
1095 // If you get an error on the following line it means that your handler
1096 // does not meet the documented type requirements for a WriteHandler.
1097 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
1098
1099 detail::non_const_lvalue<WriteHandler> handler2(handler);
1100 self_->impl_.get_service().async_send(
1101 self_->impl_.get_implementation(), buffers, flags,
20effc67 1102 handler2.value, self_->impl_.get_executor());
92f5a8d4
TL
1103 }
1104
1105 private:
1106 basic_datagram_socket* self_;
1107 };
1108
1109 class initiate_async_send_to
1110 {
1111 public:
1112 typedef Executor executor_type;
1113
1114 explicit initiate_async_send_to(basic_datagram_socket* self)
1115 : self_(self)
1116 {
1117 }
1118
1119 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
1120 {
1121 return self_->get_executor();
1122 }
1123
1124 template <typename WriteHandler, typename ConstBufferSequence>
1125 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1126 const ConstBufferSequence& buffers, const endpoint_type& destination,
1127 socket_base::message_flags flags) const
1128 {
1129 // If you get an error on the following line it means that your handler
1130 // does not meet the documented type requirements for a WriteHandler.
1131 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
1132
1133 detail::non_const_lvalue<WriteHandler> handler2(handler);
1134 self_->impl_.get_service().async_send_to(
20effc67
TL
1135 self_->impl_.get_implementation(), buffers, destination,
1136 flags, handler2.value, self_->impl_.get_executor());
92f5a8d4
TL
1137 }
1138
1139 private:
1140 basic_datagram_socket* self_;
1141 };
1142
1143 class initiate_async_receive
1144 {
1145 public:
1146 typedef Executor executor_type;
1147
1148 explicit initiate_async_receive(basic_datagram_socket* self)
1149 : self_(self)
1150 {
1151 }
1152
1153 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
1154 {
1155 return self_->get_executor();
1156 }
1157
1158 template <typename ReadHandler, typename MutableBufferSequence>
1159 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
1160 const MutableBufferSequence& buffers,
1161 socket_base::message_flags flags) const
1162 {
1163 // If you get an error on the following line it means that your handler
1164 // does not meet the documented type requirements for a ReadHandler.
1165 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
1166
1167 detail::non_const_lvalue<ReadHandler> handler2(handler);
1168 self_->impl_.get_service().async_receive(
1169 self_->impl_.get_implementation(), buffers, flags,
20effc67 1170 handler2.value, self_->impl_.get_executor());
92f5a8d4
TL
1171 }
1172
1173 private:
1174 basic_datagram_socket* self_;
1175 };
1176
1177 class initiate_async_receive_from
1178 {
1179 public:
1180 typedef Executor executor_type;
1181
1182 explicit initiate_async_receive_from(basic_datagram_socket* self)
1183 : self_(self)
1184 {
1185 }
1186
1187 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
1188 {
1189 return self_->get_executor();
1190 }
1191
1192 template <typename ReadHandler, typename MutableBufferSequence>
1193 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
1194 const MutableBufferSequence& buffers, endpoint_type* sender_endpoint,
1195 socket_base::message_flags flags) const
1196 {
1197 // If you get an error on the following line it means that your handler
1198 // does not meet the documented type requirements for a ReadHandler.
1199 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
1200
1201 detail::non_const_lvalue<ReadHandler> handler2(handler);
1202 self_->impl_.get_service().async_receive_from(
20effc67
TL
1203 self_->impl_.get_implementation(), buffers, *sender_endpoint,
1204 flags, handler2.value, self_->impl_.get_executor());
92f5a8d4
TL
1205 }
1206
1207 private:
1208 basic_datagram_socket* self_;
1209 };
7c673cae
FG
1210};
1211
1212} // namespace asio
1213} // namespace boost
1214
1215#include <boost/asio/detail/pop_options.hpp>
1216
1217#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP