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