Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:41

0001 //
0002 // basic_socket_acceptor.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
0012 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <utility>
0019 #include <boost/asio/detail/config.hpp>
0020 #include <boost/asio/any_io_executor.hpp>
0021 #include <boost/asio/basic_socket.hpp>
0022 #include <boost/asio/detail/handler_type_requirements.hpp>
0023 #include <boost/asio/detail/io_object_impl.hpp>
0024 #include <boost/asio/detail/non_const_lvalue.hpp>
0025 #include <boost/asio/detail/throw_error.hpp>
0026 #include <boost/asio/detail/type_traits.hpp>
0027 #include <boost/asio/error.hpp>
0028 #include <boost/asio/execution_context.hpp>
0029 #include <boost/asio/socket_base.hpp>
0030 
0031 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
0032 # include <boost/asio/detail/null_socket_service.hpp>
0033 #elif defined(BOOST_ASIO_HAS_IOCP)
0034 # include <boost/asio/detail/win_iocp_socket_service.hpp>
0035 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0036 # include <boost/asio/detail/io_uring_socket_service.hpp>
0037 #else
0038 # include <boost/asio/detail/reactive_socket_service.hpp>
0039 #endif
0040 
0041 #include <boost/asio/detail/push_options.hpp>
0042 
0043 namespace boost {
0044 namespace asio {
0045 
0046 #if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
0047 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL
0048 
0049 // Forward declaration with defaulted arguments.
0050 template <typename Protocol, typename Executor = any_io_executor>
0051 class basic_socket_acceptor;
0052 
0053 #endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
0054 
0055 /// Provides the ability to accept new connections.
0056 /**
0057  * The basic_socket_acceptor class template is used for accepting new socket
0058  * connections.
0059  *
0060  * @par Thread Safety
0061  * @e Distinct @e objects: Safe.@n
0062  * @e Shared @e objects: Unsafe.
0063  *
0064  * Synchronous @c accept operations are thread safe, if the underlying
0065  * operating system calls are also thread safe. This means that it is permitted
0066  * to perform concurrent calls to synchronous @c accept operations on a single
0067  * socket object. Other synchronous operations, such as @c open or @c close, are
0068  * not thread safe.
0069  *
0070  * @par Example
0071  * Opening a socket acceptor with the SO_REUSEADDR option enabled:
0072  * @code
0073  * boost::asio::ip::tcp::acceptor acceptor(my_context);
0074  * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
0075  * acceptor.open(endpoint.protocol());
0076  * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
0077  * acceptor.bind(endpoint);
0078  * acceptor.listen();
0079  * @endcode
0080  */
0081 template <typename Protocol, typename Executor>
0082 class basic_socket_acceptor
0083   : public socket_base
0084 {
0085 private:
0086   class initiate_async_wait;
0087   class initiate_async_accept;
0088   class initiate_async_move_accept;
0089 
0090 public:
0091   /// The type of the executor associated with the object.
0092   typedef Executor executor_type;
0093 
0094   /// Rebinds the acceptor type to another executor.
0095   template <typename Executor1>
0096   struct rebind_executor
0097   {
0098     /// The socket type when rebound to the specified executor.
0099     typedef basic_socket_acceptor<Protocol, Executor1> other;
0100   };
0101 
0102   /// The native representation of an acceptor.
0103 #if defined(GENERATING_DOCUMENTATION)
0104   typedef implementation_defined native_handle_type;
0105 #elif defined(BOOST_ASIO_WINDOWS_RUNTIME)
0106   typedef typename detail::null_socket_service<
0107     Protocol>::native_handle_type native_handle_type;
0108 #elif defined(BOOST_ASIO_HAS_IOCP)
0109   typedef typename detail::win_iocp_socket_service<
0110     Protocol>::native_handle_type native_handle_type;
0111 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0112   typedef typename detail::io_uring_socket_service<
0113     Protocol>::native_handle_type native_handle_type;
0114 #else
0115   typedef typename detail::reactive_socket_service<
0116     Protocol>::native_handle_type native_handle_type;
0117 #endif
0118 
0119   /// The protocol type.
0120   typedef Protocol protocol_type;
0121 
0122   /// The endpoint type.
0123   typedef typename Protocol::endpoint endpoint_type;
0124 
0125   /// Construct an acceptor without opening it.
0126   /**
0127    * This constructor creates an acceptor without opening it to listen for new
0128    * connections. The open() function must be called before the acceptor can
0129    * accept new socket connections.
0130    *
0131    * @param ex The I/O executor that the acceptor will use, by default, to
0132    * dispatch handlers for any asynchronous operations performed on the
0133    * acceptor.
0134    */
0135   explicit basic_socket_acceptor(const executor_type& ex)
0136     : impl_(0, ex)
0137   {
0138   }
0139 
0140   /// Construct an acceptor without opening it.
0141   /**
0142    * This constructor creates an acceptor without opening it to listen for new
0143    * connections. The open() function must be called before the acceptor can
0144    * accept new socket connections.
0145    *
0146    * @param context An execution context which provides the I/O executor that
0147    * the acceptor will use, by default, to dispatch handlers for any
0148    * asynchronous operations performed on the acceptor.
0149    */
0150   template <typename ExecutionContext>
0151   explicit basic_socket_acceptor(ExecutionContext& context,
0152       constraint_t<
0153         is_convertible<ExecutionContext&, execution_context&>::value
0154       > = 0)
0155     : impl_(0, 0, context)
0156   {
0157   }
0158 
0159   /// Construct an open acceptor.
0160   /**
0161    * This constructor creates an acceptor and automatically opens it.
0162    *
0163    * @param ex The I/O executor that the acceptor will use, by default, to
0164    * dispatch handlers for any asynchronous operations performed on the
0165    * acceptor.
0166    *
0167    * @param protocol An object specifying protocol parameters to be used.
0168    *
0169    * @throws boost::system::system_error Thrown on failure.
0170    */
0171   basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol)
0172     : impl_(0, ex)
0173   {
0174     boost::system::error_code ec;
0175     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
0176     boost::asio::detail::throw_error(ec, "open");
0177   }
0178 
0179   /// Construct an open acceptor.
0180   /**
0181    * This constructor creates an acceptor and automatically opens it.
0182    *
0183    * @param context An execution context which provides the I/O executor that
0184    * the acceptor will use, by default, to dispatch handlers for any
0185    * asynchronous operations performed on the acceptor.
0186    *
0187    * @param protocol An object specifying protocol parameters to be used.
0188    *
0189    * @throws boost::system::system_error Thrown on failure.
0190    */
0191   template <typename ExecutionContext>
0192   basic_socket_acceptor(ExecutionContext& context,
0193       const protocol_type& protocol,
0194       constraint_t<
0195         is_convertible<ExecutionContext&, execution_context&>::value,
0196         defaulted_constraint
0197       > = defaulted_constraint())
0198     : impl_(0, 0, context)
0199   {
0200     boost::system::error_code ec;
0201     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
0202     boost::asio::detail::throw_error(ec, "open");
0203   }
0204 
0205   /// Construct an acceptor opened on the given endpoint.
0206   /**
0207    * This constructor creates an acceptor and automatically opens it to listen
0208    * for new connections on the specified endpoint.
0209    *
0210    * @param ex The I/O executor that the acceptor will use, by default, to
0211    * dispatch handlers for any asynchronous operations performed on the
0212    * acceptor.
0213    *
0214    * @param endpoint An endpoint on the local machine on which the acceptor
0215    * will listen for new connections.
0216    *
0217    * @param reuse_addr Whether the constructor should set the socket option
0218    * socket_base::reuse_address.
0219    *
0220    * @throws boost::system::system_error Thrown on failure.
0221    *
0222    * @note This constructor is equivalent to the following code:
0223    * @code
0224    * basic_socket_acceptor<Protocol> acceptor(my_context);
0225    * acceptor.open(endpoint.protocol());
0226    * if (reuse_addr)
0227    *   acceptor.set_option(socket_base::reuse_address(true));
0228    * acceptor.bind(endpoint);
0229    * acceptor.listen();
0230    * @endcode
0231    */
0232   basic_socket_acceptor(const executor_type& ex,
0233       const endpoint_type& endpoint, bool reuse_addr = true)
0234     : impl_(0, ex)
0235   {
0236     boost::system::error_code ec;
0237     const protocol_type protocol = endpoint.protocol();
0238     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
0239     boost::asio::detail::throw_error(ec, "open");
0240     if (reuse_addr)
0241     {
0242       impl_.get_service().set_option(impl_.get_implementation(),
0243           socket_base::reuse_address(true), ec);
0244       boost::asio::detail::throw_error(ec, "set_option");
0245     }
0246     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
0247     boost::asio::detail::throw_error(ec, "bind");
0248     impl_.get_service().listen(impl_.get_implementation(),
0249         socket_base::max_listen_connections, ec);
0250     boost::asio::detail::throw_error(ec, "listen");
0251   }
0252 
0253   /// Construct an acceptor opened on the given endpoint.
0254   /**
0255    * This constructor creates an acceptor and automatically opens it to listen
0256    * for new connections on the specified endpoint.
0257    *
0258    * @param context An execution context which provides the I/O executor that
0259    * the acceptor will use, by default, to dispatch handlers for any
0260    * asynchronous operations performed on the acceptor.
0261    *
0262    * @param endpoint An endpoint on the local machine on which the acceptor
0263    * will listen for new connections.
0264    *
0265    * @param reuse_addr Whether the constructor should set the socket option
0266    * socket_base::reuse_address.
0267    *
0268    * @throws boost::system::system_error Thrown on failure.
0269    *
0270    * @note This constructor is equivalent to the following code:
0271    * @code
0272    * basic_socket_acceptor<Protocol> acceptor(my_context);
0273    * acceptor.open(endpoint.protocol());
0274    * if (reuse_addr)
0275    *   acceptor.set_option(socket_base::reuse_address(true));
0276    * acceptor.bind(endpoint);
0277    * acceptor.listen();
0278    * @endcode
0279    */
0280   template <typename ExecutionContext>
0281   basic_socket_acceptor(ExecutionContext& context,
0282       const endpoint_type& endpoint, bool reuse_addr = true,
0283       constraint_t<
0284         is_convertible<ExecutionContext&, execution_context&>::value
0285       > = 0)
0286     : impl_(0, 0, context)
0287   {
0288     boost::system::error_code ec;
0289     const protocol_type protocol = endpoint.protocol();
0290     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
0291     boost::asio::detail::throw_error(ec, "open");
0292     if (reuse_addr)
0293     {
0294       impl_.get_service().set_option(impl_.get_implementation(),
0295           socket_base::reuse_address(true), ec);
0296       boost::asio::detail::throw_error(ec, "set_option");
0297     }
0298     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
0299     boost::asio::detail::throw_error(ec, "bind");
0300     impl_.get_service().listen(impl_.get_implementation(),
0301         socket_base::max_listen_connections, ec);
0302     boost::asio::detail::throw_error(ec, "listen");
0303   }
0304 
0305   /// Construct a basic_socket_acceptor on an existing native acceptor.
0306   /**
0307    * This constructor creates an acceptor object to hold an existing native
0308    * acceptor.
0309    *
0310    * @param ex The I/O executor that the acceptor will use, by default, to
0311    * dispatch handlers for any asynchronous operations performed on the
0312    * acceptor.
0313    *
0314    * @param protocol An object specifying protocol parameters to be used.
0315    *
0316    * @param native_acceptor A native acceptor.
0317    *
0318    * @throws boost::system::system_error Thrown on failure.
0319    */
0320   basic_socket_acceptor(const executor_type& ex,
0321       const protocol_type& protocol, const native_handle_type& native_acceptor)
0322     : impl_(0, ex)
0323   {
0324     boost::system::error_code ec;
0325     impl_.get_service().assign(impl_.get_implementation(),
0326         protocol, native_acceptor, ec);
0327     boost::asio::detail::throw_error(ec, "assign");
0328   }
0329 
0330   /// Construct a basic_socket_acceptor on an existing native acceptor.
0331   /**
0332    * This constructor creates an acceptor object to hold an existing native
0333    * acceptor.
0334    *
0335    * @param context An execution context which provides the I/O executor that
0336    * the acceptor will use, by default, to dispatch handlers for any
0337    * asynchronous operations performed on the acceptor.
0338    *
0339    * @param protocol An object specifying protocol parameters to be used.
0340    *
0341    * @param native_acceptor A native acceptor.
0342    *
0343    * @throws boost::system::system_error Thrown on failure.
0344    */
0345   template <typename ExecutionContext>
0346   basic_socket_acceptor(ExecutionContext& context,
0347       const protocol_type& protocol, const native_handle_type& native_acceptor,
0348       constraint_t<
0349         is_convertible<ExecutionContext&, execution_context&>::value
0350       > = 0)
0351     : impl_(0, 0, context)
0352   {
0353     boost::system::error_code ec;
0354     impl_.get_service().assign(impl_.get_implementation(),
0355         protocol, native_acceptor, ec);
0356     boost::asio::detail::throw_error(ec, "assign");
0357   }
0358 
0359   /// Move-construct a basic_socket_acceptor from another.
0360   /**
0361    * This constructor moves an acceptor from one object to another.
0362    *
0363    * @param other The other basic_socket_acceptor object from which the move
0364    * will occur.
0365    *
0366    * @note Following the move, the moved-from object is in the same state as if
0367    * constructed using the @c basic_socket_acceptor(const executor_type&)
0368    * constructor.
0369    */
0370   basic_socket_acceptor(basic_socket_acceptor&& other) noexcept
0371     : impl_(std::move(other.impl_))
0372   {
0373   }
0374 
0375   /// Move-assign a basic_socket_acceptor from another.
0376   /**
0377    * This assignment operator moves an acceptor from one object to another.
0378    *
0379    * @param other The other basic_socket_acceptor object from which the move
0380    * will occur.
0381    *
0382    * @note Following the move, the moved-from object is in the same state as if
0383    * constructed using the @c basic_socket_acceptor(const executor_type&)
0384    * constructor.
0385    */
0386   basic_socket_acceptor& operator=(basic_socket_acceptor&& other)
0387   {
0388     impl_ = std::move(other.impl_);
0389     return *this;
0390   }
0391 
0392   // All socket acceptors have access to each other's implementations.
0393   template <typename Protocol1, typename Executor1>
0394   friend class basic_socket_acceptor;
0395 
0396   /// Move-construct a basic_socket_acceptor from an acceptor of another
0397   /// protocol type.
0398   /**
0399    * This constructor moves an acceptor from one object to another.
0400    *
0401    * @param other The other basic_socket_acceptor object from which the move
0402    * will occur.
0403    *
0404    * @note Following the move, the moved-from object is in the same state as if
0405    * constructed using the @c basic_socket_acceptor(const executor_type&)
0406    * constructor.
0407    */
0408   template <typename Protocol1, typename Executor1>
0409   basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other,
0410       constraint_t<
0411         is_convertible<Protocol1, Protocol>::value
0412           && is_convertible<Executor1, Executor>::value
0413       > = 0)
0414     : impl_(std::move(other.impl_))
0415   {
0416   }
0417 
0418   /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
0419   /// type.
0420   /**
0421    * This assignment operator moves an acceptor from one object to another.
0422    *
0423    * @param other The other basic_socket_acceptor object from which the move
0424    * will occur.
0425    *
0426    * @note Following the move, the moved-from object is in the same state as if
0427    * constructed using the @c basic_socket_acceptor(const executor_type&)
0428    * constructor.
0429    */
0430   template <typename Protocol1, typename Executor1>
0431   constraint_t<
0432     is_convertible<Protocol1, Protocol>::value
0433       && is_convertible<Executor1, Executor>::value,
0434     basic_socket_acceptor&
0435   > operator=(basic_socket_acceptor<Protocol1, Executor1>&& other)
0436   {
0437     basic_socket_acceptor tmp(std::move(other));
0438     impl_ = std::move(tmp.impl_);
0439     return *this;
0440   }
0441 
0442   /// Destroys the acceptor.
0443   /**
0444    * This function destroys the acceptor, cancelling any outstanding
0445    * asynchronous operations associated with the acceptor as if by calling
0446    * @c cancel.
0447    */
0448   ~basic_socket_acceptor()
0449   {
0450   }
0451 
0452   /// Get the executor associated with the object.
0453   const executor_type& get_executor() noexcept
0454   {
0455     return impl_.get_executor();
0456   }
0457 
0458   /// Open the acceptor using the specified protocol.
0459   /**
0460    * This function opens the socket acceptor so that it will use the specified
0461    * protocol.
0462    *
0463    * @param protocol An object specifying which protocol is to be used.
0464    *
0465    * @throws boost::system::system_error Thrown on failure.
0466    *
0467    * @par Example
0468    * @code
0469    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0470    * acceptor.open(boost::asio::ip::tcp::v4());
0471    * @endcode
0472    */
0473   void open(const protocol_type& protocol = protocol_type())
0474   {
0475     boost::system::error_code ec;
0476     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
0477     boost::asio::detail::throw_error(ec, "open");
0478   }
0479 
0480   /// Open the acceptor using the specified protocol.
0481   /**
0482    * This function opens the socket acceptor so that it will use the specified
0483    * protocol.
0484    *
0485    * @param protocol An object specifying which protocol is to be used.
0486    *
0487    * @param ec Set to indicate what error occurred, if any.
0488    *
0489    * @par Example
0490    * @code
0491    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0492    * boost::system::error_code ec;
0493    * acceptor.open(boost::asio::ip::tcp::v4(), ec);
0494    * if (ec)
0495    * {
0496    *   // An error occurred.
0497    * }
0498    * @endcode
0499    */
0500   BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
0501       boost::system::error_code& ec)
0502   {
0503     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
0504     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0505   }
0506 
0507   /// Assigns an existing native acceptor to the acceptor.
0508   /*
0509    * This function opens the acceptor to hold an existing native acceptor.
0510    *
0511    * @param protocol An object specifying which protocol is to be used.
0512    *
0513    * @param native_acceptor A native acceptor.
0514    *
0515    * @throws boost::system::system_error Thrown on failure.
0516    */
0517   void assign(const protocol_type& protocol,
0518       const native_handle_type& native_acceptor)
0519   {
0520     boost::system::error_code ec;
0521     impl_.get_service().assign(impl_.get_implementation(),
0522         protocol, native_acceptor, ec);
0523     boost::asio::detail::throw_error(ec, "assign");
0524   }
0525 
0526   /// Assigns an existing native acceptor to the acceptor.
0527   /*
0528    * This function opens the acceptor to hold an existing native acceptor.
0529    *
0530    * @param protocol An object specifying which protocol is to be used.
0531    *
0532    * @param native_acceptor A native acceptor.
0533    *
0534    * @param ec Set to indicate what error occurred, if any.
0535    */
0536   BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
0537       const native_handle_type& native_acceptor, boost::system::error_code& ec)
0538   {
0539     impl_.get_service().assign(impl_.get_implementation(),
0540         protocol, native_acceptor, ec);
0541     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0542   }
0543 
0544   /// Determine whether the acceptor is open.
0545   bool is_open() const
0546   {
0547     return impl_.get_service().is_open(impl_.get_implementation());
0548   }
0549 
0550   /// Bind the acceptor to the given local endpoint.
0551   /**
0552    * This function binds the socket acceptor to the specified endpoint on the
0553    * local machine.
0554    *
0555    * @param endpoint An endpoint on the local machine to which the socket
0556    * acceptor will be bound.
0557    *
0558    * @throws boost::system::system_error Thrown on failure.
0559    *
0560    * @par Example
0561    * @code
0562    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0563    * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
0564    * acceptor.open(endpoint.protocol());
0565    * acceptor.bind(endpoint);
0566    * @endcode
0567    */
0568   void bind(const endpoint_type& endpoint)
0569   {
0570     boost::system::error_code ec;
0571     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
0572     boost::asio::detail::throw_error(ec, "bind");
0573   }
0574 
0575   /// Bind the acceptor to the given local endpoint.
0576   /**
0577    * This function binds the socket acceptor to the specified endpoint on the
0578    * local machine.
0579    *
0580    * @param endpoint An endpoint on the local machine to which the socket
0581    * acceptor will be bound.
0582    *
0583    * @param ec Set to indicate what error occurred, if any.
0584    *
0585    * @par Example
0586    * @code
0587    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0588    * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
0589    * acceptor.open(endpoint.protocol());
0590    * boost::system::error_code ec;
0591    * acceptor.bind(endpoint, ec);
0592    * if (ec)
0593    * {
0594    *   // An error occurred.
0595    * }
0596    * @endcode
0597    */
0598   BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
0599       boost::system::error_code& ec)
0600   {
0601     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
0602     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0603   }
0604 
0605   /// Place the acceptor into the state where it will listen for new
0606   /// connections.
0607   /**
0608    * This function puts the socket acceptor into the state where it may accept
0609    * new connections.
0610    *
0611    * @param backlog The maximum length of the queue of pending connections.
0612    *
0613    * @throws boost::system::system_error Thrown on failure.
0614    */
0615   void listen(int backlog = socket_base::max_listen_connections)
0616   {
0617     boost::system::error_code ec;
0618     impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
0619     boost::asio::detail::throw_error(ec, "listen");
0620   }
0621 
0622   /// Place the acceptor into the state where it will listen for new
0623   /// connections.
0624   /**
0625    * This function puts the socket acceptor into the state where it may accept
0626    * new connections.
0627    *
0628    * @param backlog The maximum length of the queue of pending connections.
0629    *
0630    * @param ec Set to indicate what error occurred, if any.
0631    *
0632    * @par Example
0633    * @code
0634    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0635    * ...
0636    * boost::system::error_code ec;
0637    * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec);
0638    * if (ec)
0639    * {
0640    *   // An error occurred.
0641    * }
0642    * @endcode
0643    */
0644   BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec)
0645   {
0646     impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
0647     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0648   }
0649 
0650   /// Close the acceptor.
0651   /**
0652    * This function is used to close the acceptor. Any asynchronous accept
0653    * operations will be cancelled immediately.
0654    *
0655    * A subsequent call to open() is required before the acceptor can again be
0656    * used to again perform socket accept operations.
0657    *
0658    * @throws boost::system::system_error Thrown on failure.
0659    */
0660   void close()
0661   {
0662     boost::system::error_code ec;
0663     impl_.get_service().close(impl_.get_implementation(), ec);
0664     boost::asio::detail::throw_error(ec, "close");
0665   }
0666 
0667   /// Close the acceptor.
0668   /**
0669    * This function is used to close the acceptor. Any asynchronous accept
0670    * operations will be cancelled immediately.
0671    *
0672    * A subsequent call to open() is required before the acceptor can again be
0673    * used to again perform socket accept operations.
0674    *
0675    * @param ec Set to indicate what error occurred, if any.
0676    *
0677    * @par Example
0678    * @code
0679    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0680    * ...
0681    * boost::system::error_code ec;
0682    * acceptor.close(ec);
0683    * if (ec)
0684    * {
0685    *   // An error occurred.
0686    * }
0687    * @endcode
0688    */
0689   BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
0690   {
0691     impl_.get_service().close(impl_.get_implementation(), ec);
0692     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0693   }
0694 
0695   /// Release ownership of the underlying native acceptor.
0696   /**
0697    * This function causes all outstanding asynchronous accept operations to
0698    * finish immediately, and the handlers for cancelled operations will be
0699    * passed the boost::asio::error::operation_aborted error. Ownership of the
0700    * native acceptor is then transferred to the caller.
0701    *
0702    * @throws boost::system::system_error Thrown on failure.
0703    *
0704    * @note This function is unsupported on Windows versions prior to Windows
0705    * 8.1, and will fail with boost::asio::error::operation_not_supported on
0706    * these platforms.
0707    */
0708 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0709   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
0710   __declspec(deprecated("This function always fails with "
0711         "operation_not_supported when used on Windows versions "
0712         "prior to Windows 8.1."))
0713 #endif
0714   native_handle_type release()
0715   {
0716     boost::system::error_code ec;
0717     native_handle_type s = impl_.get_service().release(
0718         impl_.get_implementation(), ec);
0719     boost::asio::detail::throw_error(ec, "release");
0720     return s;
0721   }
0722 
0723   /// Release ownership of the underlying native acceptor.
0724   /**
0725    * This function causes all outstanding asynchronous accept operations to
0726    * finish immediately, and the handlers for cancelled operations will be
0727    * passed the boost::asio::error::operation_aborted error. Ownership of the
0728    * native acceptor is then transferred to the caller.
0729    *
0730    * @param ec Set to indicate what error occurred, if any.
0731    *
0732    * @note This function is unsupported on Windows versions prior to Windows
0733    * 8.1, and will fail with boost::asio::error::operation_not_supported on
0734    * these platforms.
0735    */
0736 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
0737   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
0738   __declspec(deprecated("This function always fails with "
0739         "operation_not_supported when used on Windows versions "
0740         "prior to Windows 8.1."))
0741 #endif
0742   native_handle_type release(boost::system::error_code& ec)
0743   {
0744     return impl_.get_service().release(impl_.get_implementation(), ec);
0745   }
0746 
0747   /// Get the native acceptor representation.
0748   /**
0749    * This function may be used to obtain the underlying representation of the
0750    * acceptor. This is intended to allow access to native acceptor functionality
0751    * that is not otherwise provided.
0752    */
0753   native_handle_type native_handle()
0754   {
0755     return impl_.get_service().native_handle(impl_.get_implementation());
0756   }
0757 
0758   /// Cancel all asynchronous operations associated with the acceptor.
0759   /**
0760    * This function causes all outstanding asynchronous connect, send and receive
0761    * operations to finish immediately, and the handlers for cancelled operations
0762    * will be passed the boost::asio::error::operation_aborted error.
0763    *
0764    * @throws boost::system::system_error Thrown on failure.
0765    */
0766   void cancel()
0767   {
0768     boost::system::error_code ec;
0769     impl_.get_service().cancel(impl_.get_implementation(), ec);
0770     boost::asio::detail::throw_error(ec, "cancel");
0771   }
0772 
0773   /// Cancel all asynchronous operations associated with the acceptor.
0774   /**
0775    * This function causes all outstanding asynchronous connect, send and receive
0776    * operations to finish immediately, and the handlers for cancelled operations
0777    * will be passed the boost::asio::error::operation_aborted error.
0778    *
0779    * @param ec Set to indicate what error occurred, if any.
0780    */
0781   BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
0782   {
0783     impl_.get_service().cancel(impl_.get_implementation(), ec);
0784     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0785   }
0786 
0787   /// Set an option on the acceptor.
0788   /**
0789    * This function is used to set an option on the acceptor.
0790    *
0791    * @param option The new option value to be set on the acceptor.
0792    *
0793    * @throws boost::system::system_error Thrown on failure.
0794    *
0795    * @sa SettableSocketOption @n
0796    * boost::asio::socket_base::reuse_address
0797    * boost::asio::socket_base::enable_connection_aborted
0798    *
0799    * @par Example
0800    * Setting the SOL_SOCKET/SO_REUSEADDR option:
0801    * @code
0802    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0803    * ...
0804    * boost::asio::ip::tcp::acceptor::reuse_address option(true);
0805    * acceptor.set_option(option);
0806    * @endcode
0807    */
0808   template <typename SettableSocketOption>
0809   void set_option(const SettableSocketOption& option)
0810   {
0811     boost::system::error_code ec;
0812     impl_.get_service().set_option(impl_.get_implementation(), option, ec);
0813     boost::asio::detail::throw_error(ec, "set_option");
0814   }
0815 
0816   /// Set an option on the acceptor.
0817   /**
0818    * This function is used to set an option on the acceptor.
0819    *
0820    * @param option The new option value to be set on the acceptor.
0821    *
0822    * @param ec Set to indicate what error occurred, if any.
0823    *
0824    * @sa SettableSocketOption @n
0825    * boost::asio::socket_base::reuse_address
0826    * boost::asio::socket_base::enable_connection_aborted
0827    *
0828    * @par Example
0829    * Setting the SOL_SOCKET/SO_REUSEADDR option:
0830    * @code
0831    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0832    * ...
0833    * boost::asio::ip::tcp::acceptor::reuse_address option(true);
0834    * boost::system::error_code ec;
0835    * acceptor.set_option(option, ec);
0836    * if (ec)
0837    * {
0838    *   // An error occurred.
0839    * }
0840    * @endcode
0841    */
0842   template <typename SettableSocketOption>
0843   BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
0844       boost::system::error_code& ec)
0845   {
0846     impl_.get_service().set_option(impl_.get_implementation(), option, ec);
0847     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0848   }
0849 
0850   /// Get an option from the acceptor.
0851   /**
0852    * This function is used to get the current value of an option on the
0853    * acceptor.
0854    *
0855    * @param option The option value to be obtained from the acceptor.
0856    *
0857    * @throws boost::system::system_error Thrown on failure.
0858    *
0859    * @sa GettableSocketOption @n
0860    * boost::asio::socket_base::reuse_address
0861    *
0862    * @par Example
0863    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
0864    * @code
0865    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0866    * ...
0867    * boost::asio::ip::tcp::acceptor::reuse_address option;
0868    * acceptor.get_option(option);
0869    * bool is_set = option.get();
0870    * @endcode
0871    */
0872   template <typename GettableSocketOption>
0873   void get_option(GettableSocketOption& option) const
0874   {
0875     boost::system::error_code ec;
0876     impl_.get_service().get_option(impl_.get_implementation(), option, ec);
0877     boost::asio::detail::throw_error(ec, "get_option");
0878   }
0879 
0880   /// Get an option from the acceptor.
0881   /**
0882    * This function is used to get the current value of an option on the
0883    * acceptor.
0884    *
0885    * @param option The option value to be obtained from the acceptor.
0886    *
0887    * @param ec Set to indicate what error occurred, if any.
0888    *
0889    * @sa GettableSocketOption @n
0890    * boost::asio::socket_base::reuse_address
0891    *
0892    * @par Example
0893    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
0894    * @code
0895    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0896    * ...
0897    * boost::asio::ip::tcp::acceptor::reuse_address option;
0898    * boost::system::error_code ec;
0899    * acceptor.get_option(option, ec);
0900    * if (ec)
0901    * {
0902    *   // An error occurred.
0903    * }
0904    * bool is_set = option.get();
0905    * @endcode
0906    */
0907   template <typename GettableSocketOption>
0908   BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
0909       boost::system::error_code& ec) const
0910   {
0911     impl_.get_service().get_option(impl_.get_implementation(), option, ec);
0912     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0913   }
0914 
0915   /// Perform an IO control command on the acceptor.
0916   /**
0917    * This function is used to execute an IO control command on the acceptor.
0918    *
0919    * @param command The IO control command to be performed on the acceptor.
0920    *
0921    * @throws boost::system::system_error Thrown on failure.
0922    *
0923    * @sa IoControlCommand @n
0924    * boost::asio::socket_base::non_blocking_io
0925    *
0926    * @par Example
0927    * Getting the number of bytes ready to read:
0928    * @code
0929    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0930    * ...
0931    * boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
0932    * socket.io_control(command);
0933    * @endcode
0934    */
0935   template <typename IoControlCommand>
0936   void io_control(IoControlCommand& command)
0937   {
0938     boost::system::error_code ec;
0939     impl_.get_service().io_control(impl_.get_implementation(), command, ec);
0940     boost::asio::detail::throw_error(ec, "io_control");
0941   }
0942 
0943   /// Perform an IO control command on the acceptor.
0944   /**
0945    * This function is used to execute an IO control command on the acceptor.
0946    *
0947    * @param command The IO control command to be performed on the acceptor.
0948    *
0949    * @param ec Set to indicate what error occurred, if any.
0950    *
0951    * @sa IoControlCommand @n
0952    * boost::asio::socket_base::non_blocking_io
0953    *
0954    * @par Example
0955    * Getting the number of bytes ready to read:
0956    * @code
0957    * boost::asio::ip::tcp::acceptor acceptor(my_context);
0958    * ...
0959    * boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
0960    * boost::system::error_code ec;
0961    * socket.io_control(command, ec);
0962    * if (ec)
0963    * {
0964    *   // An error occurred.
0965    * }
0966    * @endcode
0967    */
0968   template <typename IoControlCommand>
0969   BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
0970       boost::system::error_code& ec)
0971   {
0972     impl_.get_service().io_control(impl_.get_implementation(), command, ec);
0973     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0974   }
0975 
0976   /// Gets the non-blocking mode of the acceptor.
0977   /**
0978    * @returns @c true if the acceptor's synchronous operations will fail with
0979    * boost::asio::error::would_block if they are unable to perform the requested
0980    * operation immediately. If @c false, synchronous operations will block
0981    * until complete.
0982    *
0983    * @note The non-blocking mode has no effect on the behaviour of asynchronous
0984    * operations. Asynchronous operations will never fail with the error
0985    * boost::asio::error::would_block.
0986    */
0987   bool non_blocking() const
0988   {
0989     return impl_.get_service().non_blocking(impl_.get_implementation());
0990   }
0991 
0992   /// Sets the non-blocking mode of the acceptor.
0993   /**
0994    * @param mode If @c true, the acceptor's synchronous operations will fail
0995    * with boost::asio::error::would_block if they are unable to perform the
0996    * requested operation immediately. If @c false, synchronous operations will
0997    * block until complete.
0998    *
0999    * @throws boost::system::system_error Thrown on failure.
1000    *
1001    * @note The non-blocking mode has no effect on the behaviour of asynchronous
1002    * operations. Asynchronous operations will never fail with the error
1003    * boost::asio::error::would_block.
1004    */
1005   void non_blocking(bool mode)
1006   {
1007     boost::system::error_code ec;
1008     impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
1009     boost::asio::detail::throw_error(ec, "non_blocking");
1010   }
1011 
1012   /// Sets the non-blocking mode of the acceptor.
1013   /**
1014    * @param mode If @c true, the acceptor's synchronous operations will fail
1015    * with boost::asio::error::would_block if they are unable to perform the
1016    * requested operation immediately. If @c false, synchronous operations will
1017    * block until complete.
1018    *
1019    * @param ec Set to indicate what error occurred, if any.
1020    *
1021    * @note The non-blocking mode has no effect on the behaviour of asynchronous
1022    * operations. Asynchronous operations will never fail with the error
1023    * boost::asio::error::would_block.
1024    */
1025   BOOST_ASIO_SYNC_OP_VOID non_blocking(
1026       bool mode, boost::system::error_code& ec)
1027   {
1028     impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
1029     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1030   }
1031 
1032   /// Gets the non-blocking mode of the native acceptor implementation.
1033   /**
1034    * This function is used to retrieve the non-blocking mode of the underlying
1035    * native acceptor. This mode has no effect on the behaviour of the acceptor
1036    * object's synchronous operations.
1037    *
1038    * @returns @c true if the underlying acceptor is in non-blocking mode and
1039    * direct system calls may fail with boost::asio::error::would_block (or the
1040    * equivalent system error).
1041    *
1042    * @note The current non-blocking mode is cached by the acceptor object.
1043    * Consequently, the return value may be incorrect if the non-blocking mode
1044    * was set directly on the native acceptor.
1045    */
1046   bool native_non_blocking() const
1047   {
1048     return impl_.get_service().native_non_blocking(impl_.get_implementation());
1049   }
1050 
1051   /// Sets the non-blocking mode of the native acceptor implementation.
1052   /**
1053    * This function is used to modify the non-blocking mode of the underlying
1054    * native acceptor. It has no effect on the behaviour of the acceptor object's
1055    * synchronous operations.
1056    *
1057    * @param mode If @c true, the underlying acceptor is put into non-blocking
1058    * mode and direct system calls may fail with boost::asio::error::would_block
1059    * (or the equivalent system error).
1060    *
1061    * @throws boost::system::system_error Thrown on failure. If the @c mode is
1062    * @c false, but the current value of @c non_blocking() is @c true, this
1063    * function fails with boost::asio::error::invalid_argument, as the
1064    * combination does not make sense.
1065    */
1066   void native_non_blocking(bool mode)
1067   {
1068     boost::system::error_code ec;
1069     impl_.get_service().native_non_blocking(
1070         impl_.get_implementation(), mode, ec);
1071     boost::asio::detail::throw_error(ec, "native_non_blocking");
1072   }
1073 
1074   /// Sets the non-blocking mode of the native acceptor implementation.
1075   /**
1076    * This function is used to modify the non-blocking mode of the underlying
1077    * native acceptor. It has no effect on the behaviour of the acceptor object's
1078    * synchronous operations.
1079    *
1080    * @param mode If @c true, the underlying acceptor is put into non-blocking
1081    * mode and direct system calls may fail with boost::asio::error::would_block
1082    * (or the equivalent system error).
1083    *
1084    * @param ec Set to indicate what error occurred, if any. If the @c mode is
1085    * @c false, but the current value of @c non_blocking() is @c true, this
1086    * function fails with boost::asio::error::invalid_argument, as the
1087    * combination does not make sense.
1088    */
1089   BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
1090       bool mode, boost::system::error_code& ec)
1091   {
1092     impl_.get_service().native_non_blocking(
1093         impl_.get_implementation(), mode, ec);
1094     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1095   }
1096 
1097   /// Get the local endpoint of the acceptor.
1098   /**
1099    * This function is used to obtain the locally bound endpoint of the acceptor.
1100    *
1101    * @returns An object that represents the local endpoint of the acceptor.
1102    *
1103    * @throws boost::system::system_error Thrown on failure.
1104    *
1105    * @par Example
1106    * @code
1107    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1108    * ...
1109    * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
1110    * @endcode
1111    */
1112   endpoint_type local_endpoint() const
1113   {
1114     boost::system::error_code ec;
1115     endpoint_type ep = impl_.get_service().local_endpoint(
1116         impl_.get_implementation(), ec);
1117     boost::asio::detail::throw_error(ec, "local_endpoint");
1118     return ep;
1119   }
1120 
1121   /// Get the local endpoint of the acceptor.
1122   /**
1123    * This function is used to obtain the locally bound endpoint of the acceptor.
1124    *
1125    * @param ec Set to indicate what error occurred, if any.
1126    *
1127    * @returns An object that represents the local endpoint of the acceptor.
1128    * Returns a default-constructed endpoint object if an error occurred and the
1129    * error handler did not throw an exception.
1130    *
1131    * @par Example
1132    * @code
1133    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1134    * ...
1135    * boost::system::error_code ec;
1136    * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
1137    * if (ec)
1138    * {
1139    *   // An error occurred.
1140    * }
1141    * @endcode
1142    */
1143   endpoint_type local_endpoint(boost::system::error_code& ec) const
1144   {
1145     return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
1146   }
1147 
1148   /// Wait for the acceptor to become ready to read, ready to write, or to have
1149   /// pending error conditions.
1150   /**
1151    * This function is used to perform a blocking wait for an acceptor to enter
1152    * a ready to read, write or error condition state.
1153    *
1154    * @param w Specifies the desired acceptor state.
1155    *
1156    * @par Example
1157    * Waiting for an acceptor to become readable.
1158    * @code
1159    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1160    * ...
1161    * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read);
1162    * @endcode
1163    */
1164   void wait(wait_type w)
1165   {
1166     boost::system::error_code ec;
1167     impl_.get_service().wait(impl_.get_implementation(), w, ec);
1168     boost::asio::detail::throw_error(ec, "wait");
1169   }
1170 
1171   /// Wait for the acceptor to become ready to read, ready to write, or to have
1172   /// pending error conditions.
1173   /**
1174    * This function is used to perform a blocking wait for an acceptor to enter
1175    * a ready to read, write or error condition state.
1176    *
1177    * @param w Specifies the desired acceptor state.
1178    *
1179    * @param ec Set to indicate what error occurred, if any.
1180    *
1181    * @par Example
1182    * Waiting for an acceptor to become readable.
1183    * @code
1184    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1185    * ...
1186    * boost::system::error_code ec;
1187    * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec);
1188    * @endcode
1189    */
1190   BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
1191   {
1192     impl_.get_service().wait(impl_.get_implementation(), w, ec);
1193     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1194   }
1195 
1196   /// Asynchronously wait for the acceptor to become ready to read, ready to
1197   /// write, or to have pending error conditions.
1198   /**
1199    * This function is used to perform an asynchronous wait for an acceptor to
1200    * enter a ready to read, write or error condition state. It is an initiating
1201    * function for an @ref asynchronous_operation, and always returns
1202    * immediately.
1203    *
1204    * @param w Specifies the desired acceptor state.
1205    *
1206    * @param token The @ref completion_token that will be used to produce a
1207    * completion handler, which will be called when the wait completes.
1208    * Potential completion tokens include @ref use_future, @ref use_awaitable,
1209    * @ref yield_context, or a function object with the correct completion
1210    * signature. The function signature of the completion handler must be:
1211    * @code void handler(
1212    *   const boost::system::error_code& error // Result of operation.
1213    * ); @endcode
1214    * Regardless of whether the asynchronous operation completes immediately or
1215    * not, the completion handler will not be invoked from within this function.
1216    * On immediate completion, invocation of the handler will be performed in a
1217    * manner equivalent to using boost::asio::post().
1218    *
1219    * @par Completion Signature
1220    * @code void(boost::system::error_code) @endcode
1221    *
1222    * @par Example
1223    * @code
1224    * void wait_handler(const boost::system::error_code& error)
1225    * {
1226    *   if (!error)
1227    *   {
1228    *     // Wait succeeded.
1229    *   }
1230    * }
1231    *
1232    * ...
1233    *
1234    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1235    * ...
1236    * acceptor.async_wait(
1237    *     boost::asio::ip::tcp::acceptor::wait_read,
1238    *     wait_handler);
1239    * @endcode
1240    *
1241    * @par Per-Operation Cancellation
1242    * On POSIX or Windows operating systems, this asynchronous operation supports
1243    * cancellation for the following boost::asio::cancellation_type values:
1244    *
1245    * @li @c cancellation_type::terminal
1246    *
1247    * @li @c cancellation_type::partial
1248    *
1249    * @li @c cancellation_type::total
1250    */
1251   template <
1252       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
1253         WaitToken = default_completion_token_t<executor_type>>
1254   auto async_wait(wait_type w,
1255       WaitToken&& token = default_completion_token_t<executor_type>())
1256     -> decltype(
1257       async_initiate<WaitToken, void (boost::system::error_code)>(
1258         declval<initiate_async_wait>(), token, w))
1259   {
1260     return async_initiate<WaitToken, void (boost::system::error_code)>(
1261         initiate_async_wait(this), token, w);
1262   }
1263 
1264 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
1265   /// Accept a new connection.
1266   /**
1267    * This function is used to accept a new connection from a peer into the
1268    * given socket. The function call will block until a new connection has been
1269    * accepted successfully or an error occurs.
1270    *
1271    * @param peer The socket into which the new connection will be accepted.
1272    *
1273    * @throws boost::system::system_error Thrown on failure.
1274    *
1275    * @par Example
1276    * @code
1277    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1278    * ...
1279    * boost::asio::ip::tcp::socket socket(my_context);
1280    * acceptor.accept(socket);
1281    * @endcode
1282    */
1283   template <typename Protocol1, typename Executor1>
1284   void accept(basic_socket<Protocol1, Executor1>& peer,
1285       constraint_t<
1286         is_convertible<Protocol, Protocol1>::value
1287       > = 0)
1288   {
1289     boost::system::error_code ec;
1290     impl_.get_service().accept(impl_.get_implementation(),
1291         peer, static_cast<endpoint_type*>(0), ec);
1292     boost::asio::detail::throw_error(ec, "accept");
1293   }
1294 
1295   /// Accept a new connection.
1296   /**
1297    * This function is used to accept a new connection from a peer into the
1298    * given socket. The function call will block until a new connection has been
1299    * accepted successfully or an error occurs.
1300    *
1301    * @param peer The socket into which the new connection will be accepted.
1302    *
1303    * @param ec Set to indicate what error occurred, if any.
1304    *
1305    * @par Example
1306    * @code
1307    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1308    * ...
1309    * boost::asio::ip::tcp::socket socket(my_context);
1310    * boost::system::error_code ec;
1311    * acceptor.accept(socket, ec);
1312    * if (ec)
1313    * {
1314    *   // An error occurred.
1315    * }
1316    * @endcode
1317    */
1318   template <typename Protocol1, typename Executor1>
1319   BOOST_ASIO_SYNC_OP_VOID accept(
1320       basic_socket<Protocol1, Executor1>& peer, boost::system::error_code& ec,
1321       constraint_t<
1322         is_convertible<Protocol, Protocol1>::value
1323       > = 0)
1324   {
1325     impl_.get_service().accept(impl_.get_implementation(),
1326         peer, static_cast<endpoint_type*>(0), ec);
1327     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1328   }
1329 
1330   /// Start an asynchronous accept.
1331   /**
1332    * This function is used to asynchronously accept a new connection into a
1333    * socket, and additionally obtain the endpoint of the remote peer. It is an
1334    * initiating function for an @ref asynchronous_operation, and always returns
1335    * immediately.
1336    *
1337    * @param peer The socket into which the new connection will be accepted.
1338    * Ownership of the peer object is retained by the caller, which must
1339    * guarantee that it is valid until the completion handler is called.
1340    *
1341    * @param token The @ref completion_token that will be used to produce a
1342    * completion handler, which will be called when the accept completes.
1343    * Potential completion tokens include @ref use_future, @ref use_awaitable,
1344    * @ref yield_context, or a function object with the correct completion
1345    * signature. The function signature of the completion handler must be:
1346    * @code void handler(
1347    *   const boost::system::error_code& error // Result of operation.
1348    * ); @endcode
1349    * Regardless of whether the asynchronous operation completes immediately or
1350    * not, the completion handler will not be invoked from within this function.
1351    * On immediate completion, invocation of the handler will be performed in a
1352    * manner equivalent to using boost::asio::post().
1353    *
1354    * @par Completion Signature
1355    * @code void(boost::system::error_code) @endcode
1356    *
1357    * @par Example
1358    * @code
1359    * void accept_handler(const boost::system::error_code& error)
1360    * {
1361    *   if (!error)
1362    *   {
1363    *     // Accept succeeded.
1364    *   }
1365    * }
1366    *
1367    * ...
1368    *
1369    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1370    * ...
1371    * boost::asio::ip::tcp::socket socket(my_context);
1372    * acceptor.async_accept(socket, accept_handler);
1373    * @endcode
1374    *
1375    * @par Per-Operation Cancellation
1376    * On POSIX or Windows operating systems, this asynchronous operation supports
1377    * cancellation for the following boost::asio::cancellation_type values:
1378    *
1379    * @li @c cancellation_type::terminal
1380    *
1381    * @li @c cancellation_type::partial
1382    *
1383    * @li @c cancellation_type::total
1384    */
1385   template <typename Protocol1, typename Executor1,
1386       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
1387         AcceptToken = default_completion_token_t<executor_type>>
1388   auto async_accept(basic_socket<Protocol1, Executor1>& peer,
1389       AcceptToken&& token = default_completion_token_t<executor_type>(),
1390       constraint_t<
1391         is_convertible<Protocol, Protocol1>::value
1392       > = 0)
1393     -> decltype(
1394       async_initiate<AcceptToken, void (boost::system::error_code)>(
1395         declval<initiate_async_accept>(), token,
1396         &peer, static_cast<endpoint_type*>(0)))
1397   {
1398     return async_initiate<AcceptToken, void (boost::system::error_code)>(
1399         initiate_async_accept(this), token,
1400         &peer, static_cast<endpoint_type*>(0));
1401   }
1402 
1403   /// Accept a new connection and obtain the endpoint of the peer
1404   /**
1405    * This function is used to accept a new connection from a peer into the
1406    * given socket, and additionally provide the endpoint of the remote peer.
1407    * The function call will block until a new connection has been accepted
1408    * successfully or an error occurs.
1409    *
1410    * @param peer The socket into which the new connection will be accepted.
1411    *
1412    * @param peer_endpoint An endpoint object which will receive the endpoint of
1413    * the remote peer.
1414    *
1415    * @throws boost::system::system_error Thrown on failure.
1416    *
1417    * @par Example
1418    * @code
1419    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1420    * ...
1421    * boost::asio::ip::tcp::socket socket(my_context);
1422    * boost::asio::ip::tcp::endpoint endpoint;
1423    * acceptor.accept(socket, endpoint);
1424    * @endcode
1425    */
1426   template <typename Executor1>
1427   void accept(basic_socket<protocol_type, Executor1>& peer,
1428       endpoint_type& peer_endpoint)
1429   {
1430     boost::system::error_code ec;
1431     impl_.get_service().accept(impl_.get_implementation(),
1432         peer, &peer_endpoint, ec);
1433     boost::asio::detail::throw_error(ec, "accept");
1434   }
1435 
1436   /// Accept a new connection and obtain the endpoint of the peer
1437   /**
1438    * This function is used to accept a new connection from a peer into the
1439    * given socket, and additionally provide the endpoint of the remote peer.
1440    * The function call will block until a new connection has been accepted
1441    * successfully or an error occurs.
1442    *
1443    * @param peer The socket into which the new connection will be accepted.
1444    *
1445    * @param peer_endpoint An endpoint object which will receive the endpoint of
1446    * the remote peer.
1447    *
1448    * @param ec Set to indicate what error occurred, if any.
1449    *
1450    * @par Example
1451    * @code
1452    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1453    * ...
1454    * boost::asio::ip::tcp::socket socket(my_context);
1455    * boost::asio::ip::tcp::endpoint endpoint;
1456    * boost::system::error_code ec;
1457    * acceptor.accept(socket, endpoint, ec);
1458    * if (ec)
1459    * {
1460    *   // An error occurred.
1461    * }
1462    * @endcode
1463    */
1464   template <typename Executor1>
1465   BOOST_ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type, Executor1>& peer,
1466       endpoint_type& peer_endpoint, boost::system::error_code& ec)
1467   {
1468     impl_.get_service().accept(
1469         impl_.get_implementation(), peer, &peer_endpoint, ec);
1470     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1471   }
1472 
1473   /// Start an asynchronous accept.
1474   /**
1475    * This function is used to asynchronously accept a new connection into a
1476    * socket, and additionally obtain the endpoint of the remote peer. It is an
1477    * initiating function for an @ref asynchronous_operation, and always returns
1478    * immediately.
1479    *
1480    * @param peer The socket into which the new connection will be accepted.
1481    * Ownership of the peer object is retained by the caller, which must
1482    * guarantee that it is valid until the completion handler is called.
1483    *
1484    * @param peer_endpoint An endpoint object into which the endpoint of the
1485    * remote peer will be written. Ownership of the peer_endpoint object is
1486    * retained by the caller, which must guarantee that it is valid until the
1487    * handler is called.
1488    *
1489    * @param token The @ref completion_token that will be used to produce a
1490    * completion handler, which will be called when the accept completes.
1491    * Potential completion tokens include @ref use_future, @ref use_awaitable,
1492    * @ref yield_context, or a function object with the correct completion
1493    * signature. The function signature of the completion handler must be:
1494    * @code void handler(
1495    *   const boost::system::error_code& error // Result of operation.
1496    * ); @endcode
1497    * Regardless of whether the asynchronous operation completes immediately or
1498    * not, the completion handler will not be invoked from within this function.
1499    * On immediate completion, invocation of the handler will be performed in a
1500    * manner equivalent to using boost::asio::post().
1501    *
1502    * @par Completion Signature
1503    * @code void(boost::system::error_code) @endcode
1504    *
1505    * @par Per-Operation Cancellation
1506    * On POSIX or Windows operating systems, this asynchronous operation supports
1507    * cancellation for the following boost::asio::cancellation_type values:
1508    *
1509    * @li @c cancellation_type::terminal
1510    *
1511    * @li @c cancellation_type::partial
1512    *
1513    * @li @c cancellation_type::total
1514    */
1515   template <typename Executor1,
1516       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
1517         AcceptToken = default_completion_token_t<executor_type>>
1518   auto async_accept(basic_socket<protocol_type, Executor1>& peer,
1519       endpoint_type& peer_endpoint,
1520       AcceptToken&& token = default_completion_token_t<executor_type>())
1521     -> decltype(
1522       async_initiate<AcceptToken, void (boost::system::error_code)>(
1523         declval<initiate_async_accept>(), token, &peer, &peer_endpoint))
1524   {
1525     return async_initiate<AcceptToken, void (boost::system::error_code)>(
1526         initiate_async_accept(this), token, &peer, &peer_endpoint);
1527   }
1528 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
1529 
1530   /// Accept a new connection.
1531   /**
1532    * This function is used to accept a new connection from a peer. The function
1533    * call will block until a new connection has been accepted successfully or
1534    * an error occurs.
1535    *
1536    * This overload requires that the Protocol template parameter satisfy the
1537    * AcceptableProtocol type requirements.
1538    *
1539    * @returns A socket object representing the newly accepted connection.
1540    *
1541    * @throws boost::system::system_error Thrown on failure.
1542    *
1543    * @par Example
1544    * @code
1545    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1546    * ...
1547    * boost::asio::ip::tcp::socket socket(acceptor.accept());
1548    * @endcode
1549    */
1550   typename Protocol::socket::template rebind_executor<executor_type>::other
1551   accept()
1552   {
1553     boost::system::error_code ec;
1554     typename Protocol::socket::template rebind_executor<
1555       executor_type>::other peer(impl_.get_executor());
1556     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1557     boost::asio::detail::throw_error(ec, "accept");
1558     return peer;
1559   }
1560 
1561   /// Accept a new connection.
1562   /**
1563    * This function is used to accept a new connection from a peer. The function
1564    * call will block until a new connection has been accepted successfully or
1565    * an error occurs.
1566    *
1567    * This overload requires that the Protocol template parameter satisfy the
1568    * AcceptableProtocol type requirements.
1569    *
1570    * @param ec Set to indicate what error occurred, if any.
1571    *
1572    * @returns On success, a socket object representing the newly accepted
1573    * connection. On error, a socket object where is_open() is false.
1574    *
1575    * @par Example
1576    * @code
1577    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1578    * ...
1579    * boost::asio::ip::tcp::socket socket(acceptor.accept(ec));
1580    * if (ec)
1581    * {
1582    *   // An error occurred.
1583    * }
1584    * @endcode
1585    */
1586   typename Protocol::socket::template rebind_executor<executor_type>::other
1587   accept(boost::system::error_code& ec)
1588   {
1589     typename Protocol::socket::template rebind_executor<
1590       executor_type>::other peer(impl_.get_executor());
1591     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1592     return peer;
1593   }
1594 
1595   /// Start an asynchronous accept.
1596   /**
1597    * This function is used to asynchronously accept a new connection. It is an
1598    * initiating function for an @ref asynchronous_operation, and always returns
1599    * immediately.
1600    *
1601    * This overload requires that the Protocol template parameter satisfy the
1602    * AcceptableProtocol type requirements.
1603    *
1604    * @param token The @ref completion_token that will be used to produce a
1605    * completion handler, which will be called when the accept completes.
1606    * Potential completion tokens include @ref use_future, @ref use_awaitable,
1607    * @ref yield_context, or a function object with the correct completion
1608    * signature. The function signature of the completion handler must be:
1609    * @code void handler(
1610    *   // Result of operation.
1611    *   const boost::system::error_code& error,
1612    *
1613    *   // On success, the newly accepted socket.
1614    *   typename Protocol::socket::template
1615    *     rebind_executor<executor_type>::other peer
1616    * ); @endcode
1617    * Regardless of whether the asynchronous operation completes immediately or
1618    * not, the completion handler will not be invoked from within this function.
1619    * On immediate completion, invocation of the handler will be performed in a
1620    * manner equivalent to using boost::asio::post().
1621    *
1622    * @par Completion Signature
1623    * @code void(boost::system::error_code,
1624    *    typename Protocol::socket::template
1625    *      rebind_executor<executor_type>::other)) @endcode
1626    *
1627    * @par Example
1628    * @code
1629    * void accept_handler(const boost::system::error_code& error,
1630    *     boost::asio::ip::tcp::socket peer)
1631    * {
1632    *   if (!error)
1633    *   {
1634    *     // Accept succeeded.
1635    *   }
1636    * }
1637    *
1638    * ...
1639    *
1640    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1641    * ...
1642    * acceptor.async_accept(accept_handler);
1643    * @endcode
1644    *
1645    * @par Per-Operation Cancellation
1646    * On POSIX or Windows operating systems, this asynchronous operation supports
1647    * cancellation for the following boost::asio::cancellation_type values:
1648    *
1649    * @li @c cancellation_type::terminal
1650    *
1651    * @li @c cancellation_type::partial
1652    *
1653    * @li @c cancellation_type::total
1654    */
1655   template <
1656       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1657         typename Protocol::socket::template rebind_executor<
1658           executor_type>::other)) MoveAcceptToken
1659             = default_completion_token_t<executor_type>>
1660   auto async_accept(
1661       MoveAcceptToken&& token = default_completion_token_t<executor_type>())
1662     -> decltype(
1663       async_initiate<MoveAcceptToken,
1664         void (boost::system::error_code, typename Protocol::socket::template
1665           rebind_executor<executor_type>::other)>(
1666             declval<initiate_async_move_accept>(), token,
1667             declval<const executor_type&>(), static_cast<endpoint_type*>(0),
1668             static_cast<typename Protocol::socket::template
1669               rebind_executor<executor_type>::other*>(0)))
1670   {
1671     return async_initiate<MoveAcceptToken,
1672       void (boost::system::error_code, typename Protocol::socket::template
1673         rebind_executor<executor_type>::other)>(
1674           initiate_async_move_accept(this), token,
1675           impl_.get_executor(), static_cast<endpoint_type*>(0),
1676           static_cast<typename Protocol::socket::template
1677             rebind_executor<executor_type>::other*>(0));
1678   }
1679 
1680   /// Accept a new connection.
1681   /**
1682    * This function is used to accept a new connection from a peer. The function
1683    * call will block until a new connection has been accepted successfully or
1684    * an error occurs.
1685    *
1686    * This overload requires that the Protocol template parameter satisfy the
1687    * AcceptableProtocol type requirements.
1688    *
1689    * @param ex The I/O executor object to be used for the newly
1690    * accepted socket.
1691    *
1692    * @returns A socket object representing the newly accepted connection.
1693    *
1694    * @throws boost::system::system_error Thrown on failure.
1695    *
1696    * @par Example
1697    * @code
1698    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1699    * ...
1700    * boost::asio::ip::tcp::socket socket(acceptor.accept());
1701    * @endcode
1702    */
1703   template <typename Executor1>
1704   typename Protocol::socket::template rebind_executor<Executor1>::other
1705   accept(const Executor1& ex,
1706       constraint_t<
1707         is_executor<Executor1>::value
1708           || execution::is_executor<Executor1>::value
1709       > = 0)
1710   {
1711     boost::system::error_code ec;
1712     typename Protocol::socket::template
1713       rebind_executor<Executor1>::other peer(ex);
1714     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1715     boost::asio::detail::throw_error(ec, "accept");
1716     return peer;
1717   }
1718 
1719   /// Accept a new connection.
1720   /**
1721    * This function is used to accept a new connection from a peer. The function
1722    * call will block until a new connection has been accepted successfully or
1723    * an error occurs.
1724    *
1725    * This overload requires that the Protocol template parameter satisfy the
1726    * AcceptableProtocol type requirements.
1727    *
1728    * @param context The I/O execution context object to be used for the newly
1729    * accepted socket.
1730    *
1731    * @returns A socket object representing the newly accepted connection.
1732    *
1733    * @throws boost::system::system_error Thrown on failure.
1734    *
1735    * @par Example
1736    * @code
1737    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1738    * ...
1739    * boost::asio::ip::tcp::socket socket(acceptor.accept());
1740    * @endcode
1741    */
1742   template <typename ExecutionContext>
1743   typename Protocol::socket::template rebind_executor<
1744       typename ExecutionContext::executor_type>::other
1745   accept(ExecutionContext& context,
1746       constraint_t<
1747         is_convertible<ExecutionContext&, execution_context&>::value
1748       > = 0)
1749   {
1750     boost::system::error_code ec;
1751     typename Protocol::socket::template rebind_executor<
1752         typename ExecutionContext::executor_type>::other peer(context);
1753     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1754     boost::asio::detail::throw_error(ec, "accept");
1755     return peer;
1756   }
1757 
1758   /// Accept a new connection.
1759   /**
1760    * This function is used to accept a new connection from a peer. The function
1761    * call will block until a new connection has been accepted successfully or
1762    * an error occurs.
1763    *
1764    * This overload requires that the Protocol template parameter satisfy the
1765    * AcceptableProtocol type requirements.
1766    *
1767    * @param ex The I/O executor object to be used for the newly accepted
1768    * socket.
1769    *
1770    * @param ec Set to indicate what error occurred, if any.
1771    *
1772    * @returns On success, a socket object representing the newly accepted
1773    * connection. On error, a socket object where is_open() is false.
1774    *
1775    * @par Example
1776    * @code
1777    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1778    * ...
1779    * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1780    * if (ec)
1781    * {
1782    *   // An error occurred.
1783    * }
1784    * @endcode
1785    */
1786   template <typename Executor1>
1787   typename Protocol::socket::template rebind_executor<Executor1>::other
1788   accept(const Executor1& ex, boost::system::error_code& ec,
1789       constraint_t<
1790         is_executor<Executor1>::value
1791           || execution::is_executor<Executor1>::value
1792       > = 0)
1793   {
1794     typename Protocol::socket::template
1795       rebind_executor<Executor1>::other peer(ex);
1796     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1797     return peer;
1798   }
1799 
1800   /// Accept a new connection.
1801   /**
1802    * This function is used to accept a new connection from a peer. The function
1803    * call will block until a new connection has been accepted successfully or
1804    * an error occurs.
1805    *
1806    * This overload requires that the Protocol template parameter satisfy the
1807    * AcceptableProtocol type requirements.
1808    *
1809    * @param context The I/O execution context object to be used for the newly
1810    * accepted socket.
1811    *
1812    * @param ec Set to indicate what error occurred, if any.
1813    *
1814    * @returns On success, a socket object representing the newly accepted
1815    * connection. On error, a socket object where is_open() is false.
1816    *
1817    * @par Example
1818    * @code
1819    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1820    * ...
1821    * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
1822    * if (ec)
1823    * {
1824    *   // An error occurred.
1825    * }
1826    * @endcode
1827    */
1828   template <typename ExecutionContext>
1829   typename Protocol::socket::template rebind_executor<
1830       typename ExecutionContext::executor_type>::other
1831   accept(ExecutionContext& context, boost::system::error_code& ec,
1832       constraint_t<
1833         is_convertible<ExecutionContext&, execution_context&>::value
1834       > = 0)
1835   {
1836     typename Protocol::socket::template rebind_executor<
1837         typename ExecutionContext::executor_type>::other peer(context);
1838     impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
1839     return peer;
1840   }
1841 
1842   /// Start an asynchronous accept.
1843   /**
1844    * This function is used to asynchronously accept a new connection. It is an
1845    * initiating function for an @ref asynchronous_operation, and always returns
1846    * immediately.
1847    *
1848    * This overload requires that the Protocol template parameter satisfy the
1849    * AcceptableProtocol type requirements.
1850    *
1851    * @param ex The I/O executor object to be used for the newly accepted
1852    * socket.
1853    *
1854    * @param token The @ref completion_token that will be used to produce a
1855    * completion handler, which will be called when the accept completes.
1856    * Potential completion tokens include @ref use_future, @ref use_awaitable,
1857    * @ref yield_context, or a function object with the correct completion
1858    * signature. The function signature of the completion handler must be:
1859    * @code void handler(
1860    *   // Result of operation.
1861    *   const boost::system::error_code& error,
1862    *
1863    *   // On success, the newly accepted socket.
1864    *   typename Protocol::socket::template rebind_executor<
1865    *     Executor1>::other peer
1866    * ); @endcode
1867    * Regardless of whether the asynchronous operation completes immediately or
1868    * not, the completion handler will not be invoked from within this function.
1869    * On immediate completion, invocation of the handler will be performed in a
1870    * manner equivalent to using boost::asio::post().
1871    *
1872    * @par Completion Signature
1873    * @code void(boost::system::error_code,
1874    *    typename Protocol::socket::template rebind_executor<
1875    *      Executor1>::other)) @endcode
1876    *
1877    * @par Example
1878    * @code
1879    * void accept_handler(const boost::system::error_code& error,
1880    *     boost::asio::ip::tcp::socket peer)
1881    * {
1882    *   if (!error)
1883    *   {
1884    *     // Accept succeeded.
1885    *   }
1886    * }
1887    *
1888    * ...
1889    *
1890    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1891    * ...
1892    * acceptor.async_accept(my_context2, accept_handler);
1893    * @endcode
1894    *
1895    * @par Per-Operation Cancellation
1896    * On POSIX or Windows operating systems, this asynchronous operation supports
1897    * cancellation for the following boost::asio::cancellation_type values:
1898    *
1899    * @li @c cancellation_type::terminal
1900    *
1901    * @li @c cancellation_type::partial
1902    *
1903    * @li @c cancellation_type::total
1904    */
1905   template <typename Executor1,
1906       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1907         typename Protocol::socket::template rebind_executor<
1908           constraint_t<is_executor<Executor1>::value
1909             || execution::is_executor<Executor1>::value,
1910               Executor1>>::other)) MoveAcceptToken
1911                 = default_completion_token_t<executor_type>>
1912   auto async_accept(const Executor1& ex,
1913       MoveAcceptToken&& token = default_completion_token_t<executor_type>(),
1914       constraint_t<
1915         is_executor<Executor1>::value
1916           || execution::is_executor<Executor1>::value
1917       > = 0)
1918     -> decltype(
1919       async_initiate<MoveAcceptToken,
1920         void (boost::system::error_code,
1921           typename Protocol::socket::template rebind_executor<
1922             Executor1>::other)>(
1923               declval<initiate_async_move_accept>(), token,
1924               ex, static_cast<endpoint_type*>(0),
1925               static_cast<typename Protocol::socket::template
1926                 rebind_executor<Executor1>::other*>(0)))
1927   {
1928     return async_initiate<MoveAcceptToken,
1929       void (boost::system::error_code,
1930         typename Protocol::socket::template rebind_executor<
1931           Executor1>::other)>(
1932             initiate_async_move_accept(this), token,
1933             ex, static_cast<endpoint_type*>(0),
1934             static_cast<typename Protocol::socket::template
1935               rebind_executor<Executor1>::other*>(0));
1936   }
1937 
1938   /// Start an asynchronous accept.
1939   /**
1940    * This function is used to asynchronously accept a new connection. It is an
1941    * initiating function for an @ref asynchronous_operation, and always returns
1942    * immediately.
1943    *
1944    * This overload requires that the Protocol template parameter satisfy the
1945    * AcceptableProtocol type requirements.
1946    *
1947    * @param context The I/O execution context object to be used for the newly
1948    * accepted socket.
1949    *
1950    * @param token The @ref completion_token that will be used to produce a
1951    * completion handler, which will be called when the accept completes.
1952    * Potential completion tokens include @ref use_future, @ref use_awaitable,
1953    * @ref yield_context, or a function object with the correct completion
1954    * signature. The function signature of the completion handler must be:
1955    * @code void handler(
1956    *   // Result of operation.
1957    *   const boost::system::error_code& error,
1958    *
1959    *   // On success, the newly accepted socket.
1960    *   typename Protocol::socket::template rebind_executor<
1961    *     typename ExecutionContext::executor_type>::other peer
1962    * ); @endcode
1963    * Regardless of whether the asynchronous operation completes immediately or
1964    * not, the completion handler will not be invoked from within this function.
1965    * On immediate completion, invocation of the handler will be performed in a
1966    * manner equivalent to using boost::asio::post().
1967    *
1968    * @par Completion Signature
1969    * @code void(boost::system::error_code,
1970    *    typename Protocol::socket::template rebind_executor<
1971    *      typename ExecutionContext::executor_type>::other)) @endcode
1972    *
1973    * @par Example
1974    * @code
1975    * void accept_handler(const boost::system::error_code& error,
1976    *     boost::asio::ip::tcp::socket peer)
1977    * {
1978    *   if (!error)
1979    *   {
1980    *     // Accept succeeded.
1981    *   }
1982    * }
1983    *
1984    * ...
1985    *
1986    * boost::asio::ip::tcp::acceptor acceptor(my_context);
1987    * ...
1988    * acceptor.async_accept(my_context2, accept_handler);
1989    * @endcode
1990    *
1991    * @par Per-Operation Cancellation
1992    * On POSIX or Windows operating systems, this asynchronous operation supports
1993    * cancellation for the following boost::asio::cancellation_type values:
1994    *
1995    * @li @c cancellation_type::terminal
1996    *
1997    * @li @c cancellation_type::partial
1998    *
1999    * @li @c cancellation_type::total
2000    */
2001   template <typename ExecutionContext,
2002       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2003         typename Protocol::socket::template rebind_executor<
2004           typename ExecutionContext::executor_type>::other)) MoveAcceptToken
2005             = default_completion_token_t<executor_type>>
2006   auto async_accept(ExecutionContext& context,
2007       MoveAcceptToken&& token = default_completion_token_t<executor_type>(),
2008       constraint_t<
2009         is_convertible<ExecutionContext&, execution_context&>::value
2010       > = 0)
2011     -> decltype(
2012       async_initiate<MoveAcceptToken,
2013         void (boost::system::error_code,
2014           typename Protocol::socket::template rebind_executor<
2015             typename ExecutionContext::executor_type>::other)>(
2016               declval<initiate_async_move_accept>(), token,
2017               context.get_executor(), static_cast<endpoint_type*>(0),
2018               static_cast<typename Protocol::socket::template rebind_executor<
2019                 typename ExecutionContext::executor_type>::other*>(0)))
2020   {
2021     return async_initiate<MoveAcceptToken,
2022       void (boost::system::error_code,
2023         typename Protocol::socket::template rebind_executor<
2024           typename ExecutionContext::executor_type>::other)>(
2025             initiate_async_move_accept(this), token,
2026             context.get_executor(), static_cast<endpoint_type*>(0),
2027             static_cast<typename Protocol::socket::template rebind_executor<
2028               typename ExecutionContext::executor_type>::other*>(0));
2029   }
2030 
2031   /// Accept a new connection.
2032   /**
2033    * This function is used to accept a new connection from a peer. The function
2034    * call will block until a new connection has been accepted successfully or
2035    * an error occurs.
2036    *
2037    * This overload requires that the Protocol template parameter satisfy the
2038    * AcceptableProtocol type requirements.
2039    *
2040    * @param peer_endpoint An endpoint object into which the endpoint of the
2041    * remote peer will be written.
2042    *
2043    * @returns A socket object representing the newly accepted connection.
2044    *
2045    * @throws boost::system::system_error Thrown on failure.
2046    *
2047    * @par Example
2048    * @code
2049    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2050    * ...
2051    * boost::asio::ip::tcp::endpoint endpoint;
2052    * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint));
2053    * @endcode
2054    */
2055   typename Protocol::socket::template rebind_executor<executor_type>::other
2056   accept(endpoint_type& peer_endpoint)
2057   {
2058     boost::system::error_code ec;
2059     typename Protocol::socket::template rebind_executor<
2060       executor_type>::other peer(impl_.get_executor());
2061     impl_.get_service().accept(impl_.get_implementation(),
2062         peer, &peer_endpoint, ec);
2063     boost::asio::detail::throw_error(ec, "accept");
2064     return peer;
2065   }
2066 
2067   /// Accept a new connection.
2068   /**
2069    * This function is used to accept a new connection from a peer. The function
2070    * call will block until a new connection has been accepted successfully or
2071    * an error occurs.
2072    *
2073    * This overload requires that the Protocol template parameter satisfy the
2074    * AcceptableProtocol type requirements.
2075    *
2076    * @param peer_endpoint An endpoint object into which the endpoint of the
2077    * remote peer will be written.
2078    *
2079    * @param ec Set to indicate what error occurred, if any.
2080    *
2081    * @returns On success, a socket object representing the newly accepted
2082    * connection. On error, a socket object where is_open() is false.
2083    *
2084    * @par Example
2085    * @code
2086    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2087    * ...
2088    * boost::asio::ip::tcp::endpoint endpoint;
2089    * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
2090    * if (ec)
2091    * {
2092    *   // An error occurred.
2093    * }
2094    * @endcode
2095    */
2096   typename Protocol::socket::template rebind_executor<executor_type>::other
2097   accept(endpoint_type& peer_endpoint, boost::system::error_code& ec)
2098   {
2099     typename Protocol::socket::template rebind_executor<
2100       executor_type>::other peer(impl_.get_executor());
2101     impl_.get_service().accept(impl_.get_implementation(),
2102         peer, &peer_endpoint, ec);
2103     return peer;
2104   }
2105 
2106   /// Start an asynchronous accept.
2107   /**
2108    * This function is used to asynchronously accept a new connection. It is an
2109    * initiating function for an @ref asynchronous_operation, and always returns
2110    * immediately.
2111    *
2112    * This overload requires that the Protocol template parameter satisfy the
2113    * AcceptableProtocol type requirements.
2114    *
2115    * @param peer_endpoint An endpoint object into which the endpoint of the
2116    * remote peer will be written. Ownership of the peer_endpoint object is
2117    * retained by the caller, which must guarantee that it is valid until the
2118    * completion handler is called.
2119    *
2120    * @param token The @ref completion_token that will be used to produce a
2121    * completion handler, which will be called when the accept completes.
2122    * Potential completion tokens include @ref use_future, @ref use_awaitable,
2123    * @ref yield_context, or a function object with the correct completion
2124    * signature. The function signature of the completion handler must be:
2125    * @code void handler(
2126    *   // Result of operation.
2127    *   const boost::system::error_code& error,
2128    *
2129    *   // On success, the newly accepted socket.
2130    *   typename Protocol::socket::template
2131    *     rebind_executor<executor_type>::other peer
2132    * ); @endcode
2133    * Regardless of whether the asynchronous operation completes immediately or
2134    * not, the completion handler will not be invoked from within this function.
2135    * On immediate completion, invocation of the handler will be performed in a
2136    * manner equivalent to using boost::asio::post().
2137    *
2138    * @par Completion Signature
2139    * @code void(boost::system::error_code,
2140    *    typename Protocol::socket::template
2141    *      rebind_executor<executor_type>::other)) @endcode
2142    *
2143    * @par Example
2144    * @code
2145    * void accept_handler(const boost::system::error_code& error,
2146    *     boost::asio::ip::tcp::socket peer)
2147    * {
2148    *   if (!error)
2149    *   {
2150    *     // Accept succeeded.
2151    *   }
2152    * }
2153    *
2154    * ...
2155    *
2156    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2157    * ...
2158    * boost::asio::ip::tcp::endpoint endpoint;
2159    * acceptor.async_accept(endpoint, accept_handler);
2160    * @endcode
2161    *
2162    * @par Per-Operation Cancellation
2163    * On POSIX or Windows operating systems, this asynchronous operation supports
2164    * cancellation for the following boost::asio::cancellation_type values:
2165    *
2166    * @li @c cancellation_type::terminal
2167    *
2168    * @li @c cancellation_type::partial
2169    *
2170    * @li @c cancellation_type::total
2171    */
2172   template <
2173       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2174         typename Protocol::socket::template rebind_executor<
2175           executor_type>::other)) MoveAcceptToken
2176             = default_completion_token_t<executor_type>>
2177   auto async_accept(endpoint_type& peer_endpoint,
2178       MoveAcceptToken&& token = default_completion_token_t<executor_type>())
2179     -> decltype(
2180       async_initiate<MoveAcceptToken,
2181         void (boost::system::error_code, typename Protocol::socket::template
2182           rebind_executor<executor_type>::other)>(
2183             declval<initiate_async_move_accept>(), token,
2184             declval<const executor_type&>(), &peer_endpoint,
2185             static_cast<typename Protocol::socket::template
2186               rebind_executor<executor_type>::other*>(0)))
2187   {
2188     return async_initiate<MoveAcceptToken,
2189       void (boost::system::error_code, typename Protocol::socket::template
2190         rebind_executor<executor_type>::other)>(
2191           initiate_async_move_accept(this), token,
2192           impl_.get_executor(), &peer_endpoint,
2193           static_cast<typename Protocol::socket::template
2194             rebind_executor<executor_type>::other*>(0));
2195   }
2196 
2197   /// Accept a new connection.
2198   /**
2199    * This function is used to accept a new connection from a peer. The function
2200    * call will block until a new connection has been accepted successfully or
2201    * an error occurs.
2202    *
2203    * This overload requires that the Protocol template parameter satisfy the
2204    * AcceptableProtocol type requirements.
2205    *
2206    * @param ex The I/O executor object to be used for the newly accepted
2207    * socket.
2208    *
2209    * @param peer_endpoint An endpoint object into which the endpoint of the
2210    * remote peer will be written.
2211    *
2212    * @returns A socket object representing the newly accepted connection.
2213    *
2214    * @throws boost::system::system_error Thrown on failure.
2215    *
2216    * @par Example
2217    * @code
2218    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2219    * ...
2220    * boost::asio::ip::tcp::endpoint endpoint;
2221    * boost::asio::ip::tcp::socket socket(
2222    *     acceptor.accept(my_context2, endpoint));
2223    * @endcode
2224    */
2225   template <typename Executor1>
2226   typename Protocol::socket::template rebind_executor<Executor1>::other
2227   accept(const Executor1& ex, endpoint_type& peer_endpoint,
2228       constraint_t<
2229         is_executor<Executor1>::value
2230           || execution::is_executor<Executor1>::value
2231       > = 0)
2232   {
2233     boost::system::error_code ec;
2234     typename Protocol::socket::template
2235         rebind_executor<Executor1>::other peer(ex);
2236     impl_.get_service().accept(impl_.get_implementation(),
2237         peer, &peer_endpoint, ec);
2238     boost::asio::detail::throw_error(ec, "accept");
2239     return peer;
2240   }
2241 
2242   /// Accept a new connection.
2243   /**
2244    * This function is used to accept a new connection from a peer. The function
2245    * call will block until a new connection has been accepted successfully or
2246    * an error occurs.
2247    *
2248    * This overload requires that the Protocol template parameter satisfy the
2249    * AcceptableProtocol type requirements.
2250    *
2251    * @param context The I/O execution context object to be used for the newly
2252    * accepted socket.
2253    *
2254    * @param peer_endpoint An endpoint object into which the endpoint of the
2255    * remote peer will be written.
2256    *
2257    * @returns A socket object representing the newly accepted connection.
2258    *
2259    * @throws boost::system::system_error Thrown on failure.
2260    *
2261    * @par Example
2262    * @code
2263    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2264    * ...
2265    * boost::asio::ip::tcp::endpoint endpoint;
2266    * boost::asio::ip::tcp::socket socket(
2267    *     acceptor.accept(my_context2, endpoint));
2268    * @endcode
2269    */
2270   template <typename ExecutionContext>
2271   typename Protocol::socket::template rebind_executor<
2272       typename ExecutionContext::executor_type>::other
2273   accept(ExecutionContext& context, endpoint_type& peer_endpoint,
2274       constraint_t<
2275         is_convertible<ExecutionContext&, execution_context&>::value
2276       > = 0)
2277   {
2278     boost::system::error_code ec;
2279     typename Protocol::socket::template rebind_executor<
2280         typename ExecutionContext::executor_type>::other peer(context);
2281     impl_.get_service().accept(impl_.get_implementation(),
2282         peer, &peer_endpoint, ec);
2283     boost::asio::detail::throw_error(ec, "accept");
2284     return peer;
2285   }
2286 
2287   /// Accept a new connection.
2288   /**
2289    * This function is used to accept a new connection from a peer. The function
2290    * call will block until a new connection has been accepted successfully or
2291    * an error occurs.
2292    *
2293    * This overload requires that the Protocol template parameter satisfy the
2294    * AcceptableProtocol type requirements.
2295    *
2296    * @param ex The I/O executor object to be used for the newly accepted
2297    * socket.
2298    *
2299    * @param peer_endpoint An endpoint object into which the endpoint of the
2300    * remote peer will be written.
2301    *
2302    * @param ec Set to indicate what error occurred, if any.
2303    *
2304    * @returns On success, a socket object representing the newly accepted
2305    * connection. On error, a socket object where is_open() is false.
2306    *
2307    * @par Example
2308    * @code
2309    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2310    * ...
2311    * boost::asio::ip::tcp::endpoint endpoint;
2312    * boost::asio::ip::tcp::socket socket(
2313    *     acceptor.accept(my_context2, endpoint, ec));
2314    * if (ec)
2315    * {
2316    *   // An error occurred.
2317    * }
2318    * @endcode
2319    */
2320   template <typename Executor1>
2321   typename Protocol::socket::template rebind_executor<Executor1>::other
2322   accept(const executor_type& ex,
2323       endpoint_type& peer_endpoint, boost::system::error_code& ec,
2324       constraint_t<
2325         is_executor<Executor1>::value
2326           || execution::is_executor<Executor1>::value
2327       > = 0)
2328   {
2329     typename Protocol::socket::template
2330       rebind_executor<Executor1>::other peer(ex);
2331     impl_.get_service().accept(impl_.get_implementation(),
2332         peer, &peer_endpoint, ec);
2333     return peer;
2334   }
2335 
2336   /// Accept a new connection.
2337   /**
2338    * This function is used to accept a new connection from a peer. The function
2339    * call will block until a new connection has been accepted successfully or
2340    * an error occurs.
2341    *
2342    * This overload requires that the Protocol template parameter satisfy the
2343    * AcceptableProtocol type requirements.
2344    *
2345    * @param context The I/O execution context object to be used for the newly
2346    * accepted socket.
2347    *
2348    * @param peer_endpoint An endpoint object into which the endpoint of the
2349    * remote peer will be written.
2350    *
2351    * @param ec Set to indicate what error occurred, if any.
2352    *
2353    * @returns On success, a socket object representing the newly accepted
2354    * connection. On error, a socket object where is_open() is false.
2355    *
2356    * @par Example
2357    * @code
2358    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2359    * ...
2360    * boost::asio::ip::tcp::endpoint endpoint;
2361    * boost::asio::ip::tcp::socket socket(
2362    *     acceptor.accept(my_context2, endpoint, ec));
2363    * if (ec)
2364    * {
2365    *   // An error occurred.
2366    * }
2367    * @endcode
2368    */
2369   template <typename ExecutionContext>
2370   typename Protocol::socket::template rebind_executor<
2371       typename ExecutionContext::executor_type>::other
2372   accept(ExecutionContext& context,
2373       endpoint_type& peer_endpoint, boost::system::error_code& ec,
2374       constraint_t<
2375         is_convertible<ExecutionContext&, execution_context&>::value
2376       > = 0)
2377   {
2378     typename Protocol::socket::template rebind_executor<
2379         typename ExecutionContext::executor_type>::other peer(context);
2380     impl_.get_service().accept(impl_.get_implementation(),
2381         peer, &peer_endpoint, ec);
2382     return peer;
2383   }
2384 
2385   /// Start an asynchronous accept.
2386   /**
2387    * This function is used to asynchronously accept a new connection. It is an
2388    * initiating function for an @ref asynchronous_operation, and always returns
2389    * immediately.
2390    *
2391    * This overload requires that the Protocol template parameter satisfy the
2392    * AcceptableProtocol type requirements.
2393    *
2394    * @param ex The I/O executor object to be used for the newly accepted
2395    * socket.
2396    *
2397    * @param peer_endpoint An endpoint object into which the endpoint of the
2398    * remote peer will be written. Ownership of the peer_endpoint object is
2399    * retained by the caller, which must guarantee that it is valid until the
2400    * completion handler is called.
2401    *
2402    * @param token The @ref completion_token that will be used to produce a
2403    * completion handler, which will be called when the accept completes.
2404    * Potential completion tokens include @ref use_future, @ref use_awaitable,
2405    * @ref yield_context, or a function object with the correct completion
2406    * signature. The function signature of the completion handler must be:
2407    * @code void handler(
2408    *   // Result of operation.
2409    *   const boost::system::error_code& error,
2410    *
2411    *   // On success, the newly accepted socket.
2412    *   typename Protocol::socket::template rebind_executor<
2413    *     Executor1>::other peer
2414    * ); @endcode
2415    * Regardless of whether the asynchronous operation completes immediately or
2416    * not, the completion handler will not be invoked from within this function.
2417    * On immediate completion, invocation of the handler will be performed in a
2418    * manner equivalent to using boost::asio::post().
2419    *
2420    * @par Completion Signature
2421    * @code void(boost::system::error_code,
2422    *    typename Protocol::socket::template rebind_executor<
2423    *      Executor1>::other)) @endcode
2424    *
2425    * @par Example
2426    * @code
2427    * void accept_handler(const boost::system::error_code& error,
2428    *     boost::asio::ip::tcp::socket peer)
2429    * {
2430    *   if (!error)
2431    *   {
2432    *     // Accept succeeded.
2433    *   }
2434    * }
2435    *
2436    * ...
2437    *
2438    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2439    * ...
2440    * boost::asio::ip::tcp::endpoint endpoint;
2441    * acceptor.async_accept(my_context2, endpoint, accept_handler);
2442    * @endcode
2443    *
2444    * @par Per-Operation Cancellation
2445    * On POSIX or Windows operating systems, this asynchronous operation supports
2446    * cancellation for the following boost::asio::cancellation_type values:
2447    *
2448    * @li @c cancellation_type::terminal
2449    *
2450    * @li @c cancellation_type::partial
2451    *
2452    * @li @c cancellation_type::total
2453    */
2454   template <typename Executor1,
2455       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2456         typename Protocol::socket::template rebind_executor<
2457           constraint_t<is_executor<Executor1>::value
2458             || execution::is_executor<Executor1>::value,
2459               Executor1>>::other)) MoveAcceptToken
2460                 = default_completion_token_t<executor_type>>
2461   auto async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
2462       MoveAcceptToken&& token = default_completion_token_t<executor_type>(),
2463       constraint_t<
2464         is_executor<Executor1>::value
2465           || execution::is_executor<Executor1>::value
2466       > = 0)
2467     -> decltype(
2468       async_initiate<MoveAcceptToken,
2469         void (boost::system::error_code,
2470           typename Protocol::socket::template rebind_executor<
2471             Executor1>::other)>(
2472           declval<initiate_async_move_accept>(), token, ex, &peer_endpoint,
2473           static_cast<typename Protocol::socket::template
2474             rebind_executor<Executor1>::other*>(0)))
2475   {
2476     return async_initiate<MoveAcceptToken,
2477       void (boost::system::error_code,
2478         typename Protocol::socket::template rebind_executor<
2479           Executor1>::other)>(
2480             initiate_async_move_accept(this), token, ex, &peer_endpoint,
2481             static_cast<typename Protocol::socket::template
2482               rebind_executor<Executor1>::other*>(0));
2483   }
2484 
2485   /// Start an asynchronous accept.
2486   /**
2487    * This function is used to asynchronously accept a new connection. It is an
2488    * initiating function for an @ref asynchronous_operation, and always returns
2489    * immediately.
2490    *
2491    * This overload requires that the Protocol template parameter satisfy the
2492    * AcceptableProtocol type requirements.
2493    *
2494    * @param context The I/O execution context object to be used for the newly
2495    * accepted socket.
2496    *
2497    * @param peer_endpoint An endpoint object into which the endpoint of the
2498    * remote peer will be written. Ownership of the peer_endpoint object is
2499    * retained by the caller, which must guarantee that it is valid until the
2500    * completion handler is called.
2501    *
2502    * @param token The @ref completion_token that will be used to produce a
2503    * completion handler, which will be called when the accept completes.
2504    * Potential completion tokens include @ref use_future, @ref use_awaitable,
2505    * @ref yield_context, or a function object with the correct completion
2506    * signature. The function signature of the completion handler must be:
2507    * @code void handler(
2508    *   // Result of operation.
2509    *   const boost::system::error_code& error,
2510    *
2511    *   // On success, the newly accepted socket.
2512    *   typename Protocol::socket::template rebind_executor<
2513    *     typename ExecutionContext::executor_type>::other peer
2514    * ); @endcode
2515    * Regardless of whether the asynchronous operation completes immediately or
2516    * not, the completion handler will not be invoked from within this function.
2517    * On immediate completion, invocation of the handler will be performed in a
2518    * manner equivalent to using boost::asio::post().
2519    *
2520    * @par Completion Signature
2521    * @code void(boost::system::error_code,
2522    *    typename Protocol::socket::template rebind_executor<
2523    *      typename ExecutionContext::executor_type>::other)) @endcode
2524    *
2525    * @par Example
2526    * @code
2527    * void accept_handler(const boost::system::error_code& error,
2528    *     boost::asio::ip::tcp::socket peer)
2529    * {
2530    *   if (!error)
2531    *   {
2532    *     // Accept succeeded.
2533    *   }
2534    * }
2535    *
2536    * ...
2537    *
2538    * boost::asio::ip::tcp::acceptor acceptor(my_context);
2539    * ...
2540    * boost::asio::ip::tcp::endpoint endpoint;
2541    * acceptor.async_accept(my_context2, endpoint, accept_handler);
2542    * @endcode
2543    *
2544    * @par Per-Operation Cancellation
2545    * On POSIX or Windows operating systems, this asynchronous operation supports
2546    * cancellation for the following boost::asio::cancellation_type values:
2547    *
2548    * @li @c cancellation_type::terminal
2549    *
2550    * @li @c cancellation_type::partial
2551    *
2552    * @li @c cancellation_type::total
2553    */
2554   template <typename ExecutionContext,
2555       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
2556         typename Protocol::socket::template rebind_executor<
2557           typename ExecutionContext::executor_type>::other)) MoveAcceptToken
2558             = default_completion_token_t<executor_type>>
2559   auto async_accept(ExecutionContext& context, endpoint_type& peer_endpoint,
2560       MoveAcceptToken&& token = default_completion_token_t<executor_type>(),
2561       constraint_t<
2562         is_convertible<ExecutionContext&, execution_context&>::value
2563       > = 0)
2564     -> decltype(
2565       async_initiate<MoveAcceptToken,
2566         void (boost::system::error_code,
2567           typename Protocol::socket::template rebind_executor<
2568             typename ExecutionContext::executor_type>::other)>(
2569               declval<initiate_async_move_accept>(), token,
2570               context.get_executor(), &peer_endpoint,
2571               static_cast<typename Protocol::socket::template rebind_executor<
2572                 typename ExecutionContext::executor_type>::other*>(0)))
2573   {
2574     return async_initiate<MoveAcceptToken,
2575       void (boost::system::error_code,
2576         typename Protocol::socket::template rebind_executor<
2577           typename ExecutionContext::executor_type>::other)>(
2578             initiate_async_move_accept(this), token,
2579             context.get_executor(), &peer_endpoint,
2580             static_cast<typename Protocol::socket::template rebind_executor<
2581               typename ExecutionContext::executor_type>::other*>(0));
2582   }
2583 
2584 private:
2585   // Disallow copying and assignment.
2586   basic_socket_acceptor(const basic_socket_acceptor&) = delete;
2587   basic_socket_acceptor& operator=(
2588       const basic_socket_acceptor&) = delete;
2589 
2590   class initiate_async_wait
2591   {
2592   public:
2593     typedef Executor executor_type;
2594 
2595     explicit initiate_async_wait(basic_socket_acceptor* self)
2596       : self_(self)
2597     {
2598     }
2599 
2600     const executor_type& get_executor() const noexcept
2601     {
2602       return self_->get_executor();
2603     }
2604 
2605     template <typename WaitHandler>
2606     void operator()(WaitHandler&& handler, wait_type w) const
2607     {
2608       // If you get an error on the following line it means that your handler
2609       // does not meet the documented type requirements for a WaitHandler.
2610       BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
2611 
2612       detail::non_const_lvalue<WaitHandler> handler2(handler);
2613       self_->impl_.get_service().async_wait(
2614           self_->impl_.get_implementation(), w,
2615           handler2.value, self_->impl_.get_executor());
2616     }
2617 
2618   private:
2619     basic_socket_acceptor* self_;
2620   };
2621 
2622   class initiate_async_accept
2623   {
2624   public:
2625     typedef Executor executor_type;
2626 
2627     explicit initiate_async_accept(basic_socket_acceptor* self)
2628       : self_(self)
2629     {
2630     }
2631 
2632     const executor_type& get_executor() const noexcept
2633     {
2634       return self_->get_executor();
2635     }
2636 
2637     template <typename AcceptHandler, typename Protocol1, typename Executor1>
2638     void operator()(AcceptHandler&& handler,
2639         basic_socket<Protocol1, Executor1>* peer,
2640         endpoint_type* peer_endpoint) const
2641     {
2642       // If you get an error on the following line it means that your handler
2643       // does not meet the documented type requirements for a AcceptHandler.
2644       BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
2645 
2646       detail::non_const_lvalue<AcceptHandler> handler2(handler);
2647       self_->impl_.get_service().async_accept(
2648           self_->impl_.get_implementation(), *peer, peer_endpoint,
2649           handler2.value, self_->impl_.get_executor());
2650     }
2651 
2652   private:
2653     basic_socket_acceptor* self_;
2654   };
2655 
2656   class initiate_async_move_accept
2657   {
2658   public:
2659     typedef Executor executor_type;
2660 
2661     explicit initiate_async_move_accept(basic_socket_acceptor* self)
2662       : self_(self)
2663     {
2664     }
2665 
2666     const executor_type& get_executor() const noexcept
2667     {
2668       return self_->get_executor();
2669     }
2670 
2671     template <typename MoveAcceptHandler, typename Executor1, typename Socket>
2672     void operator()(MoveAcceptHandler&& handler,
2673         const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const
2674     {
2675       // If you get an error on the following line it means that your handler
2676       // does not meet the documented type requirements for a MoveAcceptHandler.
2677       BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(
2678           MoveAcceptHandler, handler, Socket) type_check;
2679 
2680       detail::non_const_lvalue<MoveAcceptHandler> handler2(handler);
2681       self_->impl_.get_service().async_move_accept(
2682           self_->impl_.get_implementation(), peer_ex, peer_endpoint,
2683           handler2.value, self_->impl_.get_executor());
2684     }
2685 
2686   private:
2687     basic_socket_acceptor* self_;
2688   };
2689 
2690 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
2691   detail::io_object_impl<
2692     detail::null_socket_service<Protocol>, Executor> impl_;
2693 #elif defined(BOOST_ASIO_HAS_IOCP)
2694   detail::io_object_impl<
2695     detail::win_iocp_socket_service<Protocol>, Executor> impl_;
2696 #elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
2697   detail::io_object_impl<
2698     detail::io_uring_socket_service<Protocol>, Executor> impl_;
2699 #else
2700   detail::io_object_impl<
2701     detail::reactive_socket_service<Protocol>, Executor> impl_;
2702 #endif
2703 };
2704 
2705 } // namespace asio
2706 } // namespace boost
2707 
2708 #include <boost/asio/detail/pop_options.hpp>
2709 
2710 #endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP