1 //
2 // basic_socket_acceptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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 ASIO_BASIC_SOCKET_ACCEPTOR_HPP
12 #define ASIO_BASIC_SOCKET_ACCEPTOR_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include "asio/basic_io_object.hpp"
20 #include "asio/basic_socket.hpp"
21 #include "asio/detail/handler_type_requirements.hpp"
22 #include "asio/detail/throw_error.hpp"
23 #include "asio/detail/type_traits.hpp"
24 #include "asio/error.hpp"
25 #include "asio/socket_base.hpp"
26 
27 #if defined(ASIO_HAS_MOVE)
28 # include <utility>
29 #endif // defined(ASIO_HAS_MOVE)
30 
31 #if defined(ASIO_ENABLE_OLD_SERVICES)
32 # include "asio/socket_acceptor_service.hpp"
33 #else // defined(ASIO_ENABLE_OLD_SERVICES)
34 # if defined(ASIO_WINDOWS_RUNTIME)
35 #  include "asio/detail/null_socket_service.hpp"
36 #  define ASIO_SVC_T detail::null_socket_service<Protocol>
37 # elif defined(ASIO_HAS_IOCP)
38 #  include "asio/detail/win_iocp_socket_service.hpp"
39 #  define ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
40 # else
41 #  include "asio/detail/reactive_socket_service.hpp"
42 #  define ASIO_SVC_T detail::reactive_socket_service<Protocol>
43 # endif
44 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
45 
46 #include "asio/detail/push_options.hpp"
47 
48 namespace asio {
49 
50 /// Provides the ability to accept new connections.
51 /**
52  * The basic_socket_acceptor class template is used for accepting new socket
53  * connections.
54  *
55  * @par Thread Safety
56  * @e Distinct @e objects: Safe.@n
57  * @e Shared @e objects: Unsafe.
58  *
59  * @par Example
60  * Opening a socket acceptor with the SO_REUSEADDR option enabled:
61  * @code
62  * asio::ip::tcp::acceptor acceptor(io_context);
63  * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
64  * acceptor.open(endpoint.protocol());
65  * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
66  * acceptor.bind(endpoint);
67  * acceptor.listen();
68  * @endcode
69  */
70 template <typename Protocol
71     ASIO_SVC_TPARAM_DEF1(= socket_acceptor_service<Protocol>)>
72 class basic_socket_acceptor
73   : ASIO_SVC_ACCESS basic_io_object<ASIO_SVC_T>,
74     public socket_base
75 {
76 public:
77   /// The type of the executor associated with the object.
78   typedef io_context::executor_type executor_type;
79 
80   /// The native representation of an acceptor.
81 #if defined(GENERATING_DOCUMENTATION)
82   typedef implementation_defined native_handle_type;
83 #else
84   typedef typename ASIO_SVC_T::native_handle_type native_handle_type;
85 #endif
86 
87   /// The protocol type.
88   typedef Protocol protocol_type;
89 
90   /// The endpoint type.
91   typedef typename Protocol::endpoint endpoint_type;
92 
93   /// Construct an acceptor without opening it.
94   /**
95    * This constructor creates an acceptor without opening it to listen for new
96    * connections. The open() function must be called before the acceptor can
97    * accept new socket connections.
98    *
99    * @param io_context The io_context object that the acceptor will use to
100    * dispatch handlers for any asynchronous operations performed on the
101    * acceptor.
102    */
basic_socket_acceptor(asio::io_context & io_context)103   explicit basic_socket_acceptor(asio::io_context& io_context)
104     : basic_io_object<ASIO_SVC_T>(io_context)
105   {
106   }
107 
108   /// Construct an open acceptor.
109   /**
110    * This constructor creates an acceptor and automatically opens it.
111    *
112    * @param io_context The io_context object that the acceptor will use to
113    * dispatch handlers for any asynchronous operations performed on the
114    * acceptor.
115    *
116    * @param protocol An object specifying protocol parameters to be used.
117    *
118    * @throws asio::system_error Thrown on failure.
119    */
basic_socket_acceptor(asio::io_context & io_context,const protocol_type & protocol)120   basic_socket_acceptor(asio::io_context& io_context,
121       const protocol_type& protocol)
122     : basic_io_object<ASIO_SVC_T>(io_context)
123   {
124     asio::error_code ec;
125     this->get_service().open(this->get_implementation(), protocol, ec);
126     asio::detail::throw_error(ec, "open");
127   }
128 
129   /// Construct an acceptor opened on the given endpoint.
130   /**
131    * This constructor creates an acceptor and automatically opens it to listen
132    * for new connections on the specified endpoint.
133    *
134    * @param io_context The io_context object that the acceptor will use to
135    * dispatch handlers for any asynchronous operations performed on the
136    * acceptor.
137    *
138    * @param endpoint An endpoint on the local machine on which the acceptor
139    * will listen for new connections.
140    *
141    * @param reuse_addr Whether the constructor should set the socket option
142    * socket_base::reuse_address.
143    *
144    * @throws asio::system_error Thrown on failure.
145    *
146    * @note This constructor is equivalent to the following code:
147    * @code
148    * basic_socket_acceptor<Protocol> acceptor(io_context);
149    * acceptor.open(endpoint.protocol());
150    * if (reuse_addr)
151    *   acceptor.set_option(socket_base::reuse_address(true));
152    * acceptor.bind(endpoint);
153    * acceptor.listen(listen_backlog);
154    * @endcode
155    */
basic_socket_acceptor(asio::io_context & io_context,const endpoint_type & endpoint,bool reuse_addr=true)156   basic_socket_acceptor(asio::io_context& io_context,
157       const endpoint_type& endpoint, bool reuse_addr = true)
158     : basic_io_object<ASIO_SVC_T>(io_context)
159   {
160     asio::error_code ec;
161     const protocol_type protocol = endpoint.protocol();
162     this->get_service().open(this->get_implementation(), protocol, ec);
163     asio::detail::throw_error(ec, "open");
164     if (reuse_addr)
165     {
166       this->get_service().set_option(this->get_implementation(),
167           socket_base::reuse_address(true), ec);
168       asio::detail::throw_error(ec, "set_option");
169     }
170     this->get_service().bind(this->get_implementation(), endpoint, ec);
171     asio::detail::throw_error(ec, "bind");
172     this->get_service().listen(this->get_implementation(),
173         socket_base::max_listen_connections, ec);
174     asio::detail::throw_error(ec, "listen");
175   }
176 
177   /// Construct a basic_socket_acceptor on an existing native acceptor.
178   /**
179    * This constructor creates an acceptor object to hold an existing native
180    * acceptor.
181    *
182    * @param io_context The io_context object that the acceptor will use to
183    * dispatch handlers for any asynchronous operations performed on the
184    * acceptor.
185    *
186    * @param protocol An object specifying protocol parameters to be used.
187    *
188    * @param native_acceptor A native acceptor.
189    *
190    * @throws asio::system_error Thrown on failure.
191    */
basic_socket_acceptor(asio::io_context & io_context,const protocol_type & protocol,const native_handle_type & native_acceptor)192   basic_socket_acceptor(asio::io_context& io_context,
193       const protocol_type& protocol, const native_handle_type& native_acceptor)
194     : basic_io_object<ASIO_SVC_T>(io_context)
195   {
196     asio::error_code ec;
197     this->get_service().assign(this->get_implementation(),
198         protocol, native_acceptor, ec);
199     asio::detail::throw_error(ec, "assign");
200   }
201 
202 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
203   /// Move-construct a basic_socket_acceptor from another.
204   /**
205    * This constructor moves an acceptor from one object to another.
206    *
207    * @param other The other basic_socket_acceptor object from which the move
208    * will occur.
209    *
210    * @note Following the move, the moved-from object is in the same state as if
211    * constructed using the @c basic_socket_acceptor(io_context&) constructor.
212    */
basic_socket_acceptor(basic_socket_acceptor && other)213   basic_socket_acceptor(basic_socket_acceptor&& other)
214     : basic_io_object<ASIO_SVC_T>(std::move(other))
215   {
216   }
217 
218   /// Move-assign a basic_socket_acceptor from another.
219   /**
220    * This assignment operator moves an acceptor from one object to another.
221    *
222    * @param other The other basic_socket_acceptor object from which the move
223    * will occur.
224    *
225    * @note Following the move, the moved-from object is in the same state as if
226    * constructed using the @c basic_socket_acceptor(io_context&) constructor.
227    */
operator =(basic_socket_acceptor && other)228   basic_socket_acceptor& operator=(basic_socket_acceptor&& other)
229   {
230     basic_io_object<ASIO_SVC_T>::operator=(std::move(other));
231     return *this;
232   }
233 
234   // All socket acceptors have access to each other's implementations.
235   template <typename Protocol1 ASIO_SVC_TPARAM1>
236   friend class basic_socket_acceptor;
237 
238   /// Move-construct a basic_socket_acceptor from an acceptor of another
239   /// protocol type.
240   /**
241    * This constructor moves an acceptor from one object to another.
242    *
243    * @param other The other basic_socket_acceptor object from which the move
244    * will occur.
245    *
246    * @note Following the move, the moved-from object is in the same state as if
247    * constructed using the @c basic_socket(io_context&) constructor.
248    */
249   template <typename Protocol1 ASIO_SVC_TPARAM1>
basic_socket_acceptor(basic_socket_acceptor<Protocol1 ASIO_SVC_TARG1> && other,typename enable_if<is_convertible<Protocol1,Protocol>::value>::type * =0)250   basic_socket_acceptor(
251       basic_socket_acceptor<Protocol1 ASIO_SVC_TARG1>&& other,
252       typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
253     : basic_io_object<ASIO_SVC_T>(
254         other.get_service().get_io_context())
255   {
256     this->get_service().template converting_move_construct<Protocol1>(
257         this->get_implementation(), other.get_implementation());
258   }
259 
260   /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
261   /// type.
262   /**
263    * This assignment operator moves an acceptor from one object to another.
264    *
265    * @param other The other basic_socket_acceptor object from which the move
266    * will occur.
267    *
268    * @note Following the move, the moved-from object is in the same state as if
269    * constructed using the @c basic_socket(io_context&) constructor.
270    */
271   template <typename Protocol1 ASIO_SVC_TPARAM1>
272   typename enable_if<is_convertible<Protocol1, Protocol>::value,
operator =(basic_socket_acceptor<Protocol1 ASIO_SVC_TARG1> && other)273       basic_socket_acceptor>::type& operator=(
274         basic_socket_acceptor<Protocol1 ASIO_SVC_TARG1>&& other)
275   {
276     basic_socket_acceptor tmp(std::move(other));
277     basic_io_object<ASIO_SVC_T>::operator=(std::move(tmp));
278     return *this;
279   }
280 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
281 
282   /// Destroys the acceptor.
283   /**
284    * This function destroys the acceptor, cancelling any outstanding
285    * asynchronous operations associated with the acceptor as if by calling
286    * @c cancel.
287    */
~basic_socket_acceptor()288   ~basic_socket_acceptor()
289   {
290   }
291 
292 #if defined(ASIO_ENABLE_OLD_SERVICES)
293   // These functions are provided by basic_io_object<>.
294 #else // defined(ASIO_ENABLE_OLD_SERVICES)
295 #if !defined(ASIO_NO_DEPRECATED)
296   /// (Deprecated: Use get_executor().) Get the io_context associated with the
297   /// object.
298   /**
299    * This function may be used to obtain the io_context object that the I/O
300    * object uses to dispatch handlers for asynchronous operations.
301    *
302    * @return A reference to the io_context object that the I/O object will use
303    * to dispatch handlers. Ownership is not transferred to the caller.
304    */
get_io_context()305   asio::io_context& get_io_context()
306   {
307     return basic_io_object<ASIO_SVC_T>::get_io_context();
308   }
309 
310   /// (Deprecated: Use get_executor().) Get the io_context associated with the
311   /// object.
312   /**
313    * This function may be used to obtain the io_context object that the I/O
314    * object uses to dispatch handlers for asynchronous operations.
315    *
316    * @return A reference to the io_context object that the I/O object will use
317    * to dispatch handlers. Ownership is not transferred to the caller.
318    */
get_io_service()319   asio::io_context& get_io_service()
320   {
321     return basic_io_object<ASIO_SVC_T>::get_io_service();
322   }
323 #endif // !defined(ASIO_NO_DEPRECATED)
324 
325   /// Get the executor associated with the object.
get_executor()326   executor_type get_executor() ASIO_NOEXCEPT
327   {
328     return basic_io_object<ASIO_SVC_T>::get_executor();
329   }
330 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
331 
332   /// Open the acceptor using the specified protocol.
333   /**
334    * This function opens the socket acceptor so that it will use the specified
335    * protocol.
336    *
337    * @param protocol An object specifying which protocol is to be used.
338    *
339    * @throws asio::system_error Thrown on failure.
340    *
341    * @par Example
342    * @code
343    * asio::ip::tcp::acceptor acceptor(io_context);
344    * acceptor.open(asio::ip::tcp::v4());
345    * @endcode
346    */
open(const protocol_type & protocol=protocol_type ())347   void open(const protocol_type& protocol = protocol_type())
348   {
349     asio::error_code ec;
350     this->get_service().open(this->get_implementation(), protocol, ec);
351     asio::detail::throw_error(ec, "open");
352   }
353 
354   /// Open the acceptor using the specified protocol.
355   /**
356    * This function opens the socket acceptor so that it will use the specified
357    * protocol.
358    *
359    * @param protocol An object specifying which protocol is to be used.
360    *
361    * @param ec Set to indicate what error occurred, if any.
362    *
363    * @par Example
364    * @code
365    * asio::ip::tcp::acceptor acceptor(io_context);
366    * asio::error_code ec;
367    * acceptor.open(asio::ip::tcp::v4(), ec);
368    * if (ec)
369    * {
370    *   // An error occurred.
371    * }
372    * @endcode
373    */
open(const protocol_type & protocol,asio::error_code & ec)374   ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
375       asio::error_code& ec)
376   {
377     this->get_service().open(this->get_implementation(), protocol, ec);
378     ASIO_SYNC_OP_VOID_RETURN(ec);
379   }
380 
381   /// Assigns an existing native acceptor to the acceptor.
382   /*
383    * This function opens the acceptor to hold an existing native acceptor.
384    *
385    * @param protocol An object specifying which protocol is to be used.
386    *
387    * @param native_acceptor A native acceptor.
388    *
389    * @throws asio::system_error Thrown on failure.
390    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor)391   void assign(const protocol_type& protocol,
392       const native_handle_type& native_acceptor)
393   {
394     asio::error_code ec;
395     this->get_service().assign(this->get_implementation(),
396         protocol, native_acceptor, ec);
397     asio::detail::throw_error(ec, "assign");
398   }
399 
400   /// Assigns an existing native acceptor to the acceptor.
401   /*
402    * This function opens the acceptor to hold an existing native acceptor.
403    *
404    * @param protocol An object specifying which protocol is to be used.
405    *
406    * @param native_acceptor A native acceptor.
407    *
408    * @param ec Set to indicate what error occurred, if any.
409    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor,asio::error_code & ec)410   ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
411       const native_handle_type& native_acceptor, asio::error_code& ec)
412   {
413     this->get_service().assign(this->get_implementation(),
414         protocol, native_acceptor, ec);
415     ASIO_SYNC_OP_VOID_RETURN(ec);
416   }
417 
418   /// Determine whether the acceptor is open.
is_open() const419   bool is_open() const
420   {
421     return this->get_service().is_open(this->get_implementation());
422   }
423 
424   /// Bind the acceptor to the given local endpoint.
425   /**
426    * This function binds the socket acceptor to the specified endpoint on the
427    * local machine.
428    *
429    * @param endpoint An endpoint on the local machine to which the socket
430    * acceptor will be bound.
431    *
432    * @throws asio::system_error Thrown on failure.
433    *
434    * @par Example
435    * @code
436    * asio::ip::tcp::acceptor acceptor(io_context);
437    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
438    * acceptor.open(endpoint.protocol());
439    * acceptor.bind(endpoint);
440    * @endcode
441    */
bind(const endpoint_type & endpoint)442   void bind(const endpoint_type& endpoint)
443   {
444     asio::error_code ec;
445     this->get_service().bind(this->get_implementation(), endpoint, ec);
446     asio::detail::throw_error(ec, "bind");
447   }
448 
449   /// Bind the acceptor to the given local endpoint.
450   /**
451    * This function binds the socket acceptor to the specified endpoint on the
452    * local machine.
453    *
454    * @param endpoint An endpoint on the local machine to which the socket
455    * acceptor will be bound.
456    *
457    * @param ec Set to indicate what error occurred, if any.
458    *
459    * @par Example
460    * @code
461    * asio::ip::tcp::acceptor acceptor(io_context);
462    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
463    * acceptor.open(endpoint.protocol());
464    * asio::error_code ec;
465    * acceptor.bind(endpoint, ec);
466    * if (ec)
467    * {
468    *   // An error occurred.
469    * }
470    * @endcode
471    */
bind(const endpoint_type & endpoint,asio::error_code & ec)472   ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
473       asio::error_code& ec)
474   {
475     this->get_service().bind(this->get_implementation(), endpoint, ec);
476     ASIO_SYNC_OP_VOID_RETURN(ec);
477   }
478 
479   /// Place the acceptor into the state where it will listen for new
480   /// connections.
481   /**
482    * This function puts the socket acceptor into the state where it may accept
483    * new connections.
484    *
485    * @param backlog The maximum length of the queue of pending connections.
486    *
487    * @throws asio::system_error Thrown on failure.
488    */
listen(int backlog=socket_base::max_listen_connections)489   void listen(int backlog = socket_base::max_listen_connections)
490   {
491     asio::error_code ec;
492     this->get_service().listen(this->get_implementation(), backlog, ec);
493     asio::detail::throw_error(ec, "listen");
494   }
495 
496   /// Place the acceptor into the state where it will listen for new
497   /// connections.
498   /**
499    * This function puts the socket acceptor into the state where it may accept
500    * new connections.
501    *
502    * @param backlog The maximum length of the queue of pending connections.
503    *
504    * @param ec Set to indicate what error occurred, if any.
505    *
506    * @par Example
507    * @code
508    * asio::ip::tcp::acceptor acceptor(io_context);
509    * ...
510    * asio::error_code ec;
511    * acceptor.listen(asio::socket_base::max_listen_connections, ec);
512    * if (ec)
513    * {
514    *   // An error occurred.
515    * }
516    * @endcode
517    */
listen(int backlog,asio::error_code & ec)518   ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code& ec)
519   {
520     this->get_service().listen(this->get_implementation(), backlog, ec);
521     ASIO_SYNC_OP_VOID_RETURN(ec);
522   }
523 
524   /// Close the acceptor.
525   /**
526    * This function is used to close the acceptor. Any asynchronous accept
527    * operations will be cancelled immediately.
528    *
529    * A subsequent call to open() is required before the acceptor can again be
530    * used to again perform socket accept operations.
531    *
532    * @throws asio::system_error Thrown on failure.
533    */
close()534   void close()
535   {
536     asio::error_code ec;
537     this->get_service().close(this->get_implementation(), ec);
538     asio::detail::throw_error(ec, "close");
539   }
540 
541   /// Close the acceptor.
542   /**
543    * This function is used to close the acceptor. Any asynchronous accept
544    * operations will be cancelled immediately.
545    *
546    * A subsequent call to open() is required before the acceptor can again be
547    * used to again perform socket accept operations.
548    *
549    * @param ec Set to indicate what error occurred, if any.
550    *
551    * @par Example
552    * @code
553    * asio::ip::tcp::acceptor acceptor(io_context);
554    * ...
555    * asio::error_code ec;
556    * acceptor.close(ec);
557    * if (ec)
558    * {
559    *   // An error occurred.
560    * }
561    * @endcode
562    */
close(asio::error_code & ec)563   ASIO_SYNC_OP_VOID close(asio::error_code& ec)
564   {
565     this->get_service().close(this->get_implementation(), ec);
566     ASIO_SYNC_OP_VOID_RETURN(ec);
567   }
568 
569   /// Get the native acceptor representation.
570   /**
571    * This function may be used to obtain the underlying representation of the
572    * acceptor. This is intended to allow access to native acceptor functionality
573    * that is not otherwise provided.
574    */
native_handle()575   native_handle_type native_handle()
576   {
577     return this->get_service().native_handle(this->get_implementation());
578   }
579 
580   /// Cancel all asynchronous operations associated with the acceptor.
581   /**
582    * This function causes all outstanding asynchronous connect, send and receive
583    * operations to finish immediately, and the handlers for cancelled operations
584    * will be passed the asio::error::operation_aborted error.
585    *
586    * @throws asio::system_error Thrown on failure.
587    */
cancel()588   void cancel()
589   {
590     asio::error_code ec;
591     this->get_service().cancel(this->get_implementation(), ec);
592     asio::detail::throw_error(ec, "cancel");
593   }
594 
595   /// Cancel all asynchronous operations associated with the acceptor.
596   /**
597    * This function causes all outstanding asynchronous connect, send and receive
598    * operations to finish immediately, and the handlers for cancelled operations
599    * will be passed the asio::error::operation_aborted error.
600    *
601    * @param ec Set to indicate what error occurred, if any.
602    */
cancel(asio::error_code & ec)603   ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
604   {
605     this->get_service().cancel(this->get_implementation(), ec);
606     ASIO_SYNC_OP_VOID_RETURN(ec);
607   }
608 
609   /// Set an option on the acceptor.
610   /**
611    * This function is used to set an option on the acceptor.
612    *
613    * @param option The new option value to be set on the acceptor.
614    *
615    * @throws asio::system_error Thrown on failure.
616    *
617    * @sa SettableSocketOption @n
618    * asio::socket_base::reuse_address
619    * asio::socket_base::enable_connection_aborted
620    *
621    * @par Example
622    * Setting the SOL_SOCKET/SO_REUSEADDR option:
623    * @code
624    * asio::ip::tcp::acceptor acceptor(io_context);
625    * ...
626    * asio::ip::tcp::acceptor::reuse_address option(true);
627    * acceptor.set_option(option);
628    * @endcode
629    */
630   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option)631   void set_option(const SettableSocketOption& option)
632   {
633     asio::error_code ec;
634     this->get_service().set_option(this->get_implementation(), option, ec);
635     asio::detail::throw_error(ec, "set_option");
636   }
637 
638   /// Set an option on the acceptor.
639   /**
640    * This function is used to set an option on the acceptor.
641    *
642    * @param option The new option value to be set on the acceptor.
643    *
644    * @param ec Set to indicate what error occurred, if any.
645    *
646    * @sa SettableSocketOption @n
647    * asio::socket_base::reuse_address
648    * asio::socket_base::enable_connection_aborted
649    *
650    * @par Example
651    * Setting the SOL_SOCKET/SO_REUSEADDR option:
652    * @code
653    * asio::ip::tcp::acceptor acceptor(io_context);
654    * ...
655    * asio::ip::tcp::acceptor::reuse_address option(true);
656    * asio::error_code ec;
657    * acceptor.set_option(option, ec);
658    * if (ec)
659    * {
660    *   // An error occurred.
661    * }
662    * @endcode
663    */
664   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option,asio::error_code & ec)665   ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
666       asio::error_code& ec)
667   {
668     this->get_service().set_option(this->get_implementation(), option, ec);
669     ASIO_SYNC_OP_VOID_RETURN(ec);
670   }
671 
672   /// Get an option from the acceptor.
673   /**
674    * This function is used to get the current value of an option on the
675    * acceptor.
676    *
677    * @param option The option value to be obtained from the acceptor.
678    *
679    * @throws asio::system_error Thrown on failure.
680    *
681    * @sa GettableSocketOption @n
682    * asio::socket_base::reuse_address
683    *
684    * @par Example
685    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
686    * @code
687    * asio::ip::tcp::acceptor acceptor(io_context);
688    * ...
689    * asio::ip::tcp::acceptor::reuse_address option;
690    * acceptor.get_option(option);
691    * bool is_set = option.get();
692    * @endcode
693    */
694   template <typename GettableSocketOption>
get_option(GettableSocketOption & option)695   void get_option(GettableSocketOption& option)
696   {
697     asio::error_code ec;
698     this->get_service().get_option(this->get_implementation(), option, ec);
699     asio::detail::throw_error(ec, "get_option");
700   }
701 
702   /// Get an option from the acceptor.
703   /**
704    * This function is used to get the current value of an option on the
705    * acceptor.
706    *
707    * @param option The option value to be obtained from the acceptor.
708    *
709    * @param ec Set to indicate what error occurred, if any.
710    *
711    * @sa GettableSocketOption @n
712    * asio::socket_base::reuse_address
713    *
714    * @par Example
715    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
716    * @code
717    * asio::ip::tcp::acceptor acceptor(io_context);
718    * ...
719    * asio::ip::tcp::acceptor::reuse_address option;
720    * asio::error_code ec;
721    * acceptor.get_option(option, ec);
722    * if (ec)
723    * {
724    *   // An error occurred.
725    * }
726    * bool is_set = option.get();
727    * @endcode
728    */
729   template <typename GettableSocketOption>
get_option(GettableSocketOption & option,asio::error_code & ec)730   ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
731       asio::error_code& ec)
732   {
733     this->get_service().get_option(this->get_implementation(), option, ec);
734     ASIO_SYNC_OP_VOID_RETURN(ec);
735   }
736 
737   /// Perform an IO control command on the acceptor.
738   /**
739    * This function is used to execute an IO control command on the acceptor.
740    *
741    * @param command The IO control command to be performed on the acceptor.
742    *
743    * @throws asio::system_error Thrown on failure.
744    *
745    * @sa IoControlCommand @n
746    * asio::socket_base::non_blocking_io
747    *
748    * @par Example
749    * Getting the number of bytes ready to read:
750    * @code
751    * asio::ip::tcp::acceptor acceptor(io_context);
752    * ...
753    * asio::ip::tcp::acceptor::non_blocking_io command(true);
754    * socket.io_control(command);
755    * @endcode
756    */
757   template <typename IoControlCommand>
io_control(IoControlCommand & command)758   void io_control(IoControlCommand& command)
759   {
760     asio::error_code ec;
761     this->get_service().io_control(this->get_implementation(), command, ec);
762     asio::detail::throw_error(ec, "io_control");
763   }
764 
765   /// Perform an IO control command on the acceptor.
766   /**
767    * This function is used to execute an IO control command on the acceptor.
768    *
769    * @param command The IO control command to be performed on the acceptor.
770    *
771    * @param ec Set to indicate what error occurred, if any.
772    *
773    * @sa IoControlCommand @n
774    * asio::socket_base::non_blocking_io
775    *
776    * @par Example
777    * Getting the number of bytes ready to read:
778    * @code
779    * asio::ip::tcp::acceptor acceptor(io_context);
780    * ...
781    * asio::ip::tcp::acceptor::non_blocking_io command(true);
782    * asio::error_code ec;
783    * socket.io_control(command, ec);
784    * if (ec)
785    * {
786    *   // An error occurred.
787    * }
788    * @endcode
789    */
790   template <typename IoControlCommand>
io_control(IoControlCommand & command,asio::error_code & ec)791   ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
792       asio::error_code& ec)
793   {
794     this->get_service().io_control(this->get_implementation(), command, ec);
795     ASIO_SYNC_OP_VOID_RETURN(ec);
796   }
797 
798   /// Gets the non-blocking mode of the acceptor.
799   /**
800    * @returns @c true if the acceptor's synchronous operations will fail with
801    * asio::error::would_block if they are unable to perform the requested
802    * operation immediately. If @c false, synchronous operations will block
803    * until complete.
804    *
805    * @note The non-blocking mode has no effect on the behaviour of asynchronous
806    * operations. Asynchronous operations will never fail with the error
807    * asio::error::would_block.
808    */
non_blocking() const809   bool non_blocking() const
810   {
811     return this->get_service().non_blocking(this->get_implementation());
812   }
813 
814   /// Sets the non-blocking mode of the acceptor.
815   /**
816    * @param mode If @c true, the acceptor's synchronous operations will fail
817    * with asio::error::would_block if they are unable to perform the
818    * requested operation immediately. If @c false, synchronous operations will
819    * block until complete.
820    *
821    * @throws asio::system_error Thrown on failure.
822    *
823    * @note The non-blocking mode has no effect on the behaviour of asynchronous
824    * operations. Asynchronous operations will never fail with the error
825    * asio::error::would_block.
826    */
non_blocking(bool mode)827   void non_blocking(bool mode)
828   {
829     asio::error_code ec;
830     this->get_service().non_blocking(this->get_implementation(), mode, ec);
831     asio::detail::throw_error(ec, "non_blocking");
832   }
833 
834   /// Sets the non-blocking mode of the acceptor.
835   /**
836    * @param mode If @c true, the acceptor's synchronous operations will fail
837    * with asio::error::would_block if they are unable to perform the
838    * requested operation immediately. If @c false, synchronous operations will
839    * block until complete.
840    *
841    * @param ec Set to indicate what error occurred, if any.
842    *
843    * @note The non-blocking mode has no effect on the behaviour of asynchronous
844    * operations. Asynchronous operations will never fail with the error
845    * asio::error::would_block.
846    */
non_blocking(bool mode,asio::error_code & ec)847   ASIO_SYNC_OP_VOID non_blocking(
848       bool mode, asio::error_code& ec)
849   {
850     this->get_service().non_blocking(this->get_implementation(), mode, ec);
851     ASIO_SYNC_OP_VOID_RETURN(ec);
852   }
853 
854   /// Gets the non-blocking mode of the native acceptor implementation.
855   /**
856    * This function is used to retrieve the non-blocking mode of the underlying
857    * native acceptor. This mode has no effect on the behaviour of the acceptor
858    * object's synchronous operations.
859    *
860    * @returns @c true if the underlying acceptor is in non-blocking mode and
861    * direct system calls may fail with asio::error::would_block (or the
862    * equivalent system error).
863    *
864    * @note The current non-blocking mode is cached by the acceptor object.
865    * Consequently, the return value may be incorrect if the non-blocking mode
866    * was set directly on the native acceptor.
867    */
native_non_blocking() const868   bool native_non_blocking() const
869   {
870     return this->get_service().native_non_blocking(this->get_implementation());
871   }
872 
873   /// Sets the non-blocking mode of the native acceptor implementation.
874   /**
875    * This function is used to modify the non-blocking mode of the underlying
876    * native acceptor. It has no effect on the behaviour of the acceptor object's
877    * synchronous operations.
878    *
879    * @param mode If @c true, the underlying acceptor is put into non-blocking
880    * mode and direct system calls may fail with asio::error::would_block
881    * (or the equivalent system error).
882    *
883    * @throws asio::system_error Thrown on failure. If the @c mode is
884    * @c false, but the current value of @c non_blocking() is @c true, this
885    * function fails with asio::error::invalid_argument, as the
886    * combination does not make sense.
887    */
native_non_blocking(bool mode)888   void native_non_blocking(bool mode)
889   {
890     asio::error_code ec;
891     this->get_service().native_non_blocking(
892         this->get_implementation(), mode, ec);
893     asio::detail::throw_error(ec, "native_non_blocking");
894   }
895 
896   /// Sets the non-blocking mode of the native acceptor implementation.
897   /**
898    * This function is used to modify the non-blocking mode of the underlying
899    * native acceptor. It has no effect on the behaviour of the acceptor object's
900    * synchronous operations.
901    *
902    * @param mode If @c true, the underlying acceptor is put into non-blocking
903    * mode and direct system calls may fail with asio::error::would_block
904    * (or the equivalent system error).
905    *
906    * @param ec Set to indicate what error occurred, if any. If the @c mode is
907    * @c false, but the current value of @c non_blocking() is @c true, this
908    * function fails with asio::error::invalid_argument, as the
909    * combination does not make sense.
910    */
native_non_blocking(bool mode,asio::error_code & ec)911   ASIO_SYNC_OP_VOID native_non_blocking(
912       bool mode, asio::error_code& ec)
913   {
914     this->get_service().native_non_blocking(
915         this->get_implementation(), mode, ec);
916     ASIO_SYNC_OP_VOID_RETURN(ec);
917   }
918 
919   /// Get the local endpoint of the acceptor.
920   /**
921    * This function is used to obtain the locally bound endpoint of the acceptor.
922    *
923    * @returns An object that represents the local endpoint of the acceptor.
924    *
925    * @throws asio::system_error Thrown on failure.
926    *
927    * @par Example
928    * @code
929    * asio::ip::tcp::acceptor acceptor(io_context);
930    * ...
931    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
932    * @endcode
933    */
local_endpoint() const934   endpoint_type local_endpoint() const
935   {
936     asio::error_code ec;
937     endpoint_type ep = this->get_service().local_endpoint(
938         this->get_implementation(), ec);
939     asio::detail::throw_error(ec, "local_endpoint");
940     return ep;
941   }
942 
943   /// Get the local endpoint of the acceptor.
944   /**
945    * This function is used to obtain the locally bound endpoint of the acceptor.
946    *
947    * @param ec Set to indicate what error occurred, if any.
948    *
949    * @returns An object that represents the local endpoint of the acceptor.
950    * Returns a default-constructed endpoint object if an error occurred and the
951    * error handler did not throw an exception.
952    *
953    * @par Example
954    * @code
955    * asio::ip::tcp::acceptor acceptor(io_context);
956    * ...
957    * asio::error_code ec;
958    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
959    * if (ec)
960    * {
961    *   // An error occurred.
962    * }
963    * @endcode
964    */
local_endpoint(asio::error_code & ec) const965   endpoint_type local_endpoint(asio::error_code& ec) const
966   {
967     return this->get_service().local_endpoint(this->get_implementation(), ec);
968   }
969 
970   /// Wait for the acceptor to become ready to read, ready to write, or to have
971   /// pending error conditions.
972   /**
973    * This function is used to perform a blocking wait for an acceptor to enter
974    * a ready to read, write or error condition state.
975    *
976    * @param w Specifies the desired acceptor state.
977    *
978    * @par Example
979    * Waiting for an acceptor to become readable.
980    * @code
981    * asio::ip::tcp::acceptor acceptor(io_context);
982    * ...
983    * acceptor.wait(asio::ip::tcp::acceptor::wait_read);
984    * @endcode
985    */
wait(wait_type w)986   void wait(wait_type w)
987   {
988     asio::error_code ec;
989     this->get_service().wait(this->get_implementation(), w, ec);
990     asio::detail::throw_error(ec, "wait");
991   }
992 
993   /// Wait for the acceptor to become ready to read, ready to write, or to have
994   /// pending error conditions.
995   /**
996    * This function is used to perform a blocking wait for an acceptor to enter
997    * a ready to read, write or error condition state.
998    *
999    * @param w Specifies the desired acceptor state.
1000    *
1001    * @param ec Set to indicate what error occurred, if any.
1002    *
1003    * @par Example
1004    * Waiting for an acceptor to become readable.
1005    * @code
1006    * asio::ip::tcp::acceptor acceptor(io_context);
1007    * ...
1008    * asio::error_code ec;
1009    * acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec);
1010    * @endcode
1011    */
wait(wait_type w,asio::error_code & ec)1012   ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec)
1013   {
1014     this->get_service().wait(this->get_implementation(), w, ec);
1015     ASIO_SYNC_OP_VOID_RETURN(ec);
1016   }
1017 
1018   /// Asynchronously wait for the acceptor to become ready to read, ready to
1019   /// write, or to have pending error conditions.
1020   /**
1021    * This function is used to perform an asynchronous wait for an acceptor to
1022    * enter a ready to read, write or error condition state.
1023    *
1024    * @param w Specifies the desired acceptor state.
1025    *
1026    * @param handler The handler to be called when the wait operation completes.
1027    * Copies will be made of the handler as required. The function signature of
1028    * the handler must be:
1029    * @code void handler(
1030    *   const asio::error_code& error // Result of operation
1031    * ); @endcode
1032    * Regardless of whether the asynchronous operation completes immediately or
1033    * not, the handler will not be invoked from within this function. Invocation
1034    * of the handler will be performed in a manner equivalent to using
1035    * asio::io_context::post().
1036    *
1037    * @par Example
1038    * @code
1039    * void wait_handler(const asio::error_code& error)
1040    * {
1041    *   if (!error)
1042    *   {
1043    *     // Wait succeeded.
1044    *   }
1045    * }
1046    *
1047    * ...
1048    *
1049    * asio::ip::tcp::acceptor acceptor(io_context);
1050    * ...
1051    * acceptor.async_wait(
1052    *     asio::ip::tcp::acceptor::wait_read,
1053    *     wait_handler);
1054    * @endcode
1055    */
1056   template <typename WaitHandler>
ASIO_INITFN_RESULT_TYPE(WaitHandler,void (asio::error_code))1057   ASIO_INITFN_RESULT_TYPE(WaitHandler,
1058       void (asio::error_code))
1059   async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler)
1060   {
1061     // If you get an error on the following line it means that your handler does
1062     // not meet the documented type requirements for a WaitHandler.
1063     ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
1064 
1065 #if defined(ASIO_ENABLE_OLD_SERVICES)
1066     return this->get_service().async_wait(this->get_implementation(),
1067         w, ASIO_MOVE_CAST(WaitHandler)(handler));
1068 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1069     async_completion<WaitHandler,
1070       void (asio::error_code)> init(handler);
1071 
1072     this->get_service().async_wait(this->get_implementation(),
1073         w, init.completion_handler);
1074 
1075     return init.result.get();
1076 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1077   }
1078 
1079 #if !defined(ASIO_NO_EXTENSIONS)
1080   /// Accept a new connection.
1081   /**
1082    * This function is used to accept a new connection from a peer into the
1083    * given socket. The function call will block until a new connection has been
1084    * accepted successfully or an error occurs.
1085    *
1086    * @param peer The socket into which the new connection will be accepted.
1087    *
1088    * @throws asio::system_error Thrown on failure.
1089    *
1090    * @par Example
1091    * @code
1092    * asio::ip::tcp::acceptor acceptor(io_context);
1093    * ...
1094    * asio::ip::tcp::socket socket(io_context);
1095    * acceptor.accept(socket);
1096    * @endcode
1097    */
1098 #if defined(ASIO_ENABLE_OLD_SERVICES)
1099   template <typename Protocol1, typename SocketService>
accept(basic_socket<Protocol1,SocketService> & peer,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)1100   void accept(basic_socket<Protocol1, SocketService>& peer,
1101       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1102 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1103   template <typename Protocol1>
1104   void accept(basic_socket<Protocol1>& peer,
1105       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1106 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1107   {
1108     asio::error_code ec;
1109     this->get_service().accept(this->get_implementation(),
1110         peer, static_cast<endpoint_type*>(0), ec);
1111     asio::detail::throw_error(ec, "accept");
1112   }
1113 
1114   /// Accept a new connection.
1115   /**
1116    * This function is used to accept a new connection from a peer into the
1117    * given socket. The function call will block until a new connection has been
1118    * accepted successfully or an error occurs.
1119    *
1120    * @param peer The socket into which the new connection will be accepted.
1121    *
1122    * @param ec Set to indicate what error occurred, if any.
1123    *
1124    * @par Example
1125    * @code
1126    * asio::ip::tcp::acceptor acceptor(io_context);
1127    * ...
1128    * asio::ip::tcp::socket socket(io_context);
1129    * asio::error_code ec;
1130    * acceptor.accept(socket, ec);
1131    * if (ec)
1132    * {
1133    *   // An error occurred.
1134    * }
1135    * @endcode
1136    */
1137 #if defined(ASIO_ENABLE_OLD_SERVICES)
1138   template <typename Protocol1, typename SocketService>
accept(basic_socket<Protocol1,SocketService> & peer,asio::error_code & ec,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)1139   ASIO_SYNC_OP_VOID accept(
1140       basic_socket<Protocol1, SocketService>& peer,
1141       asio::error_code& ec,
1142       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1143 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1144   template <typename Protocol1>
1145   ASIO_SYNC_OP_VOID accept(
1146       basic_socket<Protocol1>& peer, asio::error_code& ec,
1147       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1148 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1149   {
1150     this->get_service().accept(this->get_implementation(),
1151         peer, static_cast<endpoint_type*>(0), ec);
1152     ASIO_SYNC_OP_VOID_RETURN(ec);
1153   }
1154 
1155   /// Start an asynchronous accept.
1156   /**
1157    * This function is used to asynchronously accept a new connection into a
1158    * socket. The function call always returns immediately.
1159    *
1160    * @param peer The socket into which the new connection will be accepted.
1161    * Ownership of the peer object is retained by the caller, which must
1162    * guarantee that it is valid until the handler is called.
1163    *
1164    * @param handler The handler to be called when the accept operation
1165    * completes. Copies will be made of the handler as required. The function
1166    * signature of the handler must be:
1167    * @code void handler(
1168    *   const asio::error_code& error // Result of operation.
1169    * ); @endcode
1170    * Regardless of whether the asynchronous operation completes immediately or
1171    * not, the handler will not be invoked from within this function. Invocation
1172    * of the handler will be performed in a manner equivalent to using
1173    * asio::io_context::post().
1174    *
1175    * @par Example
1176    * @code
1177    * void accept_handler(const asio::error_code& error)
1178    * {
1179    *   if (!error)
1180    *   {
1181    *     // Accept succeeded.
1182    *   }
1183    * }
1184    *
1185    * ...
1186    *
1187    * asio::ip::tcp::acceptor acceptor(io_context);
1188    * ...
1189    * asio::ip::tcp::socket socket(io_context);
1190    * acceptor.async_accept(socket, accept_handler);
1191    * @endcode
1192    */
1193 #if defined(ASIO_ENABLE_OLD_SERVICES)
1194   template <typename Protocol1, typename SocketService, typename AcceptHandler>
ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1195   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1196       void (asio::error_code))
1197   async_accept(basic_socket<Protocol1, SocketService>& peer,
1198       ASIO_MOVE_ARG(AcceptHandler) handler,
1199       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1200 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1201   template <typename Protocol1, typename AcceptHandler>
1202   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1203       void (asio::error_code))
1204   async_accept(basic_socket<Protocol1>& peer,
1205       ASIO_MOVE_ARG(AcceptHandler) handler,
1206       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1207 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1208   {
1209     // If you get an error on the following line it means that your handler does
1210     // not meet the documented type requirements for a AcceptHandler.
1211     ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
1212 
1213 #if defined(ASIO_ENABLE_OLD_SERVICES)
1214     return this->get_service().async_accept(this->get_implementation(),
1215         peer, static_cast<endpoint_type*>(0),
1216         ASIO_MOVE_CAST(AcceptHandler)(handler));
1217 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1218     async_completion<AcceptHandler,
1219       void (asio::error_code)> init(handler);
1220 
1221     this->get_service().async_accept(this->get_implementation(),
1222         peer, static_cast<endpoint_type*>(0), init.completion_handler);
1223 
1224     return init.result.get();
1225 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1226   }
1227 
1228   /// Accept a new connection and obtain the endpoint of the peer
1229   /**
1230    * This function is used to accept a new connection from a peer into the
1231    * given socket, and additionally provide the endpoint of the remote peer.
1232    * The function call will block until a new connection has been accepted
1233    * successfully or an error occurs.
1234    *
1235    * @param peer The socket into which the new connection will be accepted.
1236    *
1237    * @param peer_endpoint An endpoint object which will receive the endpoint of
1238    * the remote peer.
1239    *
1240    * @throws asio::system_error Thrown on failure.
1241    *
1242    * @par Example
1243    * @code
1244    * asio::ip::tcp::acceptor acceptor(io_context);
1245    * ...
1246    * asio::ip::tcp::socket socket(io_context);
1247    * asio::ip::tcp::endpoint endpoint;
1248    * acceptor.accept(socket, endpoint);
1249    * @endcode
1250    */
1251 #if defined(ASIO_ENABLE_OLD_SERVICES)
1252   template <typename SocketService>
accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint)1253   void accept(basic_socket<protocol_type, SocketService>& peer,
1254       endpoint_type& peer_endpoint)
1255 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1256   void accept(basic_socket<protocol_type>& peer, endpoint_type& peer_endpoint)
1257 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1258   {
1259     asio::error_code ec;
1260     this->get_service().accept(this->get_implementation(),
1261         peer, &peer_endpoint, ec);
1262     asio::detail::throw_error(ec, "accept");
1263   }
1264 
1265   /// Accept a new connection and obtain the endpoint of the peer
1266   /**
1267    * This function is used to accept a new connection from a peer into the
1268    * given socket, and additionally provide the endpoint of the remote peer.
1269    * The function call will block until a new connection has been accepted
1270    * successfully or an error occurs.
1271    *
1272    * @param peer The socket into which the new connection will be accepted.
1273    *
1274    * @param peer_endpoint An endpoint object which will receive the endpoint of
1275    * the remote peer.
1276    *
1277    * @param ec Set to indicate what error occurred, if any.
1278    *
1279    * @par Example
1280    * @code
1281    * asio::ip::tcp::acceptor acceptor(io_context);
1282    * ...
1283    * asio::ip::tcp::socket socket(io_context);
1284    * asio::ip::tcp::endpoint endpoint;
1285    * asio::error_code ec;
1286    * acceptor.accept(socket, endpoint, ec);
1287    * if (ec)
1288    * {
1289    *   // An error occurred.
1290    * }
1291    * @endcode
1292    */
1293 #if defined(ASIO_ENABLE_OLD_SERVICES)
1294   template <typename SocketService>
accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint,asio::error_code & ec)1295   ASIO_SYNC_OP_VOID accept(
1296       basic_socket<protocol_type, SocketService>& peer,
1297       endpoint_type& peer_endpoint, asio::error_code& ec)
1298 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1299   ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type>& peer,
1300       endpoint_type& peer_endpoint, asio::error_code& ec)
1301 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1302   {
1303     this->get_service().accept(
1304         this->get_implementation(), peer, &peer_endpoint, ec);
1305     ASIO_SYNC_OP_VOID_RETURN(ec);
1306   }
1307 
1308   /// Start an asynchronous accept.
1309   /**
1310    * This function is used to asynchronously accept a new connection into a
1311    * socket, and additionally obtain the endpoint of the remote peer. The
1312    * function call always returns immediately.
1313    *
1314    * @param peer The socket into which the new connection will be accepted.
1315    * Ownership of the peer object is retained by the caller, which must
1316    * guarantee that it is valid until the handler is called.
1317    *
1318    * @param peer_endpoint An endpoint object into which the endpoint of the
1319    * remote peer will be written. Ownership of the peer_endpoint object is
1320    * retained by the caller, which must guarantee that it is valid until the
1321    * handler is called.
1322    *
1323    * @param handler The handler to be called when the accept operation
1324    * completes. Copies will be made of the handler as required. The function
1325    * signature of the handler must be:
1326    * @code void handler(
1327    *   const asio::error_code& error // Result of operation.
1328    * ); @endcode
1329    * Regardless of whether the asynchronous operation completes immediately or
1330    * not, the handler will not be invoked from within this function. Invocation
1331    * of the handler will be performed in a manner equivalent to using
1332    * asio::io_context::post().
1333    */
1334 #if defined(ASIO_ENABLE_OLD_SERVICES)
1335   template <typename SocketService, typename AcceptHandler>
ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1336   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1337       void (asio::error_code))
1338   async_accept(basic_socket<protocol_type, SocketService>& peer,
1339       endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler)
1340 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1341   template <typename AcceptHandler>
1342   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1343       void (asio::error_code))
1344   async_accept(basic_socket<protocol_type>& peer,
1345       endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler)
1346 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1347   {
1348     // If you get an error on the following line it means that your handler does
1349     // not meet the documented type requirements for a AcceptHandler.
1350     ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
1351 
1352 #if defined(ASIO_ENABLE_OLD_SERVICES)
1353     return this->get_service().async_accept(this->get_implementation(), peer,
1354         &peer_endpoint, ASIO_MOVE_CAST(AcceptHandler)(handler));
1355 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1356     async_completion<AcceptHandler,
1357       void (asio::error_code)> init(handler);
1358 
1359     this->get_service().async_accept(this->get_implementation(),
1360         peer, &peer_endpoint, init.completion_handler);
1361 
1362     return init.result.get();
1363 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1364   }
1365 #endif // !defined(ASIO_NO_EXTENSIONS)
1366 
1367 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
1368   /// Accept a new connection.
1369   /**
1370    * This function is used to accept a new connection from a peer. The function
1371    * call will block until a new connection has been accepted successfully or
1372    * an error occurs.
1373    *
1374    * This overload requires that the Protocol template parameter satisfy the
1375    * AcceptableProtocol type requirements.
1376    *
1377    * @returns A socket object representing the newly accepted connection.
1378    *
1379    * @throws asio::system_error Thrown on failure.
1380    *
1381    * @par Example
1382    * @code
1383    * asio::ip::tcp::acceptor acceptor(io_context);
1384    * ...
1385    * asio::ip::tcp::socket socket(acceptor.accept());
1386    * @endcode
1387    */
accept()1388   typename Protocol::socket accept()
1389   {
1390     asio::error_code ec;
1391     typename Protocol::socket peer(
1392         this->get_service().accept(
1393           this->get_implementation(), 0, 0, ec));
1394     asio::detail::throw_error(ec, "accept");
1395     return peer;
1396   }
1397 
1398   /// Accept a new connection.
1399   /**
1400    * This function is used to accept a new connection from a peer. The function
1401    * call will block until a new connection has been accepted successfully or
1402    * an error occurs.
1403    *
1404    * This overload requires that the Protocol template parameter satisfy the
1405    * AcceptableProtocol type requirements.
1406    *
1407    * @param ec Set to indicate what error occurred, if any.
1408    *
1409    * @returns On success, a socket object representing the newly accepted
1410    * connection. On error, a socket object where is_open() is false.
1411    *
1412    * @par Example
1413    * @code
1414    * asio::ip::tcp::acceptor acceptor(io_context);
1415    * ...
1416    * asio::ip::tcp::socket socket(acceptor.accept(ec));
1417    * if (ec)
1418    * {
1419    *   // An error occurred.
1420    * }
1421    * @endcode
1422    */
accept(asio::error_code & ec)1423   typename Protocol::socket accept(asio::error_code& ec)
1424   {
1425     return this->get_service().accept(this->get_implementation(), 0, 0, ec);
1426   }
1427 
1428   /// Start an asynchronous accept.
1429   /**
1430    * This function is used to asynchronously accept a new connection. The
1431    * function call always returns immediately.
1432    *
1433    * This overload requires that the Protocol template parameter satisfy the
1434    * AcceptableProtocol type requirements.
1435    *
1436    * @param handler The handler to be called when the accept operation
1437    * completes. Copies will be made of the handler as required. The function
1438    * signature of the handler must be:
1439    * @code void handler(
1440    *   const asio::error_code& error, // Result of operation.
1441    *   typename Protocol::socket peer // On success, the newly accepted socket.
1442    * ); @endcode
1443    * Regardless of whether the asynchronous operation completes immediately or
1444    * not, the handler will not be invoked from within this function. Invocation
1445    * of the handler will be performed in a manner equivalent to using
1446    * asio::io_context::post().
1447    *
1448    * @par Example
1449    * @code
1450    * void accept_handler(const asio::error_code& error,
1451    *     asio::ip::tcp::socket peer)
1452    * {
1453    *   if (!error)
1454    *   {
1455    *     // Accept succeeded.
1456    *   }
1457    * }
1458    *
1459    * ...
1460    *
1461    * asio::ip::tcp::acceptor acceptor(io_context);
1462    * ...
1463    * acceptor.async_accept(accept_handler);
1464    * @endcode
1465    */
1466   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1467   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1468       void (asio::error_code, typename Protocol::socket))
1469   async_accept(ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1470   {
1471     // If you get an error on the following line it means that your handler does
1472     // not meet the documented type requirements for a MoveAcceptHandler.
1473     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1474         handler, typename Protocol::socket) type_check;
1475 
1476 #if defined(ASIO_ENABLE_OLD_SERVICES)
1477     return this->get_service().async_accept(
1478         this->get_implementation(), static_cast<asio::io_context*>(0),
1479         static_cast<endpoint_type*>(0),
1480         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1481 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1482     async_completion<MoveAcceptHandler,
1483       void (asio::error_code,
1484         typename Protocol::socket)> init(handler);
1485 
1486     this->get_service().async_accept(
1487         this->get_implementation(), static_cast<asio::io_context*>(0),
1488         static_cast<endpoint_type*>(0), init.completion_handler);
1489 
1490     return init.result.get();
1491 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1492   }
1493 
1494   /// Accept a new connection.
1495   /**
1496    * This function is used to accept a new connection from a peer. The function
1497    * call will block until a new connection has been accepted successfully or
1498    * an error occurs.
1499    *
1500    * This overload requires that the Protocol template parameter satisfy the
1501    * AcceptableProtocol type requirements.
1502    *
1503    * @param io_context The io_context object to be used for the newly accepted
1504    * socket.
1505    *
1506    * @returns A socket object representing the newly accepted connection.
1507    *
1508    * @throws asio::system_error Thrown on failure.
1509    *
1510    * @par Example
1511    * @code
1512    * asio::ip::tcp::acceptor acceptor(io_context);
1513    * ...
1514    * asio::ip::tcp::socket socket(acceptor.accept());
1515    * @endcode
1516    */
accept(asio::io_context & io_context)1517   typename Protocol::socket accept(asio::io_context& io_context)
1518   {
1519     asio::error_code ec;
1520     typename Protocol::socket peer(
1521         this->get_service().accept(this->get_implementation(),
1522           &io_context, static_cast<endpoint_type*>(0), ec));
1523     asio::detail::throw_error(ec, "accept");
1524     return peer;
1525   }
1526 
1527   /// Accept a new connection.
1528   /**
1529    * This function is used to accept a new connection from a peer. The function
1530    * call will block until a new connection has been accepted successfully or
1531    * an error occurs.
1532    *
1533    * This overload requires that the Protocol template parameter satisfy the
1534    * AcceptableProtocol type requirements.
1535    *
1536    * @param io_context The io_context object to be used for the newly accepted
1537    * socket.
1538    *
1539    * @param ec Set to indicate what error occurred, if any.
1540    *
1541    * @returns On success, a socket object representing the newly accepted
1542    * connection. On error, a socket object where is_open() is false.
1543    *
1544    * @par Example
1545    * @code
1546    * asio::ip::tcp::acceptor acceptor(io_context);
1547    * ...
1548    * asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec));
1549    * if (ec)
1550    * {
1551    *   // An error occurred.
1552    * }
1553    * @endcode
1554    */
accept(asio::io_context & io_context,asio::error_code & ec)1555   typename Protocol::socket accept(
1556       asio::io_context& io_context, asio::error_code& ec)
1557   {
1558     return this->get_service().accept(this->get_implementation(),
1559         &io_context, static_cast<endpoint_type*>(0), ec);
1560   }
1561 
1562   /// Start an asynchronous accept.
1563   /**
1564    * This function is used to asynchronously accept a new connection. The
1565    * function call always returns immediately.
1566    *
1567    * This overload requires that the Protocol template parameter satisfy the
1568    * AcceptableProtocol type requirements.
1569    *
1570    * @param io_context The io_context object to be used for the newly accepted
1571    * socket.
1572    *
1573    * @param handler The handler to be called when the accept operation
1574    * completes. Copies will be made of the handler as required. The function
1575    * signature of the handler must be:
1576    * @code void handler(
1577    *   const asio::error_code& error, // Result of operation.
1578    *   typename Protocol::socket peer // On success, the newly accepted socket.
1579    * ); @endcode
1580    * Regardless of whether the asynchronous operation completes immediately or
1581    * not, the handler will not be invoked from within this function. Invocation
1582    * of the handler will be performed in a manner equivalent to using
1583    * asio::io_context::post().
1584    *
1585    * @par Example
1586    * @code
1587    * void accept_handler(const asio::error_code& error,
1588    *     asio::ip::tcp::socket peer)
1589    * {
1590    *   if (!error)
1591    *   {
1592    *     // Accept succeeded.
1593    *   }
1594    * }
1595    *
1596    * ...
1597    *
1598    * asio::ip::tcp::acceptor acceptor(io_context);
1599    * ...
1600    * acceptor.async_accept(io_context2, accept_handler);
1601    * @endcode
1602    */
1603   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1604   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1605       void (asio::error_code, typename Protocol::socket))
1606   async_accept(asio::io_context& io_context,
1607       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1608   {
1609     // If you get an error on the following line it means that your handler does
1610     // not meet the documented type requirements for a MoveAcceptHandler.
1611     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1612         handler, typename Protocol::socket) type_check;
1613 
1614 #if defined(ASIO_ENABLE_OLD_SERVICES)
1615     return this->get_service().async_accept(this->get_implementation(),
1616         &io_context, static_cast<endpoint_type*>(0),
1617         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1618 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1619     async_completion<MoveAcceptHandler,
1620       void (asio::error_code,
1621         typename Protocol::socket)> init(handler);
1622 
1623     this->get_service().async_accept(this->get_implementation(),
1624         &io_context, static_cast<endpoint_type*>(0), init.completion_handler);
1625 
1626     return init.result.get();
1627 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1628   }
1629 
1630   /// Accept a new connection.
1631   /**
1632    * This function is used to accept a new connection from a peer. The function
1633    * call will block until a new connection has been accepted successfully or
1634    * an error occurs.
1635    *
1636    * This overload requires that the Protocol template parameter satisfy the
1637    * AcceptableProtocol type requirements.
1638    *
1639    * @param peer_endpoint An endpoint object into which the endpoint of the
1640    * remote peer will be written.
1641    *
1642    * @returns A socket object representing the newly accepted connection.
1643    *
1644    * @throws asio::system_error Thrown on failure.
1645    *
1646    * @par Example
1647    * @code
1648    * asio::ip::tcp::acceptor acceptor(io_context);
1649    * ...
1650    * asio::ip::tcp::endpoint endpoint;
1651    * asio::ip::tcp::socket socket(acceptor.accept(endpoint));
1652    * @endcode
1653    */
accept(endpoint_type & peer_endpoint)1654   typename Protocol::socket accept(endpoint_type& peer_endpoint)
1655   {
1656     asio::error_code ec;
1657     typename Protocol::socket peer(
1658         this->get_service().accept(this->get_implementation(),
1659           static_cast<asio::io_context*>(0), &peer_endpoint, ec));
1660     asio::detail::throw_error(ec, "accept");
1661     return peer;
1662   }
1663 
1664   /// Accept a new connection.
1665   /**
1666    * This function is used to accept a new connection from a peer. The function
1667    * call will block until a new connection has been accepted successfully or
1668    * an error occurs.
1669    *
1670    * This overload requires that the Protocol template parameter satisfy the
1671    * AcceptableProtocol type requirements.
1672    *
1673    * @param peer_endpoint An endpoint object into which the endpoint of the
1674    * remote peer will be written.
1675    *
1676    * @param ec Set to indicate what error occurred, if any.
1677    *
1678    * @returns On success, a socket object representing the newly accepted
1679    * connection. On error, a socket object where is_open() is false.
1680    *
1681    * @par Example
1682    * @code
1683    * asio::ip::tcp::acceptor acceptor(io_context);
1684    * ...
1685    * asio::ip::tcp::endpoint endpoint;
1686    * asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
1687    * if (ec)
1688    * {
1689    *   // An error occurred.
1690    * }
1691    * @endcode
1692    */
accept(endpoint_type & peer_endpoint,asio::error_code & ec)1693   typename Protocol::socket accept(
1694       endpoint_type& peer_endpoint, asio::error_code& ec)
1695   {
1696     return this->get_service().accept(this->get_implementation(),
1697         static_cast<asio::io_context*>(0), &peer_endpoint, ec);
1698   }
1699 
1700   /// Start an asynchronous accept.
1701   /**
1702    * This function is used to asynchronously accept a new connection. The
1703    * function call always returns immediately.
1704    *
1705    * This overload requires that the Protocol template parameter satisfy the
1706    * AcceptableProtocol type requirements.
1707    *
1708    * @param peer_endpoint An endpoint object into which the endpoint of the
1709    * remote peer will be written. Ownership of the peer_endpoint object is
1710    * retained by the caller, which must guarantee that it is valid until the
1711    * handler is called.
1712    *
1713    * @param handler The handler to be called when the accept operation
1714    * completes. Copies will be made of the handler as required. The function
1715    * signature of the handler must be:
1716    * @code void handler(
1717    *   const asio::error_code& error, // Result of operation.
1718    *   typename Protocol::socket peer // On success, the newly accepted socket.
1719    * ); @endcode
1720    * Regardless of whether the asynchronous operation completes immediately or
1721    * not, the handler will not be invoked from within this function. Invocation
1722    * of the handler will be performed in a manner equivalent to using
1723    * asio::io_context::post().
1724    *
1725    * @par Example
1726    * @code
1727    * void accept_handler(const asio::error_code& error,
1728    *     asio::ip::tcp::socket peer)
1729    * {
1730    *   if (!error)
1731    *   {
1732    *     // Accept succeeded.
1733    *   }
1734    * }
1735    *
1736    * ...
1737    *
1738    * asio::ip::tcp::acceptor acceptor(io_context);
1739    * ...
1740    * asio::ip::tcp::endpoint endpoint;
1741    * acceptor.async_accept(endpoint, accept_handler);
1742    * @endcode
1743    */
1744   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1745   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1746       void (asio::error_code, typename Protocol::socket))
1747   async_accept(endpoint_type& peer_endpoint,
1748       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1749   {
1750     // If you get an error on the following line it means that your handler does
1751     // not meet the documented type requirements for a MoveAcceptHandler.
1752     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1753         handler, typename Protocol::socket) type_check;
1754 
1755 #if defined(ASIO_ENABLE_OLD_SERVICES)
1756     return this->get_service().async_accept(this->get_implementation(),
1757         static_cast<asio::io_context*>(0), &peer_endpoint,
1758         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1759 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1760     async_completion<MoveAcceptHandler,
1761       void (asio::error_code,
1762         typename Protocol::socket)> init(handler);
1763 
1764     this->get_service().async_accept(this->get_implementation(),
1765         static_cast<asio::io_context*>(0), &peer_endpoint,
1766         init.completion_handler);
1767 
1768     return init.result.get();
1769 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1770   }
1771 
1772   /// Accept a new connection.
1773   /**
1774    * This function is used to accept a new connection from a peer. The function
1775    * call will block until a new connection has been accepted successfully or
1776    * an error occurs.
1777    *
1778    * This overload requires that the Protocol template parameter satisfy the
1779    * AcceptableProtocol type requirements.
1780    *
1781    * @param io_context The io_context object to be used for the newly accepted
1782    * socket.
1783    *
1784    * @param peer_endpoint An endpoint object into which the endpoint of the
1785    * remote peer will be written.
1786    *
1787    * @returns A socket object representing the newly accepted connection.
1788    *
1789    * @throws asio::system_error Thrown on failure.
1790    *
1791    * @par Example
1792    * @code
1793    * asio::ip::tcp::acceptor acceptor(io_context);
1794    * ...
1795    * asio::ip::tcp::endpoint endpoint;
1796    * asio::ip::tcp::socket socket(
1797    *     acceptor.accept(io_context2, endpoint));
1798    * @endcode
1799    */
accept(asio::io_context & io_context,endpoint_type & peer_endpoint)1800   typename Protocol::socket accept(
1801       asio::io_context& io_context, endpoint_type& peer_endpoint)
1802   {
1803     asio::error_code ec;
1804     typename Protocol::socket peer(
1805         this->get_service().accept(this->get_implementation(),
1806           &io_context, &peer_endpoint, ec));
1807     asio::detail::throw_error(ec, "accept");
1808     return peer;
1809   }
1810 
1811   /// Accept a new connection.
1812   /**
1813    * This function is used to accept a new connection from a peer. The function
1814    * call will block until a new connection has been accepted successfully or
1815    * an error occurs.
1816    *
1817    * This overload requires that the Protocol template parameter satisfy the
1818    * AcceptableProtocol type requirements.
1819    *
1820    * @param io_context The io_context object to be used for the newly accepted
1821    * socket.
1822    *
1823    * @param peer_endpoint An endpoint object into which the endpoint of the
1824    * remote peer will be written.
1825    *
1826    * @param ec Set to indicate what error occurred, if any.
1827    *
1828    * @returns On success, a socket object representing the newly accepted
1829    * connection. On error, a socket object where is_open() is false.
1830    *
1831    * @par Example
1832    * @code
1833    * asio::ip::tcp::acceptor acceptor(io_context);
1834    * ...
1835    * asio::ip::tcp::endpoint endpoint;
1836    * asio::ip::tcp::socket socket(
1837    *     acceptor.accept(io_context2, endpoint, ec));
1838    * if (ec)
1839    * {
1840    *   // An error occurred.
1841    * }
1842    * @endcode
1843    */
accept(asio::io_context & io_context,endpoint_type & peer_endpoint,asio::error_code & ec)1844   typename Protocol::socket accept(asio::io_context& io_context,
1845       endpoint_type& peer_endpoint, asio::error_code& ec)
1846   {
1847     return this->get_service().accept(this->get_implementation(),
1848         &io_context, &peer_endpoint, ec);
1849   }
1850 
1851   /// Start an asynchronous accept.
1852   /**
1853    * This function is used to asynchronously accept a new connection. The
1854    * function call always returns immediately.
1855    *
1856    * This overload requires that the Protocol template parameter satisfy the
1857    * AcceptableProtocol type requirements.
1858    *
1859    * @param io_context The io_context object to be used for the newly accepted
1860    * socket.
1861    *
1862    * @param peer_endpoint An endpoint object into which the endpoint of the
1863    * remote peer will be written. Ownership of the peer_endpoint object is
1864    * retained by the caller, which must guarantee that it is valid until the
1865    * handler is called.
1866    *
1867    * @param handler The handler to be called when the accept operation
1868    * completes. Copies will be made of the handler as required. The function
1869    * signature of the handler must be:
1870    * @code void handler(
1871    *   const asio::error_code& error, // Result of operation.
1872    *   typename Protocol::socket peer // On success, the newly accepted socket.
1873    * ); @endcode
1874    * Regardless of whether the asynchronous operation completes immediately or
1875    * not, the handler will not be invoked from within this function. Invocation
1876    * of the handler will be performed in a manner equivalent to using
1877    * asio::io_context::post().
1878    *
1879    * @par Example
1880    * @code
1881    * void accept_handler(const asio::error_code& error,
1882    *     asio::ip::tcp::socket peer)
1883    * {
1884    *   if (!error)
1885    *   {
1886    *     // Accept succeeded.
1887    *   }
1888    * }
1889    *
1890    * ...
1891    *
1892    * asio::ip::tcp::acceptor acceptor(io_context);
1893    * ...
1894    * asio::ip::tcp::endpoint endpoint;
1895    * acceptor.async_accept(io_context2, endpoint, accept_handler);
1896    * @endcode
1897    */
1898   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1899   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1900       void (asio::error_code, typename Protocol::socket))
1901   async_accept(asio::io_context& io_context,
1902       endpoint_type& peer_endpoint,
1903       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1904   {
1905     // If you get an error on the following line it means that your handler does
1906     // not meet the documented type requirements for a MoveAcceptHandler.
1907     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1908         handler, typename Protocol::socket) type_check;
1909 
1910 #if defined(ASIO_ENABLE_OLD_SERVICES)
1911     return this->get_service().async_accept(
1912         this->get_implementation(), &io_context, &peer_endpoint,
1913         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1914 #else // defined(ASIO_ENABLE_OLD_SERVICES)
1915     async_completion<MoveAcceptHandler,
1916       void (asio::error_code,
1917         typename Protocol::socket)> init(handler);
1918 
1919     this->get_service().async_accept(this->get_implementation(),
1920         &io_context, &peer_endpoint, init.completion_handler);
1921 
1922     return init.result.get();
1923 #endif // defined(ASIO_ENABLE_OLD_SERVICES)
1924   }
1925 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
1926 };
1927 
1928 } // namespace asio
1929 
1930 #include "asio/detail/pop_options.hpp"
1931 
1932 #if !defined(ASIO_ENABLE_OLD_SERVICES)
1933 # undef ASIO_SVC_T
1934 #endif // !defined(ASIO_ENABLE_OLD_SERVICES)
1935 
1936 #endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP
1937