1 //
2 // basic_socket_acceptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 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/any_io_executor.hpp"
20 #include "asio/basic_socket.hpp"
21 #include "asio/detail/handler_type_requirements.hpp"
22 #include "asio/detail/io_object_impl.hpp"
23 #include "asio/detail/non_const_lvalue.hpp"
24 #include "asio/detail/throw_error.hpp"
25 #include "asio/detail/type_traits.hpp"
26 #include "asio/error.hpp"
27 #include "asio/execution_context.hpp"
28 #include "asio/socket_base.hpp"
29 
30 #if defined(ASIO_WINDOWS_RUNTIME)
31 # include "asio/detail/null_socket_service.hpp"
32 #elif defined(ASIO_HAS_IOCP)
33 # include "asio/detail/win_iocp_socket_service.hpp"
34 #else
35 # include "asio/detail/reactive_socket_service.hpp"
36 #endif
37 
38 #if defined(ASIO_HAS_MOVE)
39 # include <utility>
40 #endif // defined(ASIO_HAS_MOVE)
41 
42 #include "asio/detail/push_options.hpp"
43 
44 namespace asio {
45 
46 #if !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
47 #define ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL
48 
49 // Forward declaration with defaulted arguments.
50 template <typename Protocol, typename Executor = any_io_executor>
51 class basic_socket_acceptor;
52 
53 #endif // !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
54 
55 /// Provides the ability to accept new connections.
56 /**
57  * The basic_socket_acceptor class template is used for accepting new socket
58  * connections.
59  *
60  * @par Thread Safety
61  * @e Distinct @e objects: Safe.@n
62  * @e Shared @e objects: Unsafe.
63  *
64  * Synchronous @c accept operations are thread safe, if the underlying
65  * operating system calls are also thread safe. This means that it is permitted
66  * to perform concurrent calls to synchronous @c accept operations on a single
67  * socket object. Other synchronous operations, such as @c open or @c close, are
68  * not thread safe.
69  *
70  * @par Example
71  * Opening a socket acceptor with the SO_REUSEADDR option enabled:
72  * @code
73  * asio::ip::tcp::acceptor acceptor(my_context);
74  * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
75  * acceptor.open(endpoint.protocol());
76  * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
77  * acceptor.bind(endpoint);
78  * acceptor.listen();
79  * @endcode
80  */
81 template <typename Protocol, typename Executor>
82 class basic_socket_acceptor
83   : public socket_base
84 {
85 public:
86   /// The type of the executor associated with the object.
87   typedef Executor executor_type;
88 
89   /// Rebinds the acceptor type to another executor.
90   template <typename Executor1>
91   struct rebind_executor
92   {
93     /// The socket type when rebound to the specified executor.
94     typedef basic_socket_acceptor<Protocol, Executor1> other;
95   };
96 
97   /// The native representation of an acceptor.
98 #if defined(GENERATING_DOCUMENTATION)
99   typedef implementation_defined native_handle_type;
100 #elif defined(ASIO_WINDOWS_RUNTIME)
101   typedef typename detail::null_socket_service<
102     Protocol>::native_handle_type native_handle_type;
103 #elif defined(ASIO_HAS_IOCP)
104   typedef typename detail::win_iocp_socket_service<
105     Protocol>::native_handle_type native_handle_type;
106 #else
107   typedef typename detail::reactive_socket_service<
108     Protocol>::native_handle_type native_handle_type;
109 #endif
110 
111   /// The protocol type.
112   typedef Protocol protocol_type;
113 
114   /// The endpoint type.
115   typedef typename Protocol::endpoint endpoint_type;
116 
117   /// Construct an acceptor without opening it.
118   /**
119    * This constructor creates an acceptor without opening it to listen for new
120    * connections. The open() function must be called before the acceptor can
121    * accept new socket connections.
122    *
123    * @param ex The I/O executor that the acceptor will use, by default, to
124    * dispatch handlers for any asynchronous operations performed on the
125    * acceptor.
126    */
basic_socket_acceptor(const executor_type & ex)127   explicit basic_socket_acceptor(const executor_type& ex)
128     : impl_(0, ex)
129   {
130   }
131 
132   /// Construct an acceptor without opening it.
133   /**
134    * This constructor creates an acceptor without opening it to listen for new
135    * connections. The open() function must be called before the acceptor can
136    * accept new socket connections.
137    *
138    * @param context An execution context which provides the I/O executor that
139    * the acceptor will use, by default, to dispatch handlers for any
140    * asynchronous operations performed on the acceptor.
141    */
142   template <typename ExecutionContext>
basic_socket_acceptor(ExecutionContext & context,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)143   explicit basic_socket_acceptor(ExecutionContext& context,
144       typename constraint<
145         is_convertible<ExecutionContext&, execution_context&>::value
146       >::type = 0)
147     : impl_(0, 0, context)
148   {
149   }
150 
151   /// Construct an open acceptor.
152   /**
153    * This constructor creates an acceptor and automatically opens it.
154    *
155    * @param ex The I/O executor that the acceptor will use, by default, to
156    * dispatch handlers for any asynchronous operations performed on the
157    * acceptor.
158    *
159    * @param protocol An object specifying protocol parameters to be used.
160    *
161    * @throws asio::system_error Thrown on failure.
162    */
basic_socket_acceptor(const executor_type & ex,const protocol_type & protocol)163   basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol)
164     : impl_(0, ex)
165   {
166     asio::error_code ec;
167     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
168     asio::detail::throw_error(ec, "open");
169   }
170 
171   /// Construct an open acceptor.
172   /**
173    * This constructor creates an acceptor and automatically opens it.
174    *
175    * @param context An execution context which provides the I/O executor that
176    * the acceptor will use, by default, to dispatch handlers for any
177    * asynchronous operations performed on the acceptor.
178    *
179    * @param protocol An object specifying protocol parameters to be used.
180    *
181    * @throws asio::system_error Thrown on failure.
182    */
183   template <typename ExecutionContext>
basic_socket_acceptor(ExecutionContext & context,const protocol_type & protocol,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value,defaulted_constraint>::type=defaulted_constraint ())184   basic_socket_acceptor(ExecutionContext& context,
185       const protocol_type& protocol,
186       typename constraint<
187         is_convertible<ExecutionContext&, execution_context&>::value,
188         defaulted_constraint
189       >::type = defaulted_constraint())
190     : impl_(0, 0, context)
191   {
192     asio::error_code ec;
193     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
194     asio::detail::throw_error(ec, "open");
195   }
196 
197   /// Construct an acceptor opened on the given endpoint.
198   /**
199    * This constructor creates an acceptor and automatically opens it to listen
200    * for new connections on the specified endpoint.
201    *
202    * @param ex The I/O executor that the acceptor will use, by default, to
203    * dispatch handlers for any asynchronous operations performed on the
204    * acceptor.
205    *
206    * @param endpoint An endpoint on the local machine on which the acceptor
207    * will listen for new connections.
208    *
209    * @param reuse_addr Whether the constructor should set the socket option
210    * socket_base::reuse_address.
211    *
212    * @throws asio::system_error Thrown on failure.
213    *
214    * @note This constructor is equivalent to the following code:
215    * @code
216    * basic_socket_acceptor<Protocol> acceptor(my_context);
217    * acceptor.open(endpoint.protocol());
218    * if (reuse_addr)
219    *   acceptor.set_option(socket_base::reuse_address(true));
220    * acceptor.bind(endpoint);
221    * acceptor.listen();
222    * @endcode
223    */
basic_socket_acceptor(const executor_type & ex,const endpoint_type & endpoint,bool reuse_addr=true)224   basic_socket_acceptor(const executor_type& ex,
225       const endpoint_type& endpoint, bool reuse_addr = true)
226     : impl_(0, ex)
227   {
228     asio::error_code ec;
229     const protocol_type protocol = endpoint.protocol();
230     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
231     asio::detail::throw_error(ec, "open");
232     if (reuse_addr)
233     {
234       impl_.get_service().set_option(impl_.get_implementation(),
235           socket_base::reuse_address(true), ec);
236       asio::detail::throw_error(ec, "set_option");
237     }
238     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
239     asio::detail::throw_error(ec, "bind");
240     impl_.get_service().listen(impl_.get_implementation(),
241         socket_base::max_listen_connections, ec);
242     asio::detail::throw_error(ec, "listen");
243   }
244 
245   /// Construct an acceptor opened on the given endpoint.
246   /**
247    * This constructor creates an acceptor and automatically opens it to listen
248    * for new connections on the specified endpoint.
249    *
250    * @param context An execution context which provides the I/O executor that
251    * the acceptor will use, by default, to dispatch handlers for any
252    * asynchronous operations performed on the acceptor.
253    *
254    * @param endpoint An endpoint on the local machine on which the acceptor
255    * will listen for new connections.
256    *
257    * @param reuse_addr Whether the constructor should set the socket option
258    * socket_base::reuse_address.
259    *
260    * @throws asio::system_error Thrown on failure.
261    *
262    * @note This constructor is equivalent to the following code:
263    * @code
264    * basic_socket_acceptor<Protocol> acceptor(my_context);
265    * acceptor.open(endpoint.protocol());
266    * if (reuse_addr)
267    *   acceptor.set_option(socket_base::reuse_address(true));
268    * acceptor.bind(endpoint);
269    * acceptor.listen();
270    * @endcode
271    */
272   template <typename ExecutionContext>
basic_socket_acceptor(ExecutionContext & context,const endpoint_type & endpoint,bool reuse_addr=true,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)273   basic_socket_acceptor(ExecutionContext& context,
274       const endpoint_type& endpoint, bool reuse_addr = true,
275       typename constraint<
276         is_convertible<ExecutionContext&, execution_context&>::value
277       >::type = 0)
278     : impl_(0, 0, context)
279   {
280     asio::error_code ec;
281     const protocol_type protocol = endpoint.protocol();
282     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
283     asio::detail::throw_error(ec, "open");
284     if (reuse_addr)
285     {
286       impl_.get_service().set_option(impl_.get_implementation(),
287           socket_base::reuse_address(true), ec);
288       asio::detail::throw_error(ec, "set_option");
289     }
290     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
291     asio::detail::throw_error(ec, "bind");
292     impl_.get_service().listen(impl_.get_implementation(),
293         socket_base::max_listen_connections, ec);
294     asio::detail::throw_error(ec, "listen");
295   }
296 
297   /// Construct a basic_socket_acceptor on an existing native acceptor.
298   /**
299    * This constructor creates an acceptor object to hold an existing native
300    * acceptor.
301    *
302    * @param ex The I/O executor that the acceptor will use, by default, to
303    * dispatch handlers for any asynchronous operations performed on the
304    * acceptor.
305    *
306    * @param protocol An object specifying protocol parameters to be used.
307    *
308    * @param native_acceptor A native acceptor.
309    *
310    * @throws asio::system_error Thrown on failure.
311    */
basic_socket_acceptor(const executor_type & ex,const protocol_type & protocol,const native_handle_type & native_acceptor)312   basic_socket_acceptor(const executor_type& ex,
313       const protocol_type& protocol, const native_handle_type& native_acceptor)
314     : impl_(0, ex)
315   {
316     asio::error_code ec;
317     impl_.get_service().assign(impl_.get_implementation(),
318         protocol, native_acceptor, ec);
319     asio::detail::throw_error(ec, "assign");
320   }
321 
322   /// Construct a basic_socket_acceptor on an existing native acceptor.
323   /**
324    * This constructor creates an acceptor object to hold an existing native
325    * acceptor.
326    *
327    * @param context An execution context which provides the I/O executor that
328    * the acceptor will use, by default, to dispatch handlers for any
329    * asynchronous operations performed on the acceptor.
330    *
331    * @param protocol An object specifying protocol parameters to be used.
332    *
333    * @param native_acceptor A native acceptor.
334    *
335    * @throws asio::system_error Thrown on failure.
336    */
337   template <typename ExecutionContext>
basic_socket_acceptor(ExecutionContext & context,const protocol_type & protocol,const native_handle_type & native_acceptor,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)338   basic_socket_acceptor(ExecutionContext& context,
339       const protocol_type& protocol, const native_handle_type& native_acceptor,
340       typename constraint<
341         is_convertible<ExecutionContext&, execution_context&>::value
342       >::type = 0)
343     : impl_(0, 0, context)
344   {
345     asio::error_code ec;
346     impl_.get_service().assign(impl_.get_implementation(),
347         protocol, native_acceptor, ec);
348     asio::detail::throw_error(ec, "assign");
349   }
350 
351 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
352   /// Move-construct a basic_socket_acceptor from another.
353   /**
354    * This constructor moves an acceptor from one object to another.
355    *
356    * @param other The other basic_socket_acceptor object from which the move
357    * will occur.
358    *
359    * @note Following the move, the moved-from object is in the same state as if
360    * constructed using the @c basic_socket_acceptor(const executor_type&)
361    * constructor.
362    */
basic_socket_acceptor(basic_socket_acceptor && other)363   basic_socket_acceptor(basic_socket_acceptor&& other) ASIO_NOEXCEPT
364     : impl_(std::move(other.impl_))
365   {
366   }
367 
368   /// Move-assign a basic_socket_acceptor from another.
369   /**
370    * This assignment operator moves an acceptor from one object to another.
371    *
372    * @param other The other basic_socket_acceptor object from which the move
373    * will occur.
374    *
375    * @note Following the move, the moved-from object is in the same state as if
376    * constructed using the @c basic_socket_acceptor(const executor_type&)
377    * constructor.
378    */
operator =(basic_socket_acceptor && other)379   basic_socket_acceptor& operator=(basic_socket_acceptor&& other)
380   {
381     impl_ = std::move(other.impl_);
382     return *this;
383   }
384 
385   // All socket acceptors have access to each other's implementations.
386   template <typename Protocol1, typename Executor1>
387   friend class basic_socket_acceptor;
388 
389   /// Move-construct a basic_socket_acceptor from an acceptor of another
390   /// protocol type.
391   /**
392    * This constructor moves an acceptor from one object to another.
393    *
394    * @param other The other basic_socket_acceptor object from which the move
395    * will occur.
396    *
397    * @note Following the move, the moved-from object is in the same state as if
398    * constructed using the @c basic_socket_acceptor(const executor_type&)
399    * constructor.
400    */
401   template <typename Protocol1, typename Executor1>
basic_socket_acceptor(basic_socket_acceptor<Protocol1,Executor1> && other,typename constraint<is_convertible<Protocol1,Protocol>::value && is_convertible<Executor1,Executor>::value>::type=0)402   basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other,
403       typename constraint<
404         is_convertible<Protocol1, Protocol>::value
405           && is_convertible<Executor1, Executor>::value
406       >::type = 0)
407     : impl_(std::move(other.impl_))
408   {
409   }
410 
411   /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
412   /// type.
413   /**
414    * This assignment operator moves an acceptor from one object to another.
415    *
416    * @param other The other basic_socket_acceptor object from which the move
417    * will occur.
418    *
419    * @note Following the move, the moved-from object is in the same state as if
420    * constructed using the @c basic_socket_acceptor(const executor_type&)
421    * constructor.
422    */
423   template <typename Protocol1, typename Executor1>
424   typename constraint<
425     is_convertible<Protocol1, Protocol>::value
426       && is_convertible<Executor1, Executor>::value,
427     basic_socket_acceptor&
operator =(basic_socket_acceptor<Protocol1,Executor1> && other)428   >::type operator=(basic_socket_acceptor<Protocol1, Executor1>&& other)
429   {
430     basic_socket_acceptor tmp(std::move(other));
431     impl_ = std::move(tmp.impl_);
432     return *this;
433   }
434 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
435 
436   /// Destroys the acceptor.
437   /**
438    * This function destroys the acceptor, cancelling any outstanding
439    * asynchronous operations associated with the acceptor as if by calling
440    * @c cancel.
441    */
~basic_socket_acceptor()442   ~basic_socket_acceptor()
443   {
444   }
445 
446   /// Get the executor associated with the object.
get_executor()447   executor_type get_executor() ASIO_NOEXCEPT
448   {
449     return impl_.get_executor();
450   }
451 
452   /// Open the acceptor using the specified protocol.
453   /**
454    * This function opens the socket acceptor so that it will use the specified
455    * protocol.
456    *
457    * @param protocol An object specifying which protocol is to be used.
458    *
459    * @throws asio::system_error Thrown on failure.
460    *
461    * @par Example
462    * @code
463    * asio::ip::tcp::acceptor acceptor(my_context);
464    * acceptor.open(asio::ip::tcp::v4());
465    * @endcode
466    */
open(const protocol_type & protocol=protocol_type ())467   void open(const protocol_type& protocol = protocol_type())
468   {
469     asio::error_code ec;
470     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
471     asio::detail::throw_error(ec, "open");
472   }
473 
474   /// Open the acceptor using the specified protocol.
475   /**
476    * This function opens the socket acceptor so that it will use the specified
477    * protocol.
478    *
479    * @param protocol An object specifying which protocol is to be used.
480    *
481    * @param ec Set to indicate what error occurred, if any.
482    *
483    * @par Example
484    * @code
485    * asio::ip::tcp::acceptor acceptor(my_context);
486    * asio::error_code ec;
487    * acceptor.open(asio::ip::tcp::v4(), ec);
488    * if (ec)
489    * {
490    *   // An error occurred.
491    * }
492    * @endcode
493    */
open(const protocol_type & protocol,asio::error_code & ec)494   ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
495       asio::error_code& ec)
496   {
497     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
498     ASIO_SYNC_OP_VOID_RETURN(ec);
499   }
500 
501   /// Assigns an existing native acceptor to the acceptor.
502   /*
503    * This function opens the acceptor to hold an existing native acceptor.
504    *
505    * @param protocol An object specifying which protocol is to be used.
506    *
507    * @param native_acceptor A native acceptor.
508    *
509    * @throws asio::system_error Thrown on failure.
510    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor)511   void assign(const protocol_type& protocol,
512       const native_handle_type& native_acceptor)
513   {
514     asio::error_code ec;
515     impl_.get_service().assign(impl_.get_implementation(),
516         protocol, native_acceptor, ec);
517     asio::detail::throw_error(ec, "assign");
518   }
519 
520   /// Assigns an existing native acceptor to the acceptor.
521   /*
522    * This function opens the acceptor to hold an existing native acceptor.
523    *
524    * @param protocol An object specifying which protocol is to be used.
525    *
526    * @param native_acceptor A native acceptor.
527    *
528    * @param ec Set to indicate what error occurred, if any.
529    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor,asio::error_code & ec)530   ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
531       const native_handle_type& native_acceptor, asio::error_code& ec)
532   {
533     impl_.get_service().assign(impl_.get_implementation(),
534         protocol, native_acceptor, ec);
535     ASIO_SYNC_OP_VOID_RETURN(ec);
536   }
537 
538   /// Determine whether the acceptor is open.
is_open() const539   bool is_open() const
540   {
541     return impl_.get_service().is_open(impl_.get_implementation());
542   }
543 
544   /// Bind the acceptor to the given local endpoint.
545   /**
546    * This function binds the socket acceptor to the specified endpoint on the
547    * local machine.
548    *
549    * @param endpoint An endpoint on the local machine to which the socket
550    * acceptor will be bound.
551    *
552    * @throws asio::system_error Thrown on failure.
553    *
554    * @par Example
555    * @code
556    * asio::ip::tcp::acceptor acceptor(my_context);
557    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
558    * acceptor.open(endpoint.protocol());
559    * acceptor.bind(endpoint);
560    * @endcode
561    */
bind(const endpoint_type & endpoint)562   void bind(const endpoint_type& endpoint)
563   {
564     asio::error_code ec;
565     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
566     asio::detail::throw_error(ec, "bind");
567   }
568 
569   /// Bind the acceptor to the given local endpoint.
570   /**
571    * This function binds the socket acceptor to the specified endpoint on the
572    * local machine.
573    *
574    * @param endpoint An endpoint on the local machine to which the socket
575    * acceptor will be bound.
576    *
577    * @param ec Set to indicate what error occurred, if any.
578    *
579    * @par Example
580    * @code
581    * asio::ip::tcp::acceptor acceptor(my_context);
582    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
583    * acceptor.open(endpoint.protocol());
584    * asio::error_code ec;
585    * acceptor.bind(endpoint, ec);
586    * if (ec)
587    * {
588    *   // An error occurred.
589    * }
590    * @endcode
591    */
bind(const endpoint_type & endpoint,asio::error_code & ec)592   ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
593       asio::error_code& ec)
594   {
595     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
596     ASIO_SYNC_OP_VOID_RETURN(ec);
597   }
598 
599   /// Place the acceptor into the state where it will listen for new
600   /// connections.
601   /**
602    * This function puts the socket acceptor into the state where it may accept
603    * new connections.
604    *
605    * @param backlog The maximum length of the queue of pending connections.
606    *
607    * @throws asio::system_error Thrown on failure.
608    */
listen(int backlog=socket_base::max_listen_connections)609   void listen(int backlog = socket_base::max_listen_connections)
610   {
611     asio::error_code ec;
612     impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
613     asio::detail::throw_error(ec, "listen");
614   }
615 
616   /// Place the acceptor into the state where it will listen for new
617   /// connections.
618   /**
619    * This function puts the socket acceptor into the state where it may accept
620    * new connections.
621    *
622    * @param backlog The maximum length of the queue of pending connections.
623    *
624    * @param ec Set to indicate what error occurred, if any.
625    *
626    * @par Example
627    * @code
628    * asio::ip::tcp::acceptor acceptor(my_context);
629    * ...
630    * asio::error_code ec;
631    * acceptor.listen(asio::socket_base::max_listen_connections, ec);
632    * if (ec)
633    * {
634    *   // An error occurred.
635    * }
636    * @endcode
637    */
listen(int backlog,asio::error_code & ec)638   ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code& ec)
639   {
640     impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
641     ASIO_SYNC_OP_VOID_RETURN(ec);
642   }
643 
644   /// Close the acceptor.
645   /**
646    * This function is used to close the acceptor. Any asynchronous accept
647    * operations will be cancelled immediately.
648    *
649    * A subsequent call to open() is required before the acceptor can again be
650    * used to again perform socket accept operations.
651    *
652    * @throws asio::system_error Thrown on failure.
653    */
close()654   void close()
655   {
656     asio::error_code ec;
657     impl_.get_service().close(impl_.get_implementation(), ec);
658     asio::detail::throw_error(ec, "close");
659   }
660 
661   /// Close the acceptor.
662   /**
663    * This function is used to close the acceptor. Any asynchronous accept
664    * operations will be cancelled immediately.
665    *
666    * A subsequent call to open() is required before the acceptor can again be
667    * used to again perform socket accept operations.
668    *
669    * @param ec Set to indicate what error occurred, if any.
670    *
671    * @par Example
672    * @code
673    * asio::ip::tcp::acceptor acceptor(my_context);
674    * ...
675    * asio::error_code ec;
676    * acceptor.close(ec);
677    * if (ec)
678    * {
679    *   // An error occurred.
680    * }
681    * @endcode
682    */
close(asio::error_code & ec)683   ASIO_SYNC_OP_VOID close(asio::error_code& ec)
684   {
685     impl_.get_service().close(impl_.get_implementation(), ec);
686     ASIO_SYNC_OP_VOID_RETURN(ec);
687   }
688 
689   /// Release ownership of the underlying native acceptor.
690   /**
691    * This function causes all outstanding asynchronous accept operations to
692    * finish immediately, and the handlers for cancelled operations will be
693    * passed the asio::error::operation_aborted error. Ownership of the
694    * native acceptor is then transferred to the caller.
695    *
696    * @throws asio::system_error Thrown on failure.
697    *
698    * @note This function is unsupported on Windows versions prior to Windows
699    * 8.1, and will fail with asio::error::operation_not_supported on
700    * these platforms.
701    */
702 #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
703   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
704   __declspec(deprecated("This function always fails with "
705         "operation_not_supported when used on Windows versions "
706         "prior to Windows 8.1."))
707 #endif
release()708   native_handle_type release()
709   {
710     asio::error_code ec;
711     native_handle_type s = impl_.get_service().release(
712         impl_.get_implementation(), ec);
713     asio::detail::throw_error(ec, "release");
714     return s;
715   }
716 
717   /// Release ownership of the underlying native acceptor.
718   /**
719    * This function causes all outstanding asynchronous accept operations to
720    * finish immediately, and the handlers for cancelled operations will be
721    * passed the asio::error::operation_aborted error. Ownership of the
722    * native acceptor is then transferred to the caller.
723    *
724    * @param ec Set to indicate what error occurred, if any.
725    *
726    * @note This function is unsupported on Windows versions prior to Windows
727    * 8.1, and will fail with asio::error::operation_not_supported on
728    * these platforms.
729    */
730 #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
731   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
732   __declspec(deprecated("This function always fails with "
733         "operation_not_supported when used on Windows versions "
734         "prior to Windows 8.1."))
735 #endif
release(asio::error_code & ec)736   native_handle_type release(asio::error_code& ec)
737   {
738     return impl_.get_service().release(impl_.get_implementation(), ec);
739   }
740 
741   /// Get the native acceptor representation.
742   /**
743    * This function may be used to obtain the underlying representation of the
744    * acceptor. This is intended to allow access to native acceptor functionality
745    * that is not otherwise provided.
746    */
native_handle()747   native_handle_type native_handle()
748   {
749     return impl_.get_service().native_handle(impl_.get_implementation());
750   }
751 
752   /// Cancel all asynchronous operations associated with the acceptor.
753   /**
754    * This function causes all outstanding asynchronous connect, send and receive
755    * operations to finish immediately, and the handlers for cancelled operations
756    * will be passed the asio::error::operation_aborted error.
757    *
758    * @throws asio::system_error Thrown on failure.
759    */
cancel()760   void cancel()
761   {
762     asio::error_code ec;
763     impl_.get_service().cancel(impl_.get_implementation(), ec);
764     asio::detail::throw_error(ec, "cancel");
765   }
766 
767   /// Cancel all asynchronous operations associated with the acceptor.
768   /**
769    * This function causes all outstanding asynchronous connect, send and receive
770    * operations to finish immediately, and the handlers for cancelled operations
771    * will be passed the asio::error::operation_aborted error.
772    *
773    * @param ec Set to indicate what error occurred, if any.
774    */
cancel(asio::error_code & ec)775   ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
776   {
777     impl_.get_service().cancel(impl_.get_implementation(), ec);
778     ASIO_SYNC_OP_VOID_RETURN(ec);
779   }
780 
781   /// Set an option on the acceptor.
782   /**
783    * This function is used to set an option on the acceptor.
784    *
785    * @param option The new option value to be set on the acceptor.
786    *
787    * @throws asio::system_error Thrown on failure.
788    *
789    * @sa SettableSocketOption @n
790    * asio::socket_base::reuse_address
791    * asio::socket_base::enable_connection_aborted
792    *
793    * @par Example
794    * Setting the SOL_SOCKET/SO_REUSEADDR option:
795    * @code
796    * asio::ip::tcp::acceptor acceptor(my_context);
797    * ...
798    * asio::ip::tcp::acceptor::reuse_address option(true);
799    * acceptor.set_option(option);
800    * @endcode
801    */
802   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option)803   void set_option(const SettableSocketOption& option)
804   {
805     asio::error_code ec;
806     impl_.get_service().set_option(impl_.get_implementation(), option, ec);
807     asio::detail::throw_error(ec, "set_option");
808   }
809 
810   /// Set an option on the acceptor.
811   /**
812    * This function is used to set an option on the acceptor.
813    *
814    * @param option The new option value to be set on the acceptor.
815    *
816    * @param ec Set to indicate what error occurred, if any.
817    *
818    * @sa SettableSocketOption @n
819    * asio::socket_base::reuse_address
820    * asio::socket_base::enable_connection_aborted
821    *
822    * @par Example
823    * Setting the SOL_SOCKET/SO_REUSEADDR option:
824    * @code
825    * asio::ip::tcp::acceptor acceptor(my_context);
826    * ...
827    * asio::ip::tcp::acceptor::reuse_address option(true);
828    * asio::error_code ec;
829    * acceptor.set_option(option, ec);
830    * if (ec)
831    * {
832    *   // An error occurred.
833    * }
834    * @endcode
835    */
836   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option,asio::error_code & ec)837   ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
838       asio::error_code& ec)
839   {
840     impl_.get_service().set_option(impl_.get_implementation(), option, ec);
841     ASIO_SYNC_OP_VOID_RETURN(ec);
842   }
843 
844   /// Get an option from the acceptor.
845   /**
846    * This function is used to get the current value of an option on the
847    * acceptor.
848    *
849    * @param option The option value to be obtained from the acceptor.
850    *
851    * @throws asio::system_error Thrown on failure.
852    *
853    * @sa GettableSocketOption @n
854    * asio::socket_base::reuse_address
855    *
856    * @par Example
857    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
858    * @code
859    * asio::ip::tcp::acceptor acceptor(my_context);
860    * ...
861    * asio::ip::tcp::acceptor::reuse_address option;
862    * acceptor.get_option(option);
863    * bool is_set = option.get();
864    * @endcode
865    */
866   template <typename GettableSocketOption>
get_option(GettableSocketOption & option) const867   void get_option(GettableSocketOption& option) const
868   {
869     asio::error_code ec;
870     impl_.get_service().get_option(impl_.get_implementation(), option, ec);
871     asio::detail::throw_error(ec, "get_option");
872   }
873 
874   /// Get an option from the acceptor.
875   /**
876    * This function is used to get the current value of an option on the
877    * acceptor.
878    *
879    * @param option The option value to be obtained from the acceptor.
880    *
881    * @param ec Set to indicate what error occurred, if any.
882    *
883    * @sa GettableSocketOption @n
884    * asio::socket_base::reuse_address
885    *
886    * @par Example
887    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
888    * @code
889    * asio::ip::tcp::acceptor acceptor(my_context);
890    * ...
891    * asio::ip::tcp::acceptor::reuse_address option;
892    * asio::error_code ec;
893    * acceptor.get_option(option, ec);
894    * if (ec)
895    * {
896    *   // An error occurred.
897    * }
898    * bool is_set = option.get();
899    * @endcode
900    */
901   template <typename GettableSocketOption>
get_option(GettableSocketOption & option,asio::error_code & ec) const902   ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
903       asio::error_code& ec) const
904   {
905     impl_.get_service().get_option(impl_.get_implementation(), option, ec);
906     ASIO_SYNC_OP_VOID_RETURN(ec);
907   }
908 
909   /// Perform an IO control command on the acceptor.
910   /**
911    * This function is used to execute an IO control command on the acceptor.
912    *
913    * @param command The IO control command to be performed on the acceptor.
914    *
915    * @throws asio::system_error Thrown on failure.
916    *
917    * @sa IoControlCommand @n
918    * asio::socket_base::non_blocking_io
919    *
920    * @par Example
921    * Getting the number of bytes ready to read:
922    * @code
923    * asio::ip::tcp::acceptor acceptor(my_context);
924    * ...
925    * asio::ip::tcp::acceptor::non_blocking_io command(true);
926    * socket.io_control(command);
927    * @endcode
928    */
929   template <typename IoControlCommand>
io_control(IoControlCommand & command)930   void io_control(IoControlCommand& command)
931   {
932     asio::error_code ec;
933     impl_.get_service().io_control(impl_.get_implementation(), command, ec);
934     asio::detail::throw_error(ec, "io_control");
935   }
936 
937   /// Perform an IO control command on the acceptor.
938   /**
939    * This function is used to execute an IO control command on the acceptor.
940    *
941    * @param command The IO control command to be performed on the acceptor.
942    *
943    * @param ec Set to indicate what error occurred, if any.
944    *
945    * @sa IoControlCommand @n
946    * asio::socket_base::non_blocking_io
947    *
948    * @par Example
949    * Getting the number of bytes ready to read:
950    * @code
951    * asio::ip::tcp::acceptor acceptor(my_context);
952    * ...
953    * asio::ip::tcp::acceptor::non_blocking_io command(true);
954    * asio::error_code ec;
955    * socket.io_control(command, ec);
956    * if (ec)
957    * {
958    *   // An error occurred.
959    * }
960    * @endcode
961    */
962   template <typename IoControlCommand>
io_control(IoControlCommand & command,asio::error_code & ec)963   ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
964       asio::error_code& ec)
965   {
966     impl_.get_service().io_control(impl_.get_implementation(), command, ec);
967     ASIO_SYNC_OP_VOID_RETURN(ec);
968   }
969 
970   /// Gets the non-blocking mode of the acceptor.
971   /**
972    * @returns @c true if the acceptor's synchronous operations will fail with
973    * asio::error::would_block if they are unable to perform the requested
974    * operation immediately. If @c false, synchronous operations will block
975    * until complete.
976    *
977    * @note The non-blocking mode has no effect on the behaviour of asynchronous
978    * operations. Asynchronous operations will never fail with the error
979    * asio::error::would_block.
980    */
non_blocking() const981   bool non_blocking() const
982   {
983     return impl_.get_service().non_blocking(impl_.get_implementation());
984   }
985 
986   /// Sets the non-blocking mode of the acceptor.
987   /**
988    * @param mode If @c true, the acceptor's synchronous operations will fail
989    * with asio::error::would_block if they are unable to perform the
990    * requested operation immediately. If @c false, synchronous operations will
991    * block until complete.
992    *
993    * @throws asio::system_error Thrown on failure.
994    *
995    * @note The non-blocking mode has no effect on the behaviour of asynchronous
996    * operations. Asynchronous operations will never fail with the error
997    * asio::error::would_block.
998    */
non_blocking(bool mode)999   void non_blocking(bool mode)
1000   {
1001     asio::error_code ec;
1002     impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
1003     asio::detail::throw_error(ec, "non_blocking");
1004   }
1005 
1006   /// Sets the non-blocking mode of the acceptor.
1007   /**
1008    * @param mode If @c true, the acceptor's synchronous operations will fail
1009    * with asio::error::would_block if they are unable to perform the
1010    * requested operation immediately. If @c false, synchronous operations will
1011    * block until complete.
1012    *
1013    * @param ec Set to indicate what error occurred, if any.
1014    *
1015    * @note The non-blocking mode has no effect on the behaviour of asynchronous
1016    * operations. Asynchronous operations will never fail with the error
1017    * asio::error::would_block.
1018    */
non_blocking(bool mode,asio::error_code & ec)1019   ASIO_SYNC_OP_VOID non_blocking(
1020       bool mode, asio::error_code& ec)
1021   {
1022     impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
1023     ASIO_SYNC_OP_VOID_RETURN(ec);
1024   }
1025 
1026   /// Gets the non-blocking mode of the native acceptor implementation.
1027   /**
1028    * This function is used to retrieve the non-blocking mode of the underlying
1029    * native acceptor. This mode has no effect on the behaviour of the acceptor
1030    * object's synchronous operations.
1031    *
1032    * @returns @c true if the underlying acceptor is in non-blocking mode and
1033    * direct system calls may fail with asio::error::would_block (or the
1034    * equivalent system error).
1035    *
1036    * @note The current non-blocking mode is cached by the acceptor object.
1037    * Consequently, the return value may be incorrect if the non-blocking mode
1038    * was set directly on the native acceptor.
1039    */
native_non_blocking() const1040   bool native_non_blocking() const
1041   {
1042     return impl_.get_service().native_non_blocking(impl_.get_implementation());
1043   }
1044 
1045   /// Sets the non-blocking mode of the native acceptor implementation.
1046   /**
1047    * This function is used to modify the non-blocking mode of the underlying
1048    * native acceptor. It has no effect on the behaviour of the acceptor object's
1049    * synchronous operations.
1050    *
1051    * @param mode If @c true, the underlying acceptor is put into non-blocking
1052    * mode and direct system calls may fail with asio::error::would_block
1053    * (or the equivalent system error).
1054    *
1055    * @throws asio::system_error Thrown on failure. If the @c mode is
1056    * @c false, but the current value of @c non_blocking() is @c true, this
1057    * function fails with asio::error::invalid_argument, as the
1058    * combination does not make sense.
1059    */
native_non_blocking(bool mode)1060   void native_non_blocking(bool mode)
1061   {
1062     asio::error_code ec;
1063     impl_.get_service().native_non_blocking(
1064         impl_.get_implementation(), mode, ec);
1065     asio::detail::throw_error(ec, "native_non_blocking");
1066   }
1067 
1068   /// Sets the non-blocking mode of the native acceptor implementation.
1069   /**
1070    * This function is used to modify the non-blocking mode of the underlying
1071    * native acceptor. It has no effect on the behaviour of the acceptor object's
1072    * synchronous operations.
1073    *
1074    * @param mode If @c true, the underlying acceptor is put into non-blocking
1075    * mode and direct system calls may fail with asio::error::would_block
1076    * (or the equivalent system error).
1077    *
1078    * @param ec Set to indicate what error occurred, if any. If the @c mode is
1079    * @c false, but the current value of @c non_blocking() is @c true, this
1080    * function fails with asio::error::invalid_argument, as the
1081    * combination does not make sense.
1082    */
native_non_blocking(bool mode,asio::error_code & ec)1083   ASIO_SYNC_OP_VOID native_non_blocking(
1084       bool mode, asio::error_code& ec)
1085   {
1086     impl_.get_service().native_non_blocking(
1087         impl_.get_implementation(), mode, ec);
1088     ASIO_SYNC_OP_VOID_RETURN(ec);
1089   }
1090 
1091   /// Get the local endpoint of the acceptor.
1092   /**
1093    * This function is used to obtain the locally bound endpoint of the acceptor.
1094    *
1095    * @returns An object that represents the local endpoint of the acceptor.
1096    *
1097    * @throws asio::system_error Thrown on failure.
1098    *
1099    * @par Example
1100    * @code
1101    * asio::ip::tcp::acceptor acceptor(my_context);
1102    * ...
1103    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
1104    * @endcode
1105    */
local_endpoint() const1106   endpoint_type local_endpoint() const
1107   {
1108     asio::error_code ec;
1109     endpoint_type ep = impl_.get_service().local_endpoint(
1110         impl_.get_implementation(), ec);
1111     asio::detail::throw_error(ec, "local_endpoint");
1112     return ep;
1113   }
1114 
1115   /// Get the local endpoint of the acceptor.
1116   /**
1117    * This function is used to obtain the locally bound endpoint of the acceptor.
1118    *
1119    * @param ec Set to indicate what error occurred, if any.
1120    *
1121    * @returns An object that represents the local endpoint of the acceptor.
1122    * Returns a default-constructed endpoint object if an error occurred and the
1123    * error handler did not throw an exception.
1124    *
1125    * @par Example
1126    * @code
1127    * asio::ip::tcp::acceptor acceptor(my_context);
1128    * ...
1129    * asio::error_code ec;
1130    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
1131    * if (ec)
1132    * {
1133    *   // An error occurred.
1134    * }
1135    * @endcode
1136    */
local_endpoint(asio::error_code & ec) const1137   endpoint_type local_endpoint(asio::error_code& ec) const
1138   {
1139     return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
1140   }
1141 
1142   /// Wait for the acceptor to become ready to read, ready to write, or to have
1143   /// pending error conditions.
1144   /**
1145    * This function is used to perform a blocking wait for an acceptor to enter
1146    * a ready to read, write or error condition state.
1147    *
1148    * @param w Specifies the desired acceptor state.
1149    *
1150    * @par Example
1151    * Waiting for an acceptor to become readable.
1152    * @code
1153    * asio::ip::tcp::acceptor acceptor(my_context);
1154    * ...
1155    * acceptor.wait(asio::ip::tcp::acceptor::wait_read);
1156    * @endcode
1157    */
wait(wait_type w)1158   void wait(wait_type w)
1159   {
1160     asio::error_code ec;
1161     impl_.get_service().wait(impl_.get_implementation(), w, ec);
1162     asio::detail::throw_error(ec, "wait");
1163   }
1164 
1165   /// Wait for the acceptor to become ready to read, ready to write, or to have
1166   /// pending error conditions.
1167   /**
1168    * This function is used to perform a blocking wait for an acceptor to enter
1169    * a ready to read, write or error condition state.
1170    *
1171    * @param w Specifies the desired acceptor state.
1172    *
1173    * @param ec Set to indicate what error occurred, if any.
1174    *
1175    * @par Example
1176    * Waiting for an acceptor to become readable.
1177    * @code
1178    * asio::ip::tcp::acceptor acceptor(my_context);
1179    * ...
1180    * asio::error_code ec;
1181    * acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec);
1182    * @endcode
1183    */
wait(wait_type w,asio::error_code & ec)1184   ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec)
1185   {
1186     impl_.get_service().wait(impl_.get_implementation(), w, ec);
1187     ASIO_SYNC_OP_VOID_RETURN(ec);
1188   }
1189 
1190   /// Asynchronously wait for the acceptor to become ready to read, ready to
1191   /// write, or to have pending error conditions.
1192   /**
1193    * This function is used to perform an asynchronous wait for an acceptor to
1194    * enter a ready to read, write or error condition state.
1195    *
1196    * @param w Specifies the desired acceptor state.
1197    *
1198    * @param handler The handler to be called when the wait operation completes.
1199    * Copies will be made of the handler as required. The function signature of
1200    * the handler must be:
1201    * @code void handler(
1202    *   const asio::error_code& error // Result of operation
1203    * ); @endcode
1204    * Regardless of whether the asynchronous operation completes immediately or
1205    * not, the handler will not be invoked from within this function. On
1206    * immediate completion, invocation of the handler will be performed in a
1207    * manner equivalent to using asio::post().
1208    *
1209    * @par Example
1210    * @code
1211    * void wait_handler(const asio::error_code& error)
1212    * {
1213    *   if (!error)
1214    *   {
1215    *     // Wait succeeded.
1216    *   }
1217    * }
1218    *
1219    * ...
1220    *
1221    * asio::ip::tcp::acceptor acceptor(my_context);
1222    * ...
1223    * acceptor.async_wait(
1224    *     asio::ip::tcp::acceptor::wait_read,
1225    *     wait_handler);
1226    * @endcode
1227    */
1228   template <
1229       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))
1230         WaitHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,void (asio::error_code))1231   ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
1232       void (asio::error_code))
1233   async_wait(wait_type w,
1234       ASIO_MOVE_ARG(WaitHandler) handler
1235         ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1236   {
1237     return async_initiate<WaitHandler, void (asio::error_code)>(
1238         initiate_async_wait(this), handler, w);
1239   }
1240 
1241 #if !defined(ASIO_NO_EXTENSIONS)
1242   /// Accept a new connection.
1243   /**
1244    * This function is used to accept a new connection from a peer into the
1245    * given socket. The function call will block until a new connection has been
1246    * accepted successfully or an error occurs.
1247    *
1248    * @param peer The socket into which the new connection will be accepted.
1249    *
1250    * @throws asio::system_error Thrown on failure.
1251    *
1252    * @par Example
1253    * @code
1254    * asio::ip::tcp::acceptor acceptor(my_context);
1255    * ...
1256    * asio::ip::tcp::socket socket(my_context);
1257    * acceptor.accept(socket);
1258    * @endcode
1259    */
1260   template <typename Protocol1, typename Executor1>
accept(basic_socket<Protocol1,Executor1> & peer,typename constraint<is_convertible<Protocol,Protocol1>::value>::type=0)1261   void accept(basic_socket<Protocol1, Executor1>& peer,
1262       typename constraint<
1263         is_convertible<Protocol, Protocol1>::value
1264       >::type = 0)
1265   {
1266     asio::error_code ec;
1267     impl_.get_service().accept(impl_.get_implementation(),
1268         peer, static_cast<endpoint_type*>(0), ec);
1269     asio::detail::throw_error(ec, "accept");
1270   }
1271 
1272   /// Accept a new connection.
1273   /**
1274    * This function is used to accept a new connection from a peer into the
1275    * given socket. The function call will block until a new connection has been
1276    * accepted successfully or an error occurs.
1277    *
1278    * @param peer The socket into which the new connection will be accepted.
1279    *
1280    * @param ec Set to indicate what error occurred, if any.
1281    *
1282    * @par Example
1283    * @code
1284    * asio::ip::tcp::acceptor acceptor(my_context);
1285    * ...
1286    * asio::ip::tcp::socket socket(my_context);
1287    * asio::error_code ec;
1288    * acceptor.accept(socket, ec);
1289    * if (ec)
1290    * {
1291    *   // An error occurred.
1292    * }
1293    * @endcode
1294    */
1295   template <typename Protocol1, typename Executor1>
accept(basic_socket<Protocol1,Executor1> & peer,asio::error_code & ec,typename constraint<is_convertible<Protocol,Protocol1>::value>::type=0)1296   ASIO_SYNC_OP_VOID accept(
1297       basic_socket<Protocol1, Executor1>& peer, asio::error_code& ec,
1298       typename constraint<
1299         is_convertible<Protocol, Protocol1>::value
1300       >::type = 0)
1301   {
1302     impl_.get_service().accept(impl_.get_implementation(),
1303         peer, static_cast<endpoint_type*>(0), ec);
1304     ASIO_SYNC_OP_VOID_RETURN(ec);
1305   }
1306 
1307   /// Start an asynchronous accept.
1308   /**
1309    * This function is used to asynchronously accept a new connection into a
1310    * socket. The function call always returns immediately.
1311    *
1312    * @param peer The socket into which the new connection will be accepted.
1313    * Ownership of the peer object is retained by the caller, which must
1314    * guarantee that it is valid until the handler is called.
1315    *
1316    * @param handler The handler to be called when the accept operation
1317    * completes. Copies will be made of the handler as required. The function
1318    * signature of the handler must be:
1319    * @code void handler(
1320    *   const asio::error_code& error // Result of operation.
1321    * ); @endcode
1322    * Regardless of whether the asynchronous operation completes immediately or
1323    * not, the handler will not be invoked from within this function. On
1324    * immediate completion, invocation of the handler will be performed in a
1325    * manner equivalent to using asio::post().
1326    *
1327    * @par Example
1328    * @code
1329    * void accept_handler(const asio::error_code& error)
1330    * {
1331    *   if (!error)
1332    *   {
1333    *     // Accept succeeded.
1334    *   }
1335    * }
1336    *
1337    * ...
1338    *
1339    * asio::ip::tcp::acceptor acceptor(my_context);
1340    * ...
1341    * asio::ip::tcp::socket socket(my_context);
1342    * acceptor.async_accept(socket, accept_handler);
1343    * @endcode
1344    */
1345   template <typename Protocol1, typename Executor1,
1346       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))
1347         AcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,void (asio::error_code))1348   ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,
1349       void (asio::error_code))
1350   async_accept(basic_socket<Protocol1, Executor1>& peer,
1351       ASIO_MOVE_ARG(AcceptHandler) handler
1352         ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1353       typename constraint<
1354         is_convertible<Protocol, Protocol1>::value
1355       >::type = 0)
1356   {
1357     return async_initiate<AcceptHandler, void (asio::error_code)>(
1358         initiate_async_accept(this), handler,
1359         &peer, static_cast<endpoint_type*>(0));
1360   }
1361 
1362   /// Accept a new connection and obtain the endpoint of the peer
1363   /**
1364    * This function is used to accept a new connection from a peer into the
1365    * given socket, and additionally provide the endpoint of the remote peer.
1366    * The function call will block until a new connection has been accepted
1367    * successfully or an error occurs.
1368    *
1369    * @param peer The socket into which the new connection will be accepted.
1370    *
1371    * @param peer_endpoint An endpoint object which will receive the endpoint of
1372    * the remote peer.
1373    *
1374    * @throws asio::system_error Thrown on failure.
1375    *
1376    * @par Example
1377    * @code
1378    * asio::ip::tcp::acceptor acceptor(my_context);
1379    * ...
1380    * asio::ip::tcp::socket socket(my_context);
1381    * asio::ip::tcp::endpoint endpoint;
1382    * acceptor.accept(socket, endpoint);
1383    * @endcode
1384    */
1385   template <typename Executor1>
accept(basic_socket<protocol_type,Executor1> & peer,endpoint_type & peer_endpoint)1386   void accept(basic_socket<protocol_type, Executor1>& peer,
1387       endpoint_type& peer_endpoint)
1388   {
1389     asio::error_code ec;
1390     impl_.get_service().accept(impl_.get_implementation(),
1391         peer, &peer_endpoint, ec);
1392     asio::detail::throw_error(ec, "accept");
1393   }
1394 
1395   /// Accept a new connection and obtain the endpoint of the peer
1396   /**
1397    * This function is used to accept a new connection from a peer into the
1398    * given socket, and additionally provide the endpoint of the remote peer.
1399    * The function call will block until a new connection has been accepted
1400    * successfully or an error occurs.
1401    *
1402    * @param peer The socket into which the new connection will be accepted.
1403    *
1404    * @param peer_endpoint An endpoint object which will receive the endpoint of
1405    * the remote peer.
1406    *
1407    * @param ec Set to indicate what error occurred, if any.
1408    *
1409    * @par Example
1410    * @code
1411    * asio::ip::tcp::acceptor acceptor(my_context);
1412    * ...
1413    * asio::ip::tcp::socket socket(my_context);
1414    * asio::ip::tcp::endpoint endpoint;
1415    * asio::error_code ec;
1416    * acceptor.accept(socket, endpoint, ec);
1417    * if (ec)
1418    * {
1419    *   // An error occurred.
1420    * }
1421    * @endcode
1422    */
1423   template <typename Executor1>
accept(basic_socket<protocol_type,Executor1> & peer,endpoint_type & peer_endpoint,asio::error_code & ec)1424   ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type, Executor1>& peer,
1425       endpoint_type& peer_endpoint, asio::error_code& ec)
1426   {
1427     impl_.get_service().accept(
1428         impl_.get_implementation(), peer, &peer_endpoint, ec);
1429     ASIO_SYNC_OP_VOID_RETURN(ec);
1430   }
1431 
1432   /// Start an asynchronous accept.
1433   /**
1434    * This function is used to asynchronously accept a new connection into a
1435    * socket, and additionally obtain the endpoint of the remote peer. The
1436    * function call always returns immediately.
1437    *
1438    * @param peer The socket into which the new connection will be accepted.
1439    * Ownership of the peer object is retained by the caller, which must
1440    * guarantee that it is valid until the handler is called.
1441    *
1442    * @param peer_endpoint An endpoint object into which the endpoint of the
1443    * remote peer will be written. Ownership of the peer_endpoint object is
1444    * retained by the caller, which must guarantee that it is valid until the
1445    * handler is called.
1446    *
1447    * @param handler The handler to be called when the accept operation
1448    * completes. Copies will be made of the handler as required. The function
1449    * signature of the handler must be:
1450    * @code void handler(
1451    *   const asio::error_code& error // Result of operation.
1452    * ); @endcode
1453    * Regardless of whether the asynchronous operation completes immediately or
1454    * not, the handler will not be invoked from within this function. On
1455    * immediate completion, invocation of the handler will be performed in a
1456    * manner equivalent to using asio::post().
1457    */
1458   template <typename Executor1,
1459       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))
1460         AcceptHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,void (asio::error_code))1461   ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,
1462       void (asio::error_code))
1463   async_accept(basic_socket<protocol_type, Executor1>& peer,
1464       endpoint_type& peer_endpoint,
1465       ASIO_MOVE_ARG(AcceptHandler) handler
1466         ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1467   {
1468     return async_initiate<AcceptHandler, void (asio::error_code)>(
1469         initiate_async_accept(this), handler, &peer, &peer_endpoint);
1470   }
1471 #endif // !defined(ASIO_NO_EXTENSIONS)
1472 
1473 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
1474   /// Accept a new connection.
1475   /**
1476    * This function is used to accept a new connection from a peer. The function
1477    * call will block until a new connection has been accepted successfully or
1478    * an error occurs.
1479    *
1480    * This overload requires that the Protocol template parameter satisfy the
1481    * AcceptableProtocol type requirements.
1482    *
1483    * @returns A socket object representing the newly accepted connection.
1484    *
1485    * @throws asio::system_error Thrown on failure.
1486    *
1487    * @par Example
1488    * @code
1489    * asio::ip::tcp::acceptor acceptor(my_context);
1490    * ...
1491    * asio::ip::tcp::socket socket(acceptor.accept());
1492    * @endcode
1493    */
1494   typename Protocol::socket::template rebind_executor<executor_type>::other
accept()1495   accept()
1496   {
1497     asio::error_code ec;
1498     typename Protocol::socket::template rebind_executor<
1499       executor_type>::other peer(impl_.get_executor());
1500     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1501     asio::detail::throw_error(ec, "accept");
1502     return peer;
1503   }
1504 
1505   /// Accept a new connection.
1506   /**
1507    * This function is used to accept a new connection from a peer. The function
1508    * call will block until a new connection has been accepted successfully or
1509    * an error occurs.
1510    *
1511    * This overload requires that the Protocol template parameter satisfy the
1512    * AcceptableProtocol type requirements.
1513    *
1514    * @param ec Set to indicate what error occurred, if any.
1515    *
1516    * @returns On success, a socket object representing the newly accepted
1517    * connection. On error, a socket object where is_open() is false.
1518    *
1519    * @par Example
1520    * @code
1521    * asio::ip::tcp::acceptor acceptor(my_context);
1522    * ...
1523    * asio::ip::tcp::socket socket(acceptor.accept(ec));
1524    * if (ec)
1525    * {
1526    *   // An error occurred.
1527    * }
1528    * @endcode
1529    */
1530   typename Protocol::socket::template rebind_executor<executor_type>::other
accept(asio::error_code & ec)1531   accept(asio::error_code& ec)
1532   {
1533     typename Protocol::socket::template rebind_executor<
1534       executor_type>::other peer(impl_.get_executor());
1535     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1536     return peer;
1537   }
1538 
1539   /// Start an asynchronous accept.
1540   /**
1541    * This function is used to asynchronously accept a new connection. The
1542    * function call always returns immediately.
1543    *
1544    * This overload requires that the Protocol template parameter satisfy the
1545    * AcceptableProtocol type requirements.
1546    *
1547    * @param handler The handler to be called when the accept operation
1548    * completes. Copies will be made of the handler as required. The function
1549    * signature of the handler must be:
1550    * @code void handler(
1551    *   // Result of operation.
1552    *   const asio::error_code& error,
1553    *   // On success, the newly accepted socket.
1554    *   typename Protocol::socket::template
1555    *     rebind_executor<executor_type>::other peer
1556    * ); @endcode
1557    * Regardless of whether the asynchronous operation completes immediately or
1558    * not, the handler will not be invoked from within this function. On
1559    * immediate completion, invocation of the handler will be performed in a
1560    * manner equivalent to using asio::post().
1561    *
1562    * @par Example
1563    * @code
1564    * void accept_handler(const asio::error_code& error,
1565    *     asio::ip::tcp::socket peer)
1566    * {
1567    *   if (!error)
1568    *   {
1569    *     // Accept succeeded.
1570    *   }
1571    * }
1572    *
1573    * ...
1574    *
1575    * asio::ip::tcp::acceptor acceptor(my_context);
1576    * ...
1577    * acceptor.async_accept(accept_handler);
1578    * @endcode
1579    */
1580   template <
1581       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
1582         typename Protocol::socket::template rebind_executor<
1583           executor_type>::other)) MoveAcceptHandler
1584             ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<executor_type>::other))1585   ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1586       void (asio::error_code,
1587         typename Protocol::socket::template
1588           rebind_executor<executor_type>::other))
1589   async_accept(
1590       ASIO_MOVE_ARG(MoveAcceptHandler) handler
1591         ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1592   {
1593     return async_initiate<MoveAcceptHandler,
1594       void (asio::error_code, typename Protocol::socket::template
1595         rebind_executor<executor_type>::other)>(
1596           initiate_async_move_accept(this), handler,
1597           impl_.get_executor(), static_cast<endpoint_type*>(0),
1598           static_cast<typename Protocol::socket::template
1599             rebind_executor<executor_type>::other*>(0));
1600   }
1601 
1602   /// Accept a new connection.
1603   /**
1604    * This function is used to accept a new connection from a peer. The function
1605    * call will block until a new connection has been accepted successfully or
1606    * an error occurs.
1607    *
1608    * This overload requires that the Protocol template parameter satisfy the
1609    * AcceptableProtocol type requirements.
1610    *
1611    * @param ex The I/O executor object to be used for the newly
1612    * accepted socket.
1613    *
1614    * @returns A socket object representing the newly accepted connection.
1615    *
1616    * @throws asio::system_error Thrown on failure.
1617    *
1618    * @par Example
1619    * @code
1620    * asio::ip::tcp::acceptor acceptor(my_context);
1621    * ...
1622    * asio::ip::tcp::socket socket(acceptor.accept());
1623    * @endcode
1624    */
1625   template <typename Executor1>
1626   typename Protocol::socket::template rebind_executor<Executor1>::other
accept(const Executor1 & ex,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)1627   accept(const Executor1& ex,
1628       typename constraint<
1629         is_executor<Executor1>::value
1630           || execution::is_executor<Executor1>::value
1631       >::type = 0)
1632   {
1633     asio::error_code ec;
1634     typename Protocol::socket::template
1635       rebind_executor<Executor1>::other peer(ex);
1636     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1637     asio::detail::throw_error(ec, "accept");
1638     return peer;
1639   }
1640 
1641   /// Accept a new connection.
1642   /**
1643    * This function is used to accept a new connection from a peer. The function
1644    * call will block until a new connection has been accepted successfully or
1645    * an error occurs.
1646    *
1647    * This overload requires that the Protocol template parameter satisfy the
1648    * AcceptableProtocol type requirements.
1649    *
1650    * @param context The I/O execution context object to be used for the newly
1651    * accepted socket.
1652    *
1653    * @returns A socket object representing the newly accepted connection.
1654    *
1655    * @throws asio::system_error Thrown on failure.
1656    *
1657    * @par Example
1658    * @code
1659    * asio::ip::tcp::acceptor acceptor(my_context);
1660    * ...
1661    * asio::ip::tcp::socket socket(acceptor.accept());
1662    * @endcode
1663    */
1664   template <typename ExecutionContext>
1665   typename Protocol::socket::template rebind_executor<
1666       typename ExecutionContext::executor_type>::other
accept(ExecutionContext & context,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)1667   accept(ExecutionContext& context,
1668       typename constraint<
1669         is_convertible<ExecutionContext&, execution_context&>::value
1670       >::type = 0)
1671   {
1672     asio::error_code ec;
1673     typename Protocol::socket::template rebind_executor<
1674         typename ExecutionContext::executor_type>::other peer(context);
1675     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1676     asio::detail::throw_error(ec, "accept");
1677     return peer;
1678   }
1679 
1680   /// Accept a new connection.
1681   /**
1682    * This function is used to accept a new connection from a peer. The function
1683    * call will block until a new connection has been accepted successfully or
1684    * an error occurs.
1685    *
1686    * This overload requires that the Protocol template parameter satisfy the
1687    * AcceptableProtocol type requirements.
1688    *
1689    * @param ex The I/O executor object to be used for the newly accepted
1690    * socket.
1691    *
1692    * @param ec Set to indicate what error occurred, if any.
1693    *
1694    * @returns On success, a socket object representing the newly accepted
1695    * connection. On error, a socket object where is_open() is false.
1696    *
1697    * @par Example
1698    * @code
1699    * asio::ip::tcp::acceptor acceptor(my_context);
1700    * ...
1701    * asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1702    * if (ec)
1703    * {
1704    *   // An error occurred.
1705    * }
1706    * @endcode
1707    */
1708   template <typename Executor1>
1709   typename Protocol::socket::template rebind_executor<Executor1>::other
accept(const Executor1 & ex,asio::error_code & ec,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)1710   accept(const Executor1& ex, asio::error_code& ec,
1711       typename constraint<
1712         is_executor<Executor1>::value
1713           || execution::is_executor<Executor1>::value
1714       >::type = 0)
1715   {
1716     typename Protocol::socket::template
1717       rebind_executor<Executor1>::other peer(ex);
1718     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1719     return peer;
1720   }
1721 
1722   /// Accept a new connection.
1723   /**
1724    * This function is used to accept a new connection from a peer. The function
1725    * call will block until a new connection has been accepted successfully or
1726    * an error occurs.
1727    *
1728    * This overload requires that the Protocol template parameter satisfy the
1729    * AcceptableProtocol type requirements.
1730    *
1731    * @param context The I/O execution context object to be used for the newly
1732    * accepted socket.
1733    *
1734    * @param ec Set to indicate what error occurred, if any.
1735    *
1736    * @returns On success, a socket object representing the newly accepted
1737    * connection. On error, a socket object where is_open() is false.
1738    *
1739    * @par Example
1740    * @code
1741    * asio::ip::tcp::acceptor acceptor(my_context);
1742    * ...
1743    * asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1744    * if (ec)
1745    * {
1746    *   // An error occurred.
1747    * }
1748    * @endcode
1749    */
1750   template <typename ExecutionContext>
1751   typename Protocol::socket::template rebind_executor<
1752       typename ExecutionContext::executor_type>::other
accept(ExecutionContext & context,asio::error_code & ec,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)1753   accept(ExecutionContext& context, asio::error_code& ec,
1754       typename constraint<
1755         is_convertible<ExecutionContext&, execution_context&>::value
1756       >::type = 0)
1757   {
1758     typename Protocol::socket::template rebind_executor<
1759         typename ExecutionContext::executor_type>::other peer(context);
1760     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1761     return peer;
1762   }
1763 
1764   /// Start an asynchronous accept.
1765   /**
1766    * This function is used to asynchronously accept a new connection. The
1767    * function call always returns immediately.
1768    *
1769    * This overload requires that the Protocol template parameter satisfy the
1770    * AcceptableProtocol type requirements.
1771    *
1772    * @param ex The I/O executor object to be used for the newly accepted
1773    * socket.
1774    *
1775    * @param handler The handler to be called when the accept operation
1776    * completes. Copies will be made of the handler as required. The function
1777    * signature of the handler must be:
1778    * @code void handler(
1779    *   const asio::error_code& error, // Result of operation.
1780    *   typename Protocol::socket::template rebind_executor<
1781    *     Executor1>::other peer // On success, the newly accepted socket.
1782    * ); @endcode
1783    * Regardless of whether the asynchronous operation completes immediately or
1784    * not, the handler will not be invoked from within this function. On
1785    * immediate completion, invocation of the handler will be performed in a
1786    * manner equivalent to using asio::post().
1787    *
1788    * @par Example
1789    * @code
1790    * void accept_handler(const asio::error_code& error,
1791    *     asio::ip::tcp::socket peer)
1792    * {
1793    *   if (!error)
1794    *   {
1795    *     // Accept succeeded.
1796    *   }
1797    * }
1798    *
1799    * ...
1800    *
1801    * asio::ip::tcp::acceptor acceptor(my_context);
1802    * ...
1803    * acceptor.async_accept(my_context2, accept_handler);
1804    * @endcode
1805    */
1806   template <typename Executor1,
1807       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
1808         typename Protocol::socket::template rebind_executor<
1809           Executor1>::other)) MoveAcceptHandler
1810             ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<Executor1>::other))1811   ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1812       void (asio::error_code,
1813         typename Protocol::socket::template rebind_executor<
1814           Executor1>::other))
1815   async_accept(const Executor1& ex,
1816       ASIO_MOVE_ARG(MoveAcceptHandler) handler
1817         ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1818       typename constraint<
1819         is_executor<Executor1>::value
1820           || execution::is_executor<Executor1>::value
1821       >::type = 0)
1822   {
1823     typedef typename Protocol::socket::template rebind_executor<
1824       Executor1>::other other_socket_type;
1825 
1826     return async_initiate<MoveAcceptHandler,
1827       void (asio::error_code, other_socket_type)>(
1828         initiate_async_move_accept(this), handler,
1829         ex, static_cast<endpoint_type*>(0),
1830         static_cast<other_socket_type*>(0));
1831   }
1832 
1833   /// Start an asynchronous accept.
1834   /**
1835    * This function is used to asynchronously accept a new connection. The
1836    * function call always returns immediately.
1837    *
1838    * This overload requires that the Protocol template parameter satisfy the
1839    * AcceptableProtocol type requirements.
1840    *
1841    * @param context The I/O execution context object to be used for the newly
1842    * accepted socket.
1843    *
1844    * @param handler The handler to be called when the accept operation
1845    * completes. Copies will be made of the handler as required. The function
1846    * signature of the handler must be:
1847    * @code void handler(
1848    *   const asio::error_code& error, // Result of operation.
1849    *   typename Protocol::socket::template rebind_executor<
1850    *     typename ExecutionContext::executor_type>::other peer
1851    *       // On success, the newly accepted socket.
1852    * ); @endcode
1853    * Regardless of whether the asynchronous operation completes immediately or
1854    * not, the handler will not be invoked from within this function. On
1855    * immediate completion, invocation of the handler will be performed in a
1856    * manner equivalent to using asio::post().
1857    *
1858    * @par Example
1859    * @code
1860    * void accept_handler(const asio::error_code& error,
1861    *     asio::ip::tcp::socket peer)
1862    * {
1863    *   if (!error)
1864    *   {
1865    *     // Accept succeeded.
1866    *   }
1867    * }
1868    *
1869    * ...
1870    *
1871    * asio::ip::tcp::acceptor acceptor(my_context);
1872    * ...
1873    * acceptor.async_accept(my_context2, accept_handler);
1874    * @endcode
1875    */
1876   template <typename ExecutionContext,
1877       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
1878         typename Protocol::socket::template rebind_executor<
1879           typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
1880             ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<typename ExecutionContext::executor_type>::other))1881   ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1882       void (asio::error_code,
1883         typename Protocol::socket::template rebind_executor<
1884           typename ExecutionContext::executor_type>::other))
1885   async_accept(ExecutionContext& context,
1886       ASIO_MOVE_ARG(MoveAcceptHandler) handler
1887         ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1888       typename constraint<
1889         is_convertible<ExecutionContext&, execution_context&>::value
1890       >::type = 0)
1891   {
1892     typedef typename Protocol::socket::template rebind_executor<
1893       typename ExecutionContext::executor_type>::other other_socket_type;
1894 
1895     return async_initiate<MoveAcceptHandler,
1896       void (asio::error_code, other_socket_type)>(
1897         initiate_async_move_accept(this), handler,
1898         context.get_executor(), static_cast<endpoint_type*>(0),
1899         static_cast<other_socket_type*>(0));
1900   }
1901 
1902   /// Accept a new connection.
1903   /**
1904    * This function is used to accept a new connection from a peer. The function
1905    * call will block until a new connection has been accepted successfully or
1906    * an error occurs.
1907    *
1908    * This overload requires that the Protocol template parameter satisfy the
1909    * AcceptableProtocol type requirements.
1910    *
1911    * @param peer_endpoint An endpoint object into which the endpoint of the
1912    * remote peer will be written.
1913    *
1914    * @returns A socket object representing the newly accepted connection.
1915    *
1916    * @throws asio::system_error Thrown on failure.
1917    *
1918    * @par Example
1919    * @code
1920    * asio::ip::tcp::acceptor acceptor(my_context);
1921    * ...
1922    * asio::ip::tcp::endpoint endpoint;
1923    * asio::ip::tcp::socket socket(acceptor.accept(endpoint));
1924    * @endcode
1925    */
1926   typename Protocol::socket::template rebind_executor<executor_type>::other
accept(endpoint_type & peer_endpoint)1927   accept(endpoint_type& peer_endpoint)
1928   {
1929     asio::error_code ec;
1930     typename Protocol::socket::template rebind_executor<
1931       executor_type>::other peer(impl_.get_executor());
1932     impl_.get_service().accept(impl_.get_implementation(),
1933         peer, &peer_endpoint, ec);
1934     asio::detail::throw_error(ec, "accept");
1935     return peer;
1936   }
1937 
1938   /// Accept a new connection.
1939   /**
1940    * This function is used to accept a new connection from a peer. The function
1941    * call will block until a new connection has been accepted successfully or
1942    * an error occurs.
1943    *
1944    * This overload requires that the Protocol template parameter satisfy the
1945    * AcceptableProtocol type requirements.
1946    *
1947    * @param peer_endpoint An endpoint object into which the endpoint of the
1948    * remote peer will be written.
1949    *
1950    * @param ec Set to indicate what error occurred, if any.
1951    *
1952    * @returns On success, a socket object representing the newly accepted
1953    * connection. On error, a socket object where is_open() is false.
1954    *
1955    * @par Example
1956    * @code
1957    * asio::ip::tcp::acceptor acceptor(my_context);
1958    * ...
1959    * asio::ip::tcp::endpoint endpoint;
1960    * asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
1961    * if (ec)
1962    * {
1963    *   // An error occurred.
1964    * }
1965    * @endcode
1966    */
1967   typename Protocol::socket::template rebind_executor<executor_type>::other
accept(endpoint_type & peer_endpoint,asio::error_code & ec)1968   accept(endpoint_type& peer_endpoint, asio::error_code& ec)
1969   {
1970     typename Protocol::socket::template rebind_executor<
1971       executor_type>::other peer(impl_.get_executor());
1972     impl_.get_service().accept(impl_.get_implementation(),
1973         peer, &peer_endpoint, ec);
1974     return peer;
1975   }
1976 
1977   /// Start an asynchronous accept.
1978   /**
1979    * This function is used to asynchronously accept a new connection. The
1980    * function call always returns immediately.
1981    *
1982    * This overload requires that the Protocol template parameter satisfy the
1983    * AcceptableProtocol type requirements.
1984    *
1985    * @param peer_endpoint An endpoint object into which the endpoint of the
1986    * remote peer will be written. Ownership of the peer_endpoint object is
1987    * retained by the caller, which must guarantee that it is valid until the
1988    * handler is called.
1989    *
1990    * @param handler The handler to be called when the accept operation
1991    * completes. Copies will be made of the handler as required. The function
1992    * signature of the handler must be:
1993    * @code void handler(
1994    *   // Result of operation.
1995    *   const asio::error_code& error,
1996    *   // On success, the newly accepted socket.
1997    *   typename Protocol::socket::template
1998    *     rebind_executor<executor_type>::other peer
1999    * ); @endcode
2000    * Regardless of whether the asynchronous operation completes immediately or
2001    * not, the handler will not be invoked from within this function. On
2002    * immediate completion, invocation of the handler will be performed in a
2003    * manner equivalent to using asio::post().
2004    *
2005    * @par Example
2006    * @code
2007    * void accept_handler(const asio::error_code& error,
2008    *     asio::ip::tcp::socket peer)
2009    * {
2010    *   if (!error)
2011    *   {
2012    *     // Accept succeeded.
2013    *   }
2014    * }
2015    *
2016    * ...
2017    *
2018    * asio::ip::tcp::acceptor acceptor(my_context);
2019    * ...
2020    * asio::ip::tcp::endpoint endpoint;
2021    * acceptor.async_accept(endpoint, accept_handler);
2022    * @endcode
2023    */
2024   template <
2025       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
2026         typename Protocol::socket::template rebind_executor<
2027           executor_type>::other)) MoveAcceptHandler
2028             ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<executor_type>::other))2029   ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2030       void (asio::error_code,
2031         typename Protocol::socket::template
2032           rebind_executor<executor_type>::other))
2033   async_accept(endpoint_type& peer_endpoint,
2034       ASIO_MOVE_ARG(MoveAcceptHandler) handler
2035         ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
2036   {
2037     return async_initiate<MoveAcceptHandler,
2038       void (asio::error_code, typename Protocol::socket::template
2039         rebind_executor<executor_type>::other)>(
2040           initiate_async_move_accept(this), handler,
2041           impl_.get_executor(), &peer_endpoint,
2042           static_cast<typename Protocol::socket::template
2043             rebind_executor<executor_type>::other*>(0));
2044   }
2045 
2046   /// Accept a new connection.
2047   /**
2048    * This function is used to accept a new connection from a peer. The function
2049    * call will block until a new connection has been accepted successfully or
2050    * an error occurs.
2051    *
2052    * This overload requires that the Protocol template parameter satisfy the
2053    * AcceptableProtocol type requirements.
2054    *
2055    * @param ex The I/O executor object to be used for the newly accepted
2056    * socket.
2057    *
2058    * @param peer_endpoint An endpoint object into which the endpoint of the
2059    * remote peer will be written.
2060    *
2061    * @returns A socket object representing the newly accepted connection.
2062    *
2063    * @throws asio::system_error Thrown on failure.
2064    *
2065    * @par Example
2066    * @code
2067    * asio::ip::tcp::acceptor acceptor(my_context);
2068    * ...
2069    * asio::ip::tcp::endpoint endpoint;
2070    * asio::ip::tcp::socket socket(
2071    *     acceptor.accept(my_context2, endpoint));
2072    * @endcode
2073    */
2074   template <typename Executor1>
2075   typename Protocol::socket::template rebind_executor<Executor1>::other
accept(const Executor1 & ex,endpoint_type & peer_endpoint,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)2076   accept(const Executor1& ex, endpoint_type& peer_endpoint,
2077       typename constraint<
2078         is_executor<Executor1>::value
2079           || execution::is_executor<Executor1>::value
2080       >::type = 0)
2081   {
2082     asio::error_code ec;
2083     typename Protocol::socket::template
2084         rebind_executor<Executor1>::other peer(ex);
2085     impl_.get_service().accept(impl_.get_implementation(),
2086         peer, &peer_endpoint, ec);
2087     asio::detail::throw_error(ec, "accept");
2088     return peer;
2089   }
2090 
2091   /// Accept a new connection.
2092   /**
2093    * This function is used to accept a new connection from a peer. The function
2094    * call will block until a new connection has been accepted successfully or
2095    * an error occurs.
2096    *
2097    * This overload requires that the Protocol template parameter satisfy the
2098    * AcceptableProtocol type requirements.
2099    *
2100    * @param context The I/O execution context object to be used for the newly
2101    * accepted socket.
2102    *
2103    * @param peer_endpoint An endpoint object into which the endpoint of the
2104    * remote peer will be written.
2105    *
2106    * @returns A socket object representing the newly accepted connection.
2107    *
2108    * @throws asio::system_error Thrown on failure.
2109    *
2110    * @par Example
2111    * @code
2112    * asio::ip::tcp::acceptor acceptor(my_context);
2113    * ...
2114    * asio::ip::tcp::endpoint endpoint;
2115    * asio::ip::tcp::socket socket(
2116    *     acceptor.accept(my_context2, endpoint));
2117    * @endcode
2118    */
2119   template <typename ExecutionContext>
2120   typename Protocol::socket::template rebind_executor<
2121       typename ExecutionContext::executor_type>::other
accept(ExecutionContext & context,endpoint_type & peer_endpoint,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)2122   accept(ExecutionContext& context, endpoint_type& peer_endpoint,
2123       typename constraint<
2124         is_convertible<ExecutionContext&, execution_context&>::value
2125       >::type = 0)
2126   {
2127     asio::error_code ec;
2128     typename Protocol::socket::template rebind_executor<
2129         typename ExecutionContext::executor_type>::other peer(context);
2130     impl_.get_service().accept(impl_.get_implementation(),
2131         peer, &peer_endpoint, ec);
2132     asio::detail::throw_error(ec, "accept");
2133     return peer;
2134   }
2135 
2136   /// Accept a new connection.
2137   /**
2138    * This function is used to accept a new connection from a peer. The function
2139    * call will block until a new connection has been accepted successfully or
2140    * an error occurs.
2141    *
2142    * This overload requires that the Protocol template parameter satisfy the
2143    * AcceptableProtocol type requirements.
2144    *
2145    * @param ex The I/O executor object to be used for the newly accepted
2146    * socket.
2147    *
2148    * @param peer_endpoint An endpoint object into which the endpoint of the
2149    * remote peer will be written.
2150    *
2151    * @param ec Set to indicate what error occurred, if any.
2152    *
2153    * @returns On success, a socket object representing the newly accepted
2154    * connection. On error, a socket object where is_open() is false.
2155    *
2156    * @par Example
2157    * @code
2158    * asio::ip::tcp::acceptor acceptor(my_context);
2159    * ...
2160    * asio::ip::tcp::endpoint endpoint;
2161    * asio::ip::tcp::socket socket(
2162    *     acceptor.accept(my_context2, endpoint, ec));
2163    * if (ec)
2164    * {
2165    *   // An error occurred.
2166    * }
2167    * @endcode
2168    */
2169   template <typename Executor1>
2170   typename Protocol::socket::template rebind_executor<Executor1>::other
accept(const executor_type & ex,endpoint_type & peer_endpoint,asio::error_code & ec,typename constraint<is_executor<Executor1>::value||execution::is_executor<Executor1>::value>::type=0)2171   accept(const executor_type& ex,
2172       endpoint_type& peer_endpoint, asio::error_code& ec,
2173       typename constraint<
2174         is_executor<Executor1>::value
2175           || execution::is_executor<Executor1>::value
2176       >::type = 0)
2177   {
2178     typename Protocol::socket::template
2179       rebind_executor<Executor1>::other peer(ex);
2180     impl_.get_service().accept(impl_.get_implementation(),
2181         peer, &peer_endpoint, ec);
2182     return peer;
2183   }
2184 
2185   /// Accept a new connection.
2186   /**
2187    * This function is used to accept a new connection from a peer. The function
2188    * call will block until a new connection has been accepted successfully or
2189    * an error occurs.
2190    *
2191    * This overload requires that the Protocol template parameter satisfy the
2192    * AcceptableProtocol type requirements.
2193    *
2194    * @param context The I/O execution context object to be used for the newly
2195    * accepted socket.
2196    *
2197    * @param peer_endpoint An endpoint object into which the endpoint of the
2198    * remote peer will be written.
2199    *
2200    * @param ec Set to indicate what error occurred, if any.
2201    *
2202    * @returns On success, a socket object representing the newly accepted
2203    * connection. On error, a socket object where is_open() is false.
2204    *
2205    * @par Example
2206    * @code
2207    * asio::ip::tcp::acceptor acceptor(my_context);
2208    * ...
2209    * asio::ip::tcp::endpoint endpoint;
2210    * asio::ip::tcp::socket socket(
2211    *     acceptor.accept(my_context2, endpoint, ec));
2212    * if (ec)
2213    * {
2214    *   // An error occurred.
2215    * }
2216    * @endcode
2217    */
2218   template <typename ExecutionContext>
2219   typename Protocol::socket::template rebind_executor<
2220       typename ExecutionContext::executor_type>::other
accept(ExecutionContext & context,endpoint_type & peer_endpoint,asio::error_code & ec,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)2221   accept(ExecutionContext& context,
2222       endpoint_type& peer_endpoint, asio::error_code& ec,
2223       typename constraint<
2224         is_convertible<ExecutionContext&, execution_context&>::value
2225       >::type = 0)
2226   {
2227     typename Protocol::socket::template rebind_executor<
2228         typename ExecutionContext::executor_type>::other peer(context);
2229     impl_.get_service().accept(impl_.get_implementation(),
2230         peer, &peer_endpoint, ec);
2231     return peer;
2232   }
2233 
2234   /// Start an asynchronous accept.
2235   /**
2236    * This function is used to asynchronously accept a new connection. The
2237    * function call always returns immediately.
2238    *
2239    * This overload requires that the Protocol template parameter satisfy the
2240    * AcceptableProtocol type requirements.
2241    *
2242    * @param ex The I/O executor object to be used for the newly accepted
2243    * socket.
2244    *
2245    * @param peer_endpoint An endpoint object into which the endpoint of the
2246    * remote peer will be written. Ownership of the peer_endpoint object is
2247    * retained by the caller, which must guarantee that it is valid until the
2248    * handler is called.
2249    *
2250    * @param handler The handler to be called when the accept operation
2251    * completes. Copies will be made of the handler as required. The function
2252    * signature of the handler must be:
2253    * @code void handler(
2254    *   const asio::error_code& error, // Result of operation.
2255    *   typename Protocol::socket::template rebind_executor<
2256    *     Executor1>::other peer // On success, the newly accepted socket.
2257    * ); @endcode
2258    * Regardless of whether the asynchronous operation completes immediately or
2259    * not, the handler will not be invoked from within this function. On
2260    * immediate completion, invocation of the handler will be performed in a
2261    * manner equivalent to using asio::post().
2262    *
2263    * @par Example
2264    * @code
2265    * void accept_handler(const asio::error_code& error,
2266    *     asio::ip::tcp::socket peer)
2267    * {
2268    *   if (!error)
2269    *   {
2270    *     // Accept succeeded.
2271    *   }
2272    * }
2273    *
2274    * ...
2275    *
2276    * asio::ip::tcp::acceptor acceptor(my_context);
2277    * ...
2278    * asio::ip::tcp::endpoint endpoint;
2279    * acceptor.async_accept(my_context2, endpoint, accept_handler);
2280    * @endcode
2281    */
2282   template <typename Executor1,
2283       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
2284         typename Protocol::socket::template rebind_executor<
2285           Executor1>::other)) MoveAcceptHandler
2286             ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<Executor1>::other))2287   ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2288       void (asio::error_code,
2289         typename Protocol::socket::template rebind_executor<
2290           Executor1>::other))
2291   async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
2292       ASIO_MOVE_ARG(MoveAcceptHandler) handler
2293         ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2294       typename constraint<
2295         is_executor<Executor1>::value
2296           || execution::is_executor<Executor1>::value
2297       >::type = 0)
2298   {
2299     typedef typename Protocol::socket::template rebind_executor<
2300       Executor1>::other other_socket_type;
2301 
2302     return async_initiate<MoveAcceptHandler,
2303       void (asio::error_code, other_socket_type)>(
2304         initiate_async_move_accept(this), handler,
2305         ex, &peer_endpoint,
2306         static_cast<other_socket_type*>(0));
2307   }
2308 
2309   /// Start an asynchronous accept.
2310   /**
2311    * This function is used to asynchronously accept a new connection. The
2312    * function call always returns immediately.
2313    *
2314    * This overload requires that the Protocol template parameter satisfy the
2315    * AcceptableProtocol type requirements.
2316    *
2317    * @param context The I/O execution context object to be used for the newly
2318    * accepted socket.
2319    *
2320    * @param peer_endpoint An endpoint object into which the endpoint of the
2321    * remote peer will be written. Ownership of the peer_endpoint object is
2322    * retained by the caller, which must guarantee that it is valid until the
2323    * handler is called.
2324    *
2325    * @param handler The handler to be called when the accept operation
2326    * completes. Copies will be made of the handler as required. The function
2327    * signature of the handler must be:
2328    * @code void handler(
2329    *   const asio::error_code& error, // Result of operation.
2330    *   typename Protocol::socket::template rebind_executor<
2331    *     typename ExecutionContext::executor_type>::other peer
2332    *       // On success, the newly accepted socket.
2333    * ); @endcode
2334    * Regardless of whether the asynchronous operation completes immediately or
2335    * not, the handler will not be invoked from within this function. On
2336    * immediate completion, invocation of the handler will be performed in a
2337    * manner equivalent to using asio::post().
2338    *
2339    * @par Example
2340    * @code
2341    * void accept_handler(const asio::error_code& error,
2342    *     asio::ip::tcp::socket peer)
2343    * {
2344    *   if (!error)
2345    *   {
2346    *     // Accept succeeded.
2347    *   }
2348    * }
2349    *
2350    * ...
2351    *
2352    * asio::ip::tcp::acceptor acceptor(my_context);
2353    * ...
2354    * asio::ip::tcp::endpoint endpoint;
2355    * acceptor.async_accept(my_context2, endpoint, accept_handler);
2356    * @endcode
2357    */
2358   template <typename ExecutionContext,
2359       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
2360         typename Protocol::socket::template rebind_executor<
2361           typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
2362             ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<typename ExecutionContext::executor_type>::other))2363   ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2364       void (asio::error_code,
2365         typename Protocol::socket::template rebind_executor<
2366           typename ExecutionContext::executor_type>::other))
2367   async_accept(ExecutionContext& context,
2368       endpoint_type& peer_endpoint,
2369       ASIO_MOVE_ARG(MoveAcceptHandler) handler
2370         ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2371       typename constraint<
2372         is_convertible<ExecutionContext&, execution_context&>::value
2373       >::type = 0)
2374   {
2375     typedef typename Protocol::socket::template rebind_executor<
2376       typename ExecutionContext::executor_type>::other other_socket_type;
2377 
2378     return async_initiate<MoveAcceptHandler,
2379       void (asio::error_code, other_socket_type)>(
2380         initiate_async_move_accept(this), handler,
2381         context.get_executor(), &peer_endpoint,
2382         static_cast<other_socket_type*>(0));
2383   }
2384 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
2385 
2386 private:
2387   // Disallow copying and assignment.
2388   basic_socket_acceptor(const basic_socket_acceptor&) ASIO_DELETED;
2389   basic_socket_acceptor& operator=(
2390       const basic_socket_acceptor&) ASIO_DELETED;
2391 
2392   class initiate_async_wait
2393   {
2394   public:
2395     typedef Executor executor_type;
2396 
initiate_async_wait(basic_socket_acceptor * self)2397     explicit initiate_async_wait(basic_socket_acceptor* self)
2398       : self_(self)
2399     {
2400     }
2401 
get_executor() const2402     executor_type get_executor() const ASIO_NOEXCEPT
2403     {
2404       return self_->get_executor();
2405     }
2406 
2407     template <typename WaitHandler>
operator ()(ASIO_MOVE_ARG (WaitHandler)handler,wait_type w) const2408     void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
2409     {
2410       // If you get an error on the following line it means that your handler
2411       // does not meet the documented type requirements for a WaitHandler.
2412       ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
2413 
2414       detail::non_const_lvalue<WaitHandler> handler2(handler);
2415       self_->impl_.get_service().async_wait(
2416           self_->impl_.get_implementation(), w,
2417           handler2.value, self_->impl_.get_executor());
2418     }
2419 
2420   private:
2421     basic_socket_acceptor* self_;
2422   };
2423 
2424   class initiate_async_accept
2425   {
2426   public:
2427     typedef Executor executor_type;
2428 
initiate_async_accept(basic_socket_acceptor * self)2429     explicit initiate_async_accept(basic_socket_acceptor* self)
2430       : self_(self)
2431     {
2432     }
2433 
get_executor() const2434     executor_type get_executor() const ASIO_NOEXCEPT
2435     {
2436       return self_->get_executor();
2437     }
2438 
2439     template <typename AcceptHandler, typename Protocol1, typename Executor1>
operator ()(ASIO_MOVE_ARG (AcceptHandler)handler,basic_socket<Protocol1,Executor1> * peer,endpoint_type * peer_endpoint) const2440     void operator()(ASIO_MOVE_ARG(AcceptHandler) handler,
2441         basic_socket<Protocol1, Executor1>* peer,
2442         endpoint_type* peer_endpoint) const
2443     {
2444       // If you get an error on the following line it means that your handler
2445       // does not meet the documented type requirements for a AcceptHandler.
2446       ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
2447 
2448       detail::non_const_lvalue<AcceptHandler> handler2(handler);
2449       self_->impl_.get_service().async_accept(
2450           self_->impl_.get_implementation(), *peer, peer_endpoint,
2451           handler2.value, self_->impl_.get_executor());
2452     }
2453 
2454   private:
2455     basic_socket_acceptor* self_;
2456   };
2457 
2458   class initiate_async_move_accept
2459   {
2460   public:
2461     typedef Executor executor_type;
2462 
initiate_async_move_accept(basic_socket_acceptor * self)2463     explicit initiate_async_move_accept(basic_socket_acceptor* self)
2464       : self_(self)
2465     {
2466     }
2467 
get_executor() const2468     executor_type get_executor() const ASIO_NOEXCEPT
2469     {
2470       return self_->get_executor();
2471     }
2472 
2473     template <typename MoveAcceptHandler, typename Executor1, typename Socket>
operator ()(ASIO_MOVE_ARG (MoveAcceptHandler)handler,const Executor1 & peer_ex,endpoint_type * peer_endpoint,Socket *) const2474     void operator()(ASIO_MOVE_ARG(MoveAcceptHandler) handler,
2475         const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const
2476     {
2477       // If you get an error on the following line it means that your handler
2478       // does not meet the documented type requirements for a MoveAcceptHandler.
2479       ASIO_MOVE_ACCEPT_HANDLER_CHECK(
2480           MoveAcceptHandler, handler, Socket) type_check;
2481 
2482       detail::non_const_lvalue<MoveAcceptHandler> handler2(handler);
2483       self_->impl_.get_service().async_move_accept(
2484           self_->impl_.get_implementation(), peer_ex, peer_endpoint,
2485           handler2.value, self_->impl_.get_executor());
2486     }
2487 
2488   private:
2489     basic_socket_acceptor* self_;
2490   };
2491 
2492 #if defined(ASIO_WINDOWS_RUNTIME)
2493   detail::io_object_impl<
2494     detail::null_socket_service<Protocol>, Executor> impl_;
2495 #elif defined(ASIO_HAS_IOCP)
2496   detail::io_object_impl<
2497     detail::win_iocp_socket_service<Protocol>, Executor> impl_;
2498 #else
2499   detail::io_object_impl<
2500     detail::reactive_socket_service<Protocol>, Executor> impl_;
2501 #endif
2502 };
2503 
2504 } // namespace asio
2505 
2506 #include "asio/detail/pop_options.hpp"
2507 
2508 #endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP
2509