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