Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / asio / basic_socket_acceptor.hpp
1 //
2 // basic_socket_acceptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2019 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/basic_socket.hpp>
20 #include <boost/asio/detail/handler_type_requirements.hpp>
21 #include <boost/asio/detail/io_object_impl.hpp>
22 #include <boost/asio/detail/non_const_lvalue.hpp>
23 #include <boost/asio/detail/throw_error.hpp>
24 #include <boost/asio/detail/type_traits.hpp>
25 #include <boost/asio/error.hpp>
26 #include <boost/asio/execution_context.hpp>
27 #include <boost/asio/executor.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
50 // Forward declaration with defaulted arguments.
51 template <typename Protocol, typename Executor = 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)
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       >::type* = 0)
1625   {
1626     boost::system::error_code ec;
1627     typename Protocol::socket::template
1628       rebind_executor<Executor1>::other peer(ex);
1629     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1630     boost::asio::detail::throw_error(ec, "accept");
1631     return peer;
1632   }
1633
1634   /// Accept a new connection.
1635   /**
1636    * This function is used to accept a new connection from a peer. The function
1637    * call will block until a new connection has been accepted successfully or
1638    * an error occurs.
1639    *
1640    * This overload requires that the Protocol template parameter satisfy the
1641    * AcceptableProtocol type requirements.
1642    *
1643    * @param context The I/O execution context object to be used for the newly
1644    * accepted socket.
1645    *
1646    * @returns A socket object representing the newly accepted connection.
1647    *
1648    * @throws boost::system::system_error Thrown on failure.
1649    *
1650    * @par Example
1651    * @code
1652    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1653    * ...
1654    * boost::asio::ip::tcp::socket socket(acceptor.accept());
1655    * @endcode
1656    */
1657   template <typename ExecutionContext>
1658   typename Protocol::socket::template rebind_executor<
1659       typename ExecutionContext::executor_type>::other
1660   accept(ExecutionContext& context,
1661       typename enable_if<
1662         is_convertible<ExecutionContext&, execution_context&>::value
1663       >::type* = 0)
1664   {
1665     boost::system::error_code ec;
1666     typename Protocol::socket::template rebind_executor<
1667         typename ExecutionContext::executor_type>::other peer(context);
1668     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1669     boost::asio::detail::throw_error(ec, "accept");
1670     return peer;
1671   }
1672
1673   /// Accept a new connection.
1674   /**
1675    * This function is used to accept a new connection from a peer. The function
1676    * call will block until a new connection has been accepted successfully or
1677    * an error occurs.
1678    *
1679    * This overload requires that the Protocol template parameter satisfy the
1680    * AcceptableProtocol type requirements.
1681    *
1682    * @param ex The I/O executor object to be used for the newly accepted
1683    * socket.
1684    *
1685    * @param ec Set to indicate what error occurred, if any.
1686    *
1687    * @returns On success, a socket object representing the newly accepted
1688    * connection. On error, a socket object where is_open() is false.
1689    *
1690    * @par Example
1691    * @code
1692    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1693    * ...
1694    * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1695    * if (ec)
1696    * {
1697    *   // An error occurred.
1698    * }
1699    * @endcode
1700    */
1701   template <typename Executor1>
1702   typename Protocol::socket::template rebind_executor<Executor1>::other
1703   accept(const Executor1& ex, boost::system::error_code& ec,
1704       typename enable_if<
1705         is_executor<Executor1>::value
1706       >::type* = 0)
1707   {
1708     typename Protocol::socket::template
1709       rebind_executor<Executor1>::other peer(ex);
1710     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1711     return peer;
1712   }
1713
1714   /// Accept a new connection.
1715   /**
1716    * This function is used to accept a new connection from a peer. The function
1717    * call will block until a new connection has been accepted successfully or
1718    * an error occurs.
1719    *
1720    * This overload requires that the Protocol template parameter satisfy the
1721    * AcceptableProtocol type requirements.
1722    *
1723    * @param context The I/O execution context object to be used for the newly
1724    * accepted socket.
1725    *
1726    * @param ec Set to indicate what error occurred, if any.
1727    *
1728    * @returns On success, a socket object representing the newly accepted
1729    * connection. On error, a socket object where is_open() is false.
1730    *
1731    * @par Example
1732    * @code
1733    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1734    * ...
1735    * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1736    * if (ec)
1737    * {
1738    *   // An error occurred.
1739    * }
1740    * @endcode
1741    */
1742   template <typename ExecutionContext>
1743   typename Protocol::socket::template rebind_executor<
1744       typename ExecutionContext::executor_type>::other
1745   accept(ExecutionContext& context, boost::system::error_code& ec,
1746       typename enable_if<
1747         is_convertible<ExecutionContext&, execution_context&>::value
1748       >::type* = 0)
1749   {
1750     typename Protocol::socket::template rebind_executor<
1751         typename ExecutionContext::executor_type>::other peer(context);
1752     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1753     return peer;
1754   }
1755
1756   /// Start an asynchronous accept.
1757   /**
1758    * This function is used to asynchronously accept a new connection. The
1759    * function call always returns immediately.
1760    *
1761    * This overload requires that the Protocol template parameter satisfy the
1762    * AcceptableProtocol type requirements.
1763    *
1764    * @param ex The I/O executor object to be used for the newly accepted
1765    * socket.
1766    *
1767    * @param handler The handler to be called when the accept operation
1768    * completes. Copies will be made of the handler as required. The function
1769    * signature of the handler must be:
1770    * @code void handler(
1771    *   const boost::system::error_code& error, // Result of operation.
1772    *   typename Protocol::socket::template rebind_executor<
1773    *     Executor1>::other peer // On success, the newly accepted socket.
1774    * ); @endcode
1775    * Regardless of whether the asynchronous operation completes immediately or
1776    * not, the handler will not be invoked from within this function. On
1777    * immediate completion, invocation of the handler will be performed in a
1778    * manner equivalent to using boost::asio::post().
1779    *
1780    * @par Example
1781    * @code
1782    * void accept_handler(const boost::system::error_code& error,
1783    *     boost::asio::ip::tcp::socket peer)
1784    * {
1785    *   if (!error)
1786    *   {
1787    *     // Accept succeeded.
1788    *   }
1789    * }
1790    *
1791    * ...
1792    *
1793    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1794    * ...
1795    * acceptor.async_accept(my_context2, accept_handler);
1796    * @endcode
1797    */
1798   template <typename Executor1,
1799       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1800         typename Protocol::socket::template rebind_executor<
1801           Executor1>::other)) MoveAcceptHandler
1802             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1803   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1804       void (boost::system::error_code,
1805         typename Protocol::socket::template rebind_executor<
1806           Executor1>::other))
1807   async_accept(const Executor1& ex,
1808       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
1809         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1810       typename enable_if<
1811         is_executor<Executor1>::value
1812       >::type* = 0)
1813   {
1814     typedef typename Protocol::socket::template rebind_executor<
1815       Executor1>::other other_socket_type;
1816
1817     return async_initiate<MoveAcceptHandler,
1818       void (boost::system::error_code, other_socket_type)>(
1819         initiate_async_move_accept(this), handler,
1820         ex, static_cast<endpoint_type*>(0),
1821         static_cast<other_socket_type*>(0));
1822   }
1823
1824   /// Start an asynchronous accept.
1825   /**
1826    * This function is used to asynchronously accept a new connection. The
1827    * function call always returns immediately.
1828    *
1829    * This overload requires that the Protocol template parameter satisfy the
1830    * AcceptableProtocol type requirements.
1831    *
1832    * @param context The I/O execution context object to be used for the newly
1833    * accepted socket.
1834    *
1835    * @param handler The handler to be called when the accept operation
1836    * completes. Copies will be made of the handler as required. The function
1837    * signature of the handler must be:
1838    * @code void handler(
1839    *   const boost::system::error_code& error, // Result of operation.
1840    *   typename Protocol::socket::template rebind_executor<
1841    *     typename ExecutionContext::executor_type>::other peer
1842    *       // On success, the newly accepted socket.
1843    * ); @endcode
1844    * Regardless of whether the asynchronous operation completes immediately or
1845    * not, the handler will not be invoked from within this function. On
1846    * immediate completion, invocation of the handler will be performed in a
1847    * manner equivalent to using boost::asio::post().
1848    *
1849    * @par Example
1850    * @code
1851    * void accept_handler(const boost::system::error_code& error,
1852    *     boost::asio::ip::tcp::socket peer)
1853    * {
1854    *   if (!error)
1855    *   {
1856    *     // Accept succeeded.
1857    *   }
1858    * }
1859    *
1860    * ...
1861    *
1862    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1863    * ...
1864    * acceptor.async_accept(my_context2, accept_handler);
1865    * @endcode
1866    */
1867   template <typename ExecutionContext,
1868       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1869         typename Protocol::socket::template rebind_executor<
1870           typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
1871             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1872   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
1873       void (boost::system::error_code,
1874         typename Protocol::socket::template rebind_executor<
1875           typename ExecutionContext::executor_type>::other))
1876   async_accept(ExecutionContext& context,
1877       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
1878         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
1879       typename enable_if<
1880         is_convertible<ExecutionContext&, execution_context&>::value
1881       >::type* = 0)
1882   {
1883     typedef typename Protocol::socket::template rebind_executor<
1884       typename ExecutionContext::executor_type>::other other_socket_type;
1885
1886     return async_initiate<MoveAcceptHandler,
1887       void (boost::system::error_code, other_socket_type)>(
1888         initiate_async_move_accept(this), handler,
1889         context.get_executor(), static_cast<endpoint_type*>(0),
1890         static_cast<other_socket_type*>(0));
1891   }
1892
1893   /// Accept a new connection.
1894   /**
1895    * This function is used to accept a new connection from a peer. The function
1896    * call will block until a new connection has been accepted successfully or
1897    * an error occurs.
1898    *
1899    * This overload requires that the Protocol template parameter satisfy the
1900    * AcceptableProtocol type requirements.
1901    *
1902    * @param peer_endpoint An endpoint object into which the endpoint of the
1903    * remote peer will be written.
1904    *
1905    * @returns A socket object representing the newly accepted connection.
1906    *
1907    * @throws boost::system::system_error Thrown on failure.
1908    *
1909    * @par Example
1910    * @code
1911    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1912    * ...
1913    * boost::asio::ip::tcp::endpoint endpoint;
1914    * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint));
1915    * @endcode
1916    */
1917   typename Protocol::socket::template rebind_executor<executor_type>::other
1918   accept(endpoint_type& peer_endpoint)
1919   {
1920     boost::system::error_code ec;
1921     typename Protocol::socket::template rebind_executor<
1922       executor_type>::other peer(impl_.get_executor());
1923     impl_.get_service().accept(impl_.get_implementation(),
1924         peer, &peer_endpoint, ec);
1925     boost::asio::detail::throw_error(ec, "accept");
1926     return peer;
1927   }
1928
1929   /// Accept a new connection.
1930   /**
1931    * This function is used to accept a new connection from a peer. The function
1932    * call will block until a new connection has been accepted successfully or
1933    * an error occurs.
1934    *
1935    * This overload requires that the Protocol template parameter satisfy the
1936    * AcceptableProtocol type requirements.
1937    *
1938    * @param peer_endpoint An endpoint object into which the endpoint of the
1939    * remote peer will be written.
1940    *
1941    * @param ec Set to indicate what error occurred, if any.
1942    *
1943    * @returns On success, a socket object representing the newly accepted
1944    * connection. On error, a socket object where is_open() is false.
1945    *
1946    * @par Example
1947    * @code
1948    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1949    * ...
1950    * boost::asio::ip::tcp::endpoint endpoint;
1951    * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
1952    * if (ec)
1953    * {
1954    *   // An error occurred.
1955    * }
1956    * @endcode
1957    */
1958   typename Protocol::socket::template rebind_executor<executor_type>::other
1959   accept(endpoint_type& peer_endpoint, boost::system::error_code& ec)
1960   {
1961     typename Protocol::socket::template rebind_executor<
1962       executor_type>::other peer(impl_.get_executor());
1963     impl_.get_service().accept(impl_.get_implementation(),
1964         peer, &peer_endpoint, ec);
1965     return peer;
1966   }
1967
1968   /// Start an asynchronous accept.
1969   /**
1970    * This function is used to asynchronously accept a new connection. The
1971    * function call always returns immediately.
1972    *
1973    * This overload requires that the Protocol template parameter satisfy the
1974    * AcceptableProtocol type requirements.
1975    *
1976    * @param peer_endpoint An endpoint object into which the endpoint of the
1977    * remote peer will be written. Ownership of the peer_endpoint object is
1978    * retained by the caller, which must guarantee that it is valid until the
1979    * handler is called.
1980    *
1981    * @param handler The handler to be called when the accept operation
1982    * completes. Copies will be made of the handler as required. The function
1983    * signature of the handler must be:
1984    * @code void handler(
1985    *   // Result of operation.
1986    *   const boost::system::error_code& error,
1987    *   // On success, the newly accepted socket.
1988    *   typename Protocol::socket::template
1989    *     rebind_executor<executor_type>::other peer
1990    * ); @endcode
1991    * Regardless of whether the asynchronous operation completes immediately or
1992    * not, the handler will not be invoked from within this function. On
1993    * immediate completion, invocation of the handler will be performed in a
1994    * manner equivalent to using boost::asio::post().
1995    *
1996    * @par Example
1997    * @code
1998    * void accept_handler(const boost::system::error_code& error,
1999    *     boost::asio::ip::tcp::socket peer)
2000    * {
2001    *   if (!error)
2002    *   {
2003    *     // Accept succeeded.
2004    *   }
2005    * }
2006    *
2007    * ...
2008    *
2009    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2010    * ...
2011    * boost::asio::ip::tcp::endpoint endpoint;
2012    * acceptor.async_accept(endpoint, accept_handler);
2013    * @endcode
2014    */
2015   template <
2016       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2017         typename Protocol::socket::template rebind_executor<
2018           executor_type>::other)) MoveAcceptHandler
2019             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
2020   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2021       void (boost::system::error_code,
2022         typename Protocol::socket::template
2023           rebind_executor<executor_type>::other))
2024   async_accept(endpoint_type& peer_endpoint,
2025       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
2026         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
2027   {
2028     return async_initiate<MoveAcceptHandler,
2029       void (boost::system::error_code, typename Protocol::socket::template
2030         rebind_executor<executor_type>::other)>(
2031           initiate_async_move_accept(this), handler,
2032           impl_.get_executor(), &peer_endpoint,
2033           static_cast<typename Protocol::socket::template
2034             rebind_executor<executor_type>::other*>(0));
2035   }
2036
2037   /// Accept a new connection.
2038   /**
2039    * This function is used to accept a new connection from a peer. The function
2040    * call will block until a new connection has been accepted successfully or
2041    * an error occurs.
2042    *
2043    * This overload requires that the Protocol template parameter satisfy the
2044    * AcceptableProtocol type requirements.
2045    *
2046    * @param ex The I/O executor object to be used for the newly accepted
2047    * socket.
2048    *
2049    * @param peer_endpoint An endpoint object into which the endpoint of the
2050    * remote peer will be written.
2051    *
2052    * @returns A socket object representing the newly accepted connection.
2053    *
2054    * @throws boost::system::system_error Thrown on failure.
2055    *
2056    * @par Example
2057    * @code
2058    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2059    * ...
2060    * boost::asio::ip::tcp::endpoint endpoint;
2061    * boost::asio::ip::tcp::socket socket(
2062    *     acceptor.accept(my_context2, endpoint));
2063    * @endcode
2064    */
2065   template <typename Executor1>
2066   typename Protocol::socket::template rebind_executor<Executor1>::other
2067   accept(const Executor1& ex, endpoint_type& peer_endpoint,
2068       typename enable_if<
2069         is_executor<Executor1>::value
2070       >::type* = 0)
2071   {
2072     boost::system::error_code ec;
2073     typename Protocol::socket::template
2074         rebind_executor<Executor1>::other peer(ex);
2075     impl_.get_service().accept(impl_.get_implementation(),
2076         peer, &peer_endpoint, ec);
2077     boost::asio::detail::throw_error(ec, "accept");
2078     return peer;
2079   }
2080
2081   /// Accept a new connection.
2082   /**
2083    * This function is used to accept a new connection from a peer. The function
2084    * call will block until a new connection has been accepted successfully or
2085    * an error occurs.
2086    *
2087    * This overload requires that the Protocol template parameter satisfy the
2088    * AcceptableProtocol type requirements.
2089    *
2090    * @param context The I/O execution context object to be used for the newly
2091    * accepted socket.
2092    *
2093    * @param peer_endpoint An endpoint object into which the endpoint of the
2094    * remote peer will be written.
2095    *
2096    * @returns A socket object representing the newly accepted connection.
2097    *
2098    * @throws boost::system::system_error Thrown on failure.
2099    *
2100    * @par Example
2101    * @code
2102    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2103    * ...
2104    * boost::asio::ip::tcp::endpoint endpoint;
2105    * boost::asio::ip::tcp::socket socket(
2106    *     acceptor.accept(my_context2, endpoint));
2107    * @endcode
2108    */
2109   template <typename ExecutionContext>
2110   typename Protocol::socket::template rebind_executor<
2111       typename ExecutionContext::executor_type>::other
2112   accept(ExecutionContext& context, endpoint_type& peer_endpoint,
2113       typename enable_if<
2114         is_convertible<ExecutionContext&, execution_context&>::value
2115       >::type* = 0)
2116   {
2117     boost::system::error_code ec;
2118     typename Protocol::socket::template rebind_executor<
2119         typename ExecutionContext::executor_type>::other peer(context);
2120     impl_.get_service().accept(impl_.get_implementation(),
2121         peer, &peer_endpoint, ec);
2122     boost::asio::detail::throw_error(ec, "accept");
2123     return peer;
2124   }
2125
2126   /// Accept a new connection.
2127   /**
2128    * This function is used to accept a new connection from a peer. The function
2129    * call will block until a new connection has been accepted successfully or
2130    * an error occurs.
2131    *
2132    * This overload requires that the Protocol template parameter satisfy the
2133    * AcceptableProtocol type requirements.
2134    *
2135    * @param ex The I/O executor object to be used for the newly accepted
2136    * socket.
2137    *
2138    * @param peer_endpoint An endpoint object into which the endpoint of the
2139    * remote peer will be written.
2140    *
2141    * @param ec Set to indicate what error occurred, if any.
2142    *
2143    * @returns On success, a socket object representing the newly accepted
2144    * connection. On error, a socket object where is_open() is false.
2145    *
2146    * @par Example
2147    * @code
2148    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2149    * ...
2150    * boost::asio::ip::tcp::endpoint endpoint;
2151    * boost::asio::ip::tcp::socket socket(
2152    *     acceptor.accept(my_context2, endpoint, ec));
2153    * if (ec)
2154    * {
2155    *   // An error occurred.
2156    * }
2157    * @endcode
2158    */
2159   template <typename Executor1>
2160   typename Protocol::socket::template rebind_executor<Executor1>::other
2161   accept(const executor_type& ex,
2162       endpoint_type& peer_endpoint, boost::system::error_code& ec,
2163       typename enable_if<
2164         is_executor<Executor1>::value
2165       >::type* = 0)
2166   {
2167     typename Protocol::socket::template
2168       rebind_executor<Executor1>::other peer(ex);
2169     impl_.get_service().accept(impl_.get_implementation(),
2170         peer, &peer_endpoint, ec);
2171     return peer;
2172   }
2173
2174   /// Accept a new connection.
2175   /**
2176    * This function is used to accept a new connection from a peer. The function
2177    * call will block until a new connection has been accepted successfully or
2178    * an error occurs.
2179    *
2180    * This overload requires that the Protocol template parameter satisfy the
2181    * AcceptableProtocol type requirements.
2182    *
2183    * @param context The I/O execution context object to be used for the newly
2184    * accepted socket.
2185    *
2186    * @param peer_endpoint An endpoint object into which the endpoint of the
2187    * remote peer will be written.
2188    *
2189    * @param ec Set to indicate what error occurred, if any.
2190    *
2191    * @returns On success, a socket object representing the newly accepted
2192    * connection. On error, a socket object where is_open() is false.
2193    *
2194    * @par Example
2195    * @code
2196    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2197    * ...
2198    * boost::asio::ip::tcp::endpoint endpoint;
2199    * boost::asio::ip::tcp::socket socket(
2200    *     acceptor.accept(my_context2, endpoint, ec));
2201    * if (ec)
2202    * {
2203    *   // An error occurred.
2204    * }
2205    * @endcode
2206    */
2207   template <typename ExecutionContext>
2208   typename Protocol::socket::template rebind_executor<
2209       typename ExecutionContext::executor_type>::other
2210   accept(ExecutionContext& context,
2211       endpoint_type& peer_endpoint, boost::system::error_code& ec,
2212       typename enable_if<
2213         is_convertible<ExecutionContext&, execution_context&>::value
2214       >::type* = 0)
2215   {
2216     typename Protocol::socket::template rebind_executor<
2217         typename ExecutionContext::executor_type>::other peer(context);
2218     impl_.get_service().accept(impl_.get_implementation(),
2219         peer, &peer_endpoint, ec);
2220     return peer;
2221   }
2222
2223   /// Start an asynchronous accept.
2224   /**
2225    * This function is used to asynchronously accept a new connection. The
2226    * function call always returns immediately.
2227    *
2228    * This overload requires that the Protocol template parameter satisfy the
2229    * AcceptableProtocol type requirements.
2230    *
2231    * @param ex The I/O executor object to be used for the newly accepted
2232    * socket.
2233    *
2234    * @param peer_endpoint An endpoint object into which the endpoint of the
2235    * remote peer will be written. Ownership of the peer_endpoint object is
2236    * retained by the caller, which must guarantee that it is valid until the
2237    * handler is called.
2238    *
2239    * @param handler The handler to be called when the accept operation
2240    * completes. Copies will be made of the handler as required. The function
2241    * signature of the handler must be:
2242    * @code void handler(
2243    *   const boost::system::error_code& error, // Result of operation.
2244    *   typename Protocol::socket::template rebind_executor<
2245    *     Executor1>::other peer // On success, the newly accepted socket.
2246    * ); @endcode
2247    * Regardless of whether the asynchronous operation completes immediately or
2248    * not, the handler will not be invoked from within this function. On
2249    * immediate completion, invocation of the handler will be performed in a
2250    * manner equivalent to using boost::asio::post().
2251    *
2252    * @par Example
2253    * @code
2254    * void accept_handler(const boost::system::error_code& error,
2255    *     boost::asio::ip::tcp::socket peer)
2256    * {
2257    *   if (!error)
2258    *   {
2259    *     // Accept succeeded.
2260    *   }
2261    * }
2262    *
2263    * ...
2264    *
2265    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2266    * ...
2267    * boost::asio::ip::tcp::endpoint endpoint;
2268    * acceptor.async_accept(my_context2, endpoint, accept_handler);
2269    * @endcode
2270    */
2271   template <typename Executor1,
2272       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2273         typename Protocol::socket::template rebind_executor<
2274           Executor1>::other)) MoveAcceptHandler
2275             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
2276   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2277       void (boost::system::error_code,
2278         typename Protocol::socket::template rebind_executor<
2279           Executor1>::other))
2280   async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
2281       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
2282         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2283       typename enable_if<
2284         is_executor<Executor1>::value
2285       >::type* = 0)
2286   {
2287     typedef typename Protocol::socket::template rebind_executor<
2288       Executor1>::other other_socket_type;
2289
2290     return async_initiate<MoveAcceptHandler,
2291       void (boost::system::error_code, other_socket_type)>(
2292         initiate_async_move_accept(this), handler,
2293         ex, &peer_endpoint,
2294         static_cast<other_socket_type*>(0));
2295   }
2296
2297   /// Start an asynchronous accept.
2298   /**
2299    * This function is used to asynchronously accept a new connection. The
2300    * function call always returns immediately.
2301    *
2302    * This overload requires that the Protocol template parameter satisfy the
2303    * AcceptableProtocol type requirements.
2304    *
2305    * @param context The I/O execution context object to be used for the newly
2306    * accepted socket.
2307    *
2308    * @param peer_endpoint An endpoint object into which the endpoint of the
2309    * remote peer will be written. Ownership of the peer_endpoint object is
2310    * retained by the caller, which must guarantee that it is valid until the
2311    * handler is called.
2312    *
2313    * @param handler The handler to be called when the accept operation
2314    * completes. Copies will be made of the handler as required. The function
2315    * signature of the handler must be:
2316    * @code void handler(
2317    *   const boost::system::error_code& error, // Result of operation.
2318    *   typename Protocol::socket::template rebind_executor<
2319    *     typename ExecutionContext::executor_type>::other peer
2320    *       // On success, the newly accepted socket.
2321    * ); @endcode
2322    * Regardless of whether the asynchronous operation completes immediately or
2323    * not, the handler will not be invoked from within this function. On
2324    * immediate completion, invocation of the handler will be performed in a
2325    * manner equivalent to using boost::asio::post().
2326    *
2327    * @par Example
2328    * @code
2329    * void accept_handler(const boost::system::error_code& error,
2330    *     boost::asio::ip::tcp::socket peer)
2331    * {
2332    *   if (!error)
2333    *   {
2334    *     // Accept succeeded.
2335    *   }
2336    * }
2337    *
2338    * ...
2339    *
2340    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2341    * ...
2342    * boost::asio::ip::tcp::endpoint endpoint;
2343    * acceptor.async_accept(my_context2, endpoint, accept_handler);
2344    * @endcode
2345    */
2346   template <typename ExecutionContext,
2347       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2348         typename Protocol::socket::template rebind_executor<
2349           typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
2350             BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
2351   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
2352       void (boost::system::error_code,
2353         typename Protocol::socket::template rebind_executor<
2354           typename ExecutionContext::executor_type>::other))
2355   async_accept(ExecutionContext& context,
2356       endpoint_type& peer_endpoint,
2357       BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
2358         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
2359       typename enable_if<
2360         is_convertible<ExecutionContext&, execution_context&>::value
2361       >::type* = 0)
2362   {
2363     typedef typename Protocol::socket::template rebind_executor<
2364       typename ExecutionContext::executor_type>::other other_socket_type;
2365
2366     return async_initiate<MoveAcceptHandler,
2367       void (boost::system::error_code, other_socket_type)>(
2368         initiate_async_move_accept(this), handler,
2369         context.get_executor(), &peer_endpoint,
2370         static_cast<other_socket_type*>(0));
2371   }
2372 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
2373
2374 private:
2375   // Disallow copying and assignment.
2376   basic_socket_acceptor(const basic_socket_acceptor&) BOOST_ASIO_DELETED;
2377   basic_socket_acceptor& operator=(
2378       const basic_socket_acceptor&) BOOST_ASIO_DELETED;
2379
2380   class initiate_async_wait
2381   {
2382   public:
2383     typedef Executor executor_type;
2384
2385     explicit initiate_async_wait(basic_socket_acceptor* self)
2386       : self_(self)
2387     {
2388     }
2389
2390     executor_type get_executor() const BOOST_ASIO_NOEXCEPT
2391     {
2392       return self_->get_executor();
2393     }
2394
2395     template <typename WaitHandler>
2396     void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
2397     {
2398       // If you get an error on the following line it means that your handler
2399       // does not meet the documented type requirements for a WaitHandler.
2400       BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
2401
2402       detail::non_const_lvalue<WaitHandler> handler2(handler);
2403       self_->impl_.get_service().async_wait(
2404           self_->impl_.get_implementation(), w, handler2.value,
2405           self_->impl_.get_implementation_executor());
2406     }
2407
2408   private:
2409     basic_socket_acceptor* self_;
2410   };
2411
2412   class initiate_async_accept
2413   {
2414   public:
2415     typedef Executor executor_type;
2416
2417     explicit initiate_async_accept(basic_socket_acceptor* self)
2418       : self_(self)
2419     {
2420     }
2421
2422     executor_type get_executor() const BOOST_ASIO_NOEXCEPT
2423     {
2424       return self_->get_executor();
2425     }
2426
2427     template <typename AcceptHandler, typename Protocol1, typename Executor1>
2428     void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
2429         basic_socket<Protocol1, Executor1>* peer,
2430         endpoint_type* peer_endpoint) const
2431     {
2432       // If you get an error on the following line it means that your handler
2433       // does not meet the documented type requirements for a AcceptHandler.
2434       BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
2435
2436       detail::non_const_lvalue<AcceptHandler> handler2(handler);
2437       self_->impl_.get_service().async_accept(
2438           self_->impl_.get_implementation(), *peer, peer_endpoint,
2439           handler2.value, self_->impl_.get_implementation_executor());
2440     }
2441
2442   private:
2443     basic_socket_acceptor* self_;
2444   };
2445
2446   class initiate_async_move_accept
2447   {
2448   public:
2449     typedef Executor executor_type;
2450
2451     explicit initiate_async_move_accept(basic_socket_acceptor* self)
2452       : self_(self)
2453     {
2454     }
2455
2456     executor_type get_executor() const BOOST_ASIO_NOEXCEPT
2457     {
2458       return self_->get_executor();
2459     }
2460
2461     template <typename MoveAcceptHandler, typename Executor1, typename Socket>
2462     void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
2463         const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const
2464     {
2465       // If you get an error on the following line it means that your handler
2466       // does not meet the documented type requirements for a MoveAcceptHandler.
2467       BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(
2468           MoveAcceptHandler, handler, Socket) type_check;
2469
2470       detail::non_const_lvalue<MoveAcceptHandler> handler2(handler);
2471       self_->impl_.get_service().async_move_accept(
2472           self_->impl_.get_implementation(), peer_ex, peer_endpoint,
2473           handler2.value, self_->impl_.get_implementation_executor());
2474     }
2475
2476   private:
2477     basic_socket_acceptor* self_;
2478   };
2479
2480 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
2481   detail::io_object_impl<
2482     detail::null_socket_service<Protocol>, Executor> impl_;
2483 #elif defined(BOOST_ASIO_HAS_IOCP)
2484   detail::io_object_impl<
2485     detail::win_iocp_socket_service<Protocol>, Executor> impl_;
2486 #else
2487   detail::io_object_impl<
2488     detail::reactive_socket_service<Protocol>, Executor> impl_;
2489 #endif
2490 };
2491
2492 } // namespace asio
2493 } // namespace boost
2494
2495 #include <boost/asio/detail/pop_options.hpp>
2496
2497 #endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP