Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // basic_raw_socket.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_RAW_SOCKET_HPP
0012 #define BOOST_ASIO_BASIC_RAW_SOCKET_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <cstddef>
0020 #include <boost/asio/basic_socket.hpp>
0021 #include <boost/asio/detail/handler_type_requirements.hpp>
0022 #include <boost/asio/detail/non_const_lvalue.hpp>
0023 #include <boost/asio/detail/throw_error.hpp>
0024 #include <boost/asio/detail/type_traits.hpp>
0025 #include <boost/asio/error.hpp>
0026 
0027 #include <boost/asio/detail/push_options.hpp>
0028 
0029 namespace boost {
0030 namespace asio {
0031 
0032 #if !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL)
0033 #define BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL
0034 
0035 // Forward declaration with defaulted arguments.
0036 template <typename Protocol, typename Executor = any_io_executor>
0037 class basic_raw_socket;
0038 
0039 #endif // !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL)
0040 
0041 /// Provides raw-oriented socket functionality.
0042 /**
0043  * The basic_raw_socket class template provides asynchronous and blocking
0044  * raw-oriented socket functionality.
0045  *
0046  * @par Thread Safety
0047  * @e Distinct @e objects: Safe.@n
0048  * @e Shared @e objects: Unsafe.
0049  *
0050  * Synchronous @c send, @c send_to, @c receive, @c receive_from, @c connect,
0051  * and @c shutdown operations are thread safe with respect to each other, if
0052  * the underlying operating system calls are also thread safe. This means that
0053  * it is permitted to perform concurrent calls to these synchronous operations
0054  * on a single socket object. Other synchronous operations, such as @c open or
0055  * @c close, are not thread safe.
0056  */
0057 template <typename Protocol, typename Executor>
0058 class basic_raw_socket
0059   : public basic_socket<Protocol, Executor>
0060 {
0061 private:
0062   class initiate_async_send;
0063   class initiate_async_send_to;
0064   class initiate_async_receive;
0065   class initiate_async_receive_from;
0066 
0067 public:
0068   /// The type of the executor associated with the object.
0069   typedef Executor executor_type;
0070 
0071   /// Rebinds the socket type to another executor.
0072   template <typename Executor1>
0073   struct rebind_executor
0074   {
0075     /// The socket type when rebound to the specified executor.
0076     typedef basic_raw_socket<Protocol, Executor1> other;
0077   };
0078 
0079   /// The native representation of a socket.
0080 #if defined(GENERATING_DOCUMENTATION)
0081   typedef implementation_defined native_handle_type;
0082 #else
0083   typedef typename basic_socket<Protocol,
0084     Executor>::native_handle_type native_handle_type;
0085 #endif
0086 
0087   /// The protocol type.
0088   typedef Protocol protocol_type;
0089 
0090   /// The endpoint type.
0091   typedef typename Protocol::endpoint endpoint_type;
0092 
0093   /// Construct a basic_raw_socket without opening it.
0094   /**
0095    * This constructor creates a raw socket without opening it. The open()
0096    * function must be called before data can be sent or received on the socket.
0097    *
0098    * @param ex The I/O executor that the socket will use, by default, to
0099    * dispatch handlers for any asynchronous operations performed on the socket.
0100    */
0101   explicit basic_raw_socket(const executor_type& ex)
0102     : basic_socket<Protocol, Executor>(ex)
0103   {
0104   }
0105 
0106   /// Construct a basic_raw_socket without opening it.
0107   /**
0108    * This constructor creates a raw socket without opening it. The open()
0109    * function must be called before data can be sent or received on the socket.
0110    *
0111    * @param context An execution context which provides the I/O executor that
0112    * the socket will use, by default, to dispatch handlers for any asynchronous
0113    * operations performed on the socket.
0114    */
0115   template <typename ExecutionContext>
0116   explicit basic_raw_socket(ExecutionContext& context,
0117       constraint_t<
0118         is_convertible<ExecutionContext&, execution_context&>::value
0119       > = 0)
0120     : basic_socket<Protocol, Executor>(context)
0121   {
0122   }
0123 
0124   /// Construct and open a basic_raw_socket.
0125   /**
0126    * This constructor creates and opens a raw socket.
0127    *
0128    * @param ex The I/O executor that the socket will use, by default, to
0129    * dispatch handlers for any asynchronous operations performed on the socket.
0130    *
0131    * @param protocol An object specifying protocol parameters to be used.
0132    *
0133    * @throws boost::system::system_error Thrown on failure.
0134    */
0135   basic_raw_socket(const executor_type& ex, const protocol_type& protocol)
0136     : basic_socket<Protocol, Executor>(ex, protocol)
0137   {
0138   }
0139 
0140   /// Construct and open a basic_raw_socket.
0141   /**
0142    * This constructor creates and opens a raw socket.
0143    *
0144    * @param context An execution context which provides the I/O executor that
0145    * the socket will use, by default, to dispatch handlers for any asynchronous
0146    * operations performed on the socket.
0147    *
0148    * @param protocol An object specifying protocol parameters to be used.
0149    *
0150    * @throws boost::system::system_error Thrown on failure.
0151    */
0152   template <typename ExecutionContext>
0153   basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,
0154       constraint_t<
0155         is_convertible<ExecutionContext&, execution_context&>::value,
0156         defaulted_constraint
0157       > = defaulted_constraint())
0158     : basic_socket<Protocol, Executor>(context, protocol)
0159   {
0160   }
0161 
0162   /// Construct a basic_raw_socket, opening it and binding it to the given
0163   /// local endpoint.
0164   /**
0165    * This constructor creates a raw socket and automatically opens it bound
0166    * to the specified endpoint on the local machine. The protocol used is the
0167    * protocol associated with the given endpoint.
0168    *
0169    * @param ex The I/O executor that the socket will use, by default, to
0170    * dispatch handlers for any asynchronous operations performed on the socket.
0171    *
0172    * @param endpoint An endpoint on the local machine to which the raw
0173    * socket will be bound.
0174    *
0175    * @throws boost::system::system_error Thrown on failure.
0176    */
0177   basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint)
0178     : basic_socket<Protocol, Executor>(ex, endpoint)
0179   {
0180   }
0181 
0182   /// Construct a basic_raw_socket, opening it and binding it to the given
0183   /// local endpoint.
0184   /**
0185    * This constructor creates a raw socket and automatically opens it bound
0186    * to the specified endpoint on the local machine. The protocol used is the
0187    * protocol associated with the given endpoint.
0188    *
0189    * @param context An execution context which provides the I/O executor that
0190    * the socket will use, by default, to dispatch handlers for any asynchronous
0191    * operations performed on the socket.
0192    *
0193    * @param endpoint An endpoint on the local machine to which the raw
0194    * socket will be bound.
0195    *
0196    * @throws boost::system::system_error Thrown on failure.
0197    */
0198   template <typename ExecutionContext>
0199   basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,
0200       constraint_t<
0201         is_convertible<ExecutionContext&, execution_context&>::value
0202       > = 0)
0203     : basic_socket<Protocol, Executor>(context, endpoint)
0204   {
0205   }
0206 
0207   /// Construct a basic_raw_socket on an existing native socket.
0208   /**
0209    * This constructor creates a raw socket object to hold an existing
0210    * native socket.
0211    *
0212    * @param ex The I/O executor that the socket will use, by default, to
0213    * dispatch handlers for any asynchronous operations performed on the socket.
0214    *
0215    * @param protocol An object specifying protocol parameters to be used.
0216    *
0217    * @param native_socket The new underlying socket implementation.
0218    *
0219    * @throws boost::system::system_error Thrown on failure.
0220    */
0221   basic_raw_socket(const executor_type& ex,
0222       const protocol_type& protocol, const native_handle_type& native_socket)
0223     : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
0224   {
0225   }
0226 
0227   /// Construct a basic_raw_socket on an existing native socket.
0228   /**
0229    * This constructor creates a raw socket object to hold an existing
0230    * native socket.
0231    *
0232    * @param context An execution context which provides the I/O executor that
0233    * the socket will use, by default, to dispatch handlers for any asynchronous
0234    * operations performed on the socket.
0235    *
0236    * @param protocol An object specifying protocol parameters to be used.
0237    *
0238    * @param native_socket The new underlying socket implementation.
0239    *
0240    * @throws boost::system::system_error Thrown on failure.
0241    */
0242   template <typename ExecutionContext>
0243   basic_raw_socket(ExecutionContext& context,
0244       const protocol_type& protocol, const native_handle_type& native_socket,
0245       constraint_t<
0246         is_convertible<ExecutionContext&, execution_context&>::value
0247       > = 0)
0248     : basic_socket<Protocol, Executor>(context, protocol, native_socket)
0249   {
0250   }
0251 
0252   /// Move-construct a basic_raw_socket from another.
0253   /**
0254    * This constructor moves a raw socket from one object to another.
0255    *
0256    * @param other The other basic_raw_socket object from which the move
0257    * will occur.
0258    *
0259    * @note Following the move, the moved-from object is in the same state as if
0260    * constructed using the @c basic_raw_socket(const executor_type&)
0261    * constructor.
0262    */
0263   basic_raw_socket(basic_raw_socket&& other) noexcept
0264     : basic_socket<Protocol, Executor>(std::move(other))
0265   {
0266   }
0267 
0268   /// Move-assign a basic_raw_socket from another.
0269   /**
0270    * This assignment operator moves a raw socket from one object to another.
0271    *
0272    * @param other The other basic_raw_socket object from which the move
0273    * will occur.
0274    *
0275    * @note Following the move, the moved-from object is in the same state as if
0276    * constructed using the @c basic_raw_socket(const executor_type&)
0277    * constructor.
0278    */
0279   basic_raw_socket& operator=(basic_raw_socket&& other)
0280   {
0281     basic_socket<Protocol, Executor>::operator=(std::move(other));
0282     return *this;
0283   }
0284 
0285   /// Move-construct a basic_raw_socket from a socket of another protocol
0286   /// type.
0287   /**
0288    * This constructor moves a raw socket from one object to another.
0289    *
0290    * @param other The other basic_raw_socket object from which the move
0291    * will occur.
0292    *
0293    * @note Following the move, the moved-from object is in the same state as if
0294    * constructed using the @c basic_raw_socket(const executor_type&)
0295    * constructor.
0296    */
0297   template <typename Protocol1, typename Executor1>
0298   basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,
0299       constraint_t<
0300         is_convertible<Protocol1, Protocol>::value
0301           && is_convertible<Executor1, Executor>::value
0302       > = 0)
0303     : basic_socket<Protocol, Executor>(std::move(other))
0304   {
0305   }
0306 
0307   /// Move-assign a basic_raw_socket from a socket of another protocol type.
0308   /**
0309    * This assignment operator moves a raw socket from one object to another.
0310    *
0311    * @param other The other basic_raw_socket object from which the move
0312    * will occur.
0313    *
0314    * @note Following the move, the moved-from object is in the same state as if
0315    * constructed using the @c basic_raw_socket(const executor_type&)
0316    * constructor.
0317    */
0318   template <typename Protocol1, typename Executor1>
0319   constraint_t<
0320     is_convertible<Protocol1, Protocol>::value
0321       && is_convertible<Executor1, Executor>::value,
0322     basic_raw_socket&
0323   > operator=(basic_raw_socket<Protocol1, Executor1>&& other)
0324   {
0325     basic_socket<Protocol, Executor>::operator=(std::move(other));
0326     return *this;
0327   }
0328 
0329   /// Destroys the socket.
0330   /**
0331    * This function destroys the socket, cancelling any outstanding asynchronous
0332    * operations associated with the socket as if by calling @c cancel.
0333    */
0334   ~basic_raw_socket()
0335   {
0336   }
0337 
0338   /// Send some data on a connected socket.
0339   /**
0340    * This function is used to send data on the raw socket. The function call
0341    * will block until the data has been sent successfully or an error occurs.
0342    *
0343    * @param buffers One ore more data buffers to be sent on the socket.
0344    *
0345    * @returns The number of bytes sent.
0346    *
0347    * @throws boost::system::system_error Thrown on failure.
0348    *
0349    * @note The send operation can only be used with a connected socket. Use
0350    * the send_to function to send data on an unconnected raw socket.
0351    *
0352    * @par Example
0353    * To send a single data buffer use the @ref buffer function as follows:
0354    * @code socket.send(boost::asio::buffer(data, size)); @endcode
0355    * See the @ref buffer documentation for information on sending multiple
0356    * buffers in one go, and how to use it with arrays, boost::array or
0357    * std::vector.
0358    */
0359   template <typename ConstBufferSequence>
0360   std::size_t send(const ConstBufferSequence& buffers)
0361   {
0362     boost::system::error_code ec;
0363     std::size_t s = this->impl_.get_service().send(
0364         this->impl_.get_implementation(), buffers, 0, ec);
0365     boost::asio::detail::throw_error(ec, "send");
0366     return s;
0367   }
0368 
0369   /// Send some data on a connected socket.
0370   /**
0371    * This function is used to send data on the raw socket. The function call
0372    * will block until the data has been sent successfully or an error occurs.
0373    *
0374    * @param buffers One ore more data buffers to be sent on the socket.
0375    *
0376    * @param flags Flags specifying how the send call is to be made.
0377    *
0378    * @returns The number of bytes sent.
0379    *
0380    * @throws boost::system::system_error Thrown on failure.
0381    *
0382    * @note The send operation can only be used with a connected socket. Use
0383    * the send_to function to send data on an unconnected raw socket.
0384    */
0385   template <typename ConstBufferSequence>
0386   std::size_t send(const ConstBufferSequence& buffers,
0387       socket_base::message_flags flags)
0388   {
0389     boost::system::error_code ec;
0390     std::size_t s = this->impl_.get_service().send(
0391         this->impl_.get_implementation(), buffers, flags, ec);
0392     boost::asio::detail::throw_error(ec, "send");
0393     return s;
0394   }
0395 
0396   /// Send some data on a connected socket.
0397   /**
0398    * This function is used to send data on the raw socket. The function call
0399    * will block until the data has been sent successfully or an error occurs.
0400    *
0401    * @param buffers One or more data buffers to be sent on the socket.
0402    *
0403    * @param flags Flags specifying how the send call is to be made.
0404    *
0405    * @param ec Set to indicate what error occurred, if any.
0406    *
0407    * @returns The number of bytes sent.
0408    *
0409    * @note The send operation can only be used with a connected socket. Use
0410    * the send_to function to send data on an unconnected raw socket.
0411    */
0412   template <typename ConstBufferSequence>
0413   std::size_t send(const ConstBufferSequence& buffers,
0414       socket_base::message_flags flags, boost::system::error_code& ec)
0415   {
0416     return this->impl_.get_service().send(
0417         this->impl_.get_implementation(), buffers, flags, ec);
0418   }
0419 
0420   /// Start an asynchronous send on a connected socket.
0421   /**
0422    * This function is used to asynchronously send data on the raw socket. It is
0423    * an initiating function for an @ref asynchronous_operation, and always
0424    * returns immediately.
0425    *
0426    * @param buffers One or more data buffers to be sent on the socket. Although
0427    * the buffers object may be copied as necessary, ownership of the underlying
0428    * memory blocks is retained by the caller, which must guarantee that they
0429    * remain valid until the completion handler is called.
0430    *
0431    * @param token The @ref completion_token that will be used to produce a
0432    * completion handler, which will be called when the send completes.
0433    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0434    * @ref yield_context, or a function object with the correct completion
0435    * signature. The function signature of the completion handler must be:
0436    * @code void handler(
0437    *   const boost::system::error_code& error, // Result of operation.
0438    *   std::size_t bytes_transferred // Number of bytes sent.
0439    * ); @endcode
0440    * Regardless of whether the asynchronous operation completes immediately or
0441    * not, the completion handler will not be invoked from within this function.
0442    * On immediate completion, invocation of the handler will be performed in a
0443    * manner equivalent to using boost::asio::post().
0444    *
0445    * @par Completion Signature
0446    * @code void(boost::system::error_code, std::size_t) @endcode
0447    *
0448    * @note The async_send operation can only be used with a connected socket.
0449    * Use the async_send_to function to send data on an unconnected raw
0450    * socket.
0451    *
0452    * @par Example
0453    * To send a single data buffer use the @ref buffer function as follows:
0454    * @code
0455    * socket.async_send(boost::asio::buffer(data, size), handler);
0456    * @endcode
0457    * See the @ref buffer documentation for information on sending multiple
0458    * buffers in one go, and how to use it with arrays, boost::array or
0459    * std::vector.
0460    *
0461    * @par Per-Operation Cancellation
0462    * On POSIX or Windows operating systems, this asynchronous operation supports
0463    * cancellation for the following boost::asio::cancellation_type values:
0464    *
0465    * @li @c cancellation_type::terminal
0466    *
0467    * @li @c cancellation_type::partial
0468    *
0469    * @li @c cancellation_type::total
0470    */
0471   template <typename ConstBufferSequence,
0472       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0473         std::size_t)) WriteToken = default_completion_token_t<executor_type>>
0474   auto async_send(const ConstBufferSequence& buffers,
0475       WriteToken&& token = default_completion_token_t<executor_type>())
0476     -> decltype(
0477       async_initiate<WriteToken,
0478         void (boost::system::error_code, std::size_t)>(
0479           declval<initiate_async_send>(), token,
0480           buffers, socket_base::message_flags(0)))
0481   {
0482     return async_initiate<WriteToken,
0483       void (boost::system::error_code, std::size_t)>(
0484         initiate_async_send(this), token,
0485         buffers, socket_base::message_flags(0));
0486   }
0487 
0488   /// Start an asynchronous send on a connected socket.
0489   /**
0490    * This function is used to asynchronously send data on the raw socket. It is
0491    * an initiating function for an @ref asynchronous_operation, and always
0492    * returns immediately.
0493    *
0494    * @param buffers One or more data buffers to be sent on the socket. Although
0495    * the buffers object may be copied as necessary, ownership of the underlying
0496    * memory blocks is retained by the caller, which must guarantee that they
0497    * remain valid until the completion handler is called.
0498    *
0499    * @param flags Flags specifying how the send call is to be made.
0500    *
0501    * @param token The @ref completion_token that will be used to produce a
0502    * completion handler, which will be called when the send completes.
0503    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0504    * @ref yield_context, or a function object with the correct completion
0505    * signature. The function signature of the completion handler must be:
0506    * @code void handler(
0507    *   const boost::system::error_code& error, // Result of operation.
0508    *   std::size_t bytes_transferred // Number of bytes sent.
0509    * ); @endcode
0510    * Regardless of whether the asynchronous operation completes immediately or
0511    * not, the completion handler will not be invoked from within this function.
0512    * On immediate completion, invocation of the handler will be performed in a
0513    * manner equivalent to using boost::asio::post().
0514    *
0515    * @par Completion Signature
0516    * @code void(boost::system::error_code, std::size_t) @endcode
0517    *
0518    * @note The async_send operation can only be used with a connected socket.
0519    * Use the async_send_to function to send data on an unconnected raw
0520    * socket.
0521    *
0522    * @par Per-Operation Cancellation
0523    * On POSIX or Windows operating systems, this asynchronous operation supports
0524    * cancellation for the following boost::asio::cancellation_type values:
0525    *
0526    * @li @c cancellation_type::terminal
0527    *
0528    * @li @c cancellation_type::partial
0529    *
0530    * @li @c cancellation_type::total
0531    */
0532   template <typename ConstBufferSequence,
0533       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0534         std::size_t)) WriteToken = default_completion_token_t<executor_type>>
0535   auto async_send(const ConstBufferSequence& buffers,
0536       socket_base::message_flags flags,
0537       WriteToken&& token = default_completion_token_t<executor_type>())
0538     -> decltype(
0539       async_initiate<WriteToken,
0540         void (boost::system::error_code, std::size_t)>(
0541           declval<initiate_async_send>(), token, buffers, flags))
0542   {
0543     return async_initiate<WriteToken,
0544       void (boost::system::error_code, std::size_t)>(
0545         initiate_async_send(this), token, buffers, flags);
0546   }
0547 
0548   /// Send raw data to the specified endpoint.
0549   /**
0550    * This function is used to send raw data to the specified remote endpoint.
0551    * The function call will block until the data has been sent successfully or
0552    * an error occurs.
0553    *
0554    * @param buffers One or more data buffers to be sent to the remote endpoint.
0555    *
0556    * @param destination The remote endpoint to which the data will be sent.
0557    *
0558    * @returns The number of bytes sent.
0559    *
0560    * @throws boost::system::system_error Thrown on failure.
0561    *
0562    * @par Example
0563    * To send a single data buffer use the @ref buffer function as follows:
0564    * @code
0565    * boost::asio::ip::udp::endpoint destination(
0566    *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
0567    * socket.send_to(boost::asio::buffer(data, size), destination);
0568    * @endcode
0569    * See the @ref buffer documentation for information on sending multiple
0570    * buffers in one go, and how to use it with arrays, boost::array or
0571    * std::vector.
0572    */
0573   template <typename ConstBufferSequence>
0574   std::size_t send_to(const ConstBufferSequence& buffers,
0575       const endpoint_type& destination)
0576   {
0577     boost::system::error_code ec;
0578     std::size_t s = this->impl_.get_service().send_to(
0579         this->impl_.get_implementation(), buffers, destination, 0, ec);
0580     boost::asio::detail::throw_error(ec, "send_to");
0581     return s;
0582   }
0583 
0584   /// Send raw data to the specified endpoint.
0585   /**
0586    * This function is used to send raw data to the specified remote endpoint.
0587    * The function call will block until the data has been sent successfully or
0588    * an error occurs.
0589    *
0590    * @param buffers One or more data buffers to be sent to the remote endpoint.
0591    *
0592    * @param destination The remote endpoint to which the data will be sent.
0593    *
0594    * @param flags Flags specifying how the send call is to be made.
0595    *
0596    * @returns The number of bytes sent.
0597    *
0598    * @throws boost::system::system_error Thrown on failure.
0599    */
0600   template <typename ConstBufferSequence>
0601   std::size_t send_to(const ConstBufferSequence& buffers,
0602       const endpoint_type& destination, socket_base::message_flags flags)
0603   {
0604     boost::system::error_code ec;
0605     std::size_t s = this->impl_.get_service().send_to(
0606         this->impl_.get_implementation(), buffers, destination, flags, ec);
0607     boost::asio::detail::throw_error(ec, "send_to");
0608     return s;
0609   }
0610 
0611   /// Send raw data to the specified endpoint.
0612   /**
0613    * This function is used to send raw data to the specified remote endpoint.
0614    * The function call will block until the data has been sent successfully or
0615    * an error occurs.
0616    *
0617    * @param buffers One or more data buffers to be sent to the remote endpoint.
0618    *
0619    * @param destination The remote endpoint to which the data will be sent.
0620    *
0621    * @param flags Flags specifying how the send call is to be made.
0622    *
0623    * @param ec Set to indicate what error occurred, if any.
0624    *
0625    * @returns The number of bytes sent.
0626    */
0627   template <typename ConstBufferSequence>
0628   std::size_t send_to(const ConstBufferSequence& buffers,
0629       const endpoint_type& destination, socket_base::message_flags flags,
0630       boost::system::error_code& ec)
0631   {
0632     return this->impl_.get_service().send_to(this->impl_.get_implementation(),
0633         buffers, destination, flags, ec);
0634   }
0635 
0636   /// Start an asynchronous send.
0637   /**
0638    * This function is used to asynchronously send raw data to the specified
0639    * remote endpoint. It is an initiating function for an @ref
0640    * asynchronous_operation, and always returns immediately.
0641    *
0642    * @param buffers One or more data buffers to be sent to the remote endpoint.
0643    * Although the buffers object may be copied as necessary, ownership of the
0644    * underlying memory blocks is retained by the caller, which must guarantee
0645    * that they remain valid until the completion handler is called.
0646    *
0647    * @param destination The remote endpoint to which the data will be sent.
0648    * Copies will be made of the endpoint as required.
0649    *
0650    * @param token The @ref completion_token that will be used to produce a
0651    * completion handler, which will be called when the send completes.
0652    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0653    * @ref yield_context, or a function object with the correct completion
0654    * signature. The function signature of the completion handler must be:
0655    * @code void handler(
0656    *   const boost::system::error_code& error, // Result of operation.
0657    *   std::size_t bytes_transferred // Number of bytes sent.
0658    * ); @endcode
0659    * Regardless of whether the asynchronous operation completes immediately or
0660    * not, the completion handler will not be invoked from within this function.
0661    * On immediate completion, invocation of the handler will be performed in a
0662    * manner equivalent to using boost::asio::post().
0663    *
0664    * @par Completion Signature
0665    * @code void(boost::system::error_code, std::size_t) @endcode
0666    *
0667    * @par Example
0668    * To send a single data buffer use the @ref buffer function as follows:
0669    * @code
0670    * boost::asio::ip::udp::endpoint destination(
0671    *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
0672    * socket.async_send_to(
0673    *     boost::asio::buffer(data, size), destination, handler);
0674    * @endcode
0675    * See the @ref buffer documentation for information on sending multiple
0676    * buffers in one go, and how to use it with arrays, boost::array or
0677    * std::vector.
0678    *
0679    * @par Per-Operation Cancellation
0680    * On POSIX or Windows operating systems, this asynchronous operation supports
0681    * cancellation for the following boost::asio::cancellation_type values:
0682    *
0683    * @li @c cancellation_type::terminal
0684    *
0685    * @li @c cancellation_type::partial
0686    *
0687    * @li @c cancellation_type::total
0688    */
0689   template <typename ConstBufferSequence,
0690       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0691         std::size_t)) WriteToken = default_completion_token_t<executor_type>>
0692   auto async_send_to(const ConstBufferSequence& buffers,
0693       const endpoint_type& destination,
0694       WriteToken&& token = default_completion_token_t<executor_type>())
0695     -> decltype(
0696       async_initiate<WriteToken,
0697         void (boost::system::error_code, std::size_t)>(
0698           declval<initiate_async_send_to>(), token, buffers,
0699           destination, socket_base::message_flags(0)))
0700   {
0701     return async_initiate<WriteToken,
0702       void (boost::system::error_code, std::size_t)>(
0703         initiate_async_send_to(this), token, buffers,
0704         destination, socket_base::message_flags(0));
0705   }
0706 
0707   /// Start an asynchronous send.
0708   /**
0709    * This function is used to asynchronously send raw data to the specified
0710    * remote endpoint. It is an initiating function for an @ref
0711    * asynchronous_operation, and always returns immediately.
0712    *
0713    * @param buffers One or more data buffers to be sent to the remote endpoint.
0714    * Although the buffers object may be copied as necessary, ownership of the
0715    * underlying memory blocks is retained by the caller, which must guarantee
0716    * that they remain valid until the completion handler is called.
0717    *
0718    * @param flags Flags specifying how the send call is to be made.
0719    *
0720    * @param destination The remote endpoint to which the data will be sent.
0721    * Copies will be made of the endpoint as required.
0722    *
0723    * @param token The @ref completion_token that will be used to produce a
0724    * completion handler, which will be called when the send completes.
0725    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0726    * @ref yield_context, or a function object with the correct completion
0727    * signature. The function signature of the completion handler must be:
0728    * @code void handler(
0729    *   const boost::system::error_code& error, // Result of operation.
0730    *   std::size_t bytes_transferred // Number of bytes sent.
0731    * ); @endcode
0732    * Regardless of whether the asynchronous operation completes immediately or
0733    * not, the completion handler will not be invoked from within this function.
0734    * On immediate completion, invocation of the handler will be performed in a
0735    * manner equivalent to using boost::asio::post().
0736    *
0737    * @par Completion Signature
0738    * @code void(boost::system::error_code, std::size_t) @endcode
0739    *
0740    * @par Per-Operation Cancellation
0741    * On POSIX or Windows operating systems, this asynchronous operation supports
0742    * cancellation for the following boost::asio::cancellation_type values:
0743    *
0744    * @li @c cancellation_type::terminal
0745    *
0746    * @li @c cancellation_type::partial
0747    *
0748    * @li @c cancellation_type::total
0749    */
0750   template <typename ConstBufferSequence,
0751       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0752         std::size_t)) WriteToken = default_completion_token_t<executor_type>>
0753   auto async_send_to(const ConstBufferSequence& buffers,
0754       const endpoint_type& destination, socket_base::message_flags flags,
0755       WriteToken&& token = default_completion_token_t<executor_type>())
0756     -> decltype(
0757       async_initiate<WriteToken,
0758         void (boost::system::error_code, std::size_t)>(
0759           declval<initiate_async_send_to>(), token,
0760           buffers, destination, flags))
0761   {
0762     return async_initiate<WriteToken,
0763       void (boost::system::error_code, std::size_t)>(
0764         initiate_async_send_to(this), token,
0765         buffers, destination, flags);
0766   }
0767 
0768   /// Receive some data on a connected socket.
0769   /**
0770    * This function is used to receive data on the raw socket. The function
0771    * call will block until data has been received successfully or an error
0772    * occurs.
0773    *
0774    * @param buffers One or more buffers into which the data will be received.
0775    *
0776    * @returns The number of bytes received.
0777    *
0778    * @throws boost::system::system_error Thrown on failure.
0779    *
0780    * @note The receive operation can only be used with a connected socket. Use
0781    * the receive_from function to receive data on an unconnected raw
0782    * socket.
0783    *
0784    * @par Example
0785    * To receive into a single data buffer use the @ref buffer function as
0786    * follows:
0787    * @code socket.receive(boost::asio::buffer(data, size)); @endcode
0788    * See the @ref buffer documentation for information on receiving into
0789    * multiple buffers in one go, and how to use it with arrays, boost::array or
0790    * std::vector.
0791    */
0792   template <typename MutableBufferSequence>
0793   std::size_t receive(const MutableBufferSequence& buffers)
0794   {
0795     boost::system::error_code ec;
0796     std::size_t s = this->impl_.get_service().receive(
0797         this->impl_.get_implementation(), buffers, 0, ec);
0798     boost::asio::detail::throw_error(ec, "receive");
0799     return s;
0800   }
0801 
0802   /// Receive some data on a connected socket.
0803   /**
0804    * This function is used to receive data on the raw socket. The function
0805    * call will block until data has been received successfully or an error
0806    * occurs.
0807    *
0808    * @param buffers One or more buffers into which the data will be received.
0809    *
0810    * @param flags Flags specifying how the receive call is to be made.
0811    *
0812    * @returns The number of bytes received.
0813    *
0814    * @throws boost::system::system_error Thrown on failure.
0815    *
0816    * @note The receive operation can only be used with a connected socket. Use
0817    * the receive_from function to receive data on an unconnected raw
0818    * socket.
0819    */
0820   template <typename MutableBufferSequence>
0821   std::size_t receive(const MutableBufferSequence& buffers,
0822       socket_base::message_flags flags)
0823   {
0824     boost::system::error_code ec;
0825     std::size_t s = this->impl_.get_service().receive(
0826         this->impl_.get_implementation(), buffers, flags, ec);
0827     boost::asio::detail::throw_error(ec, "receive");
0828     return s;
0829   }
0830 
0831   /// Receive some data on a connected socket.
0832   /**
0833    * This function is used to receive data on the raw socket. The function
0834    * call will block until data has been received successfully or an error
0835    * occurs.
0836    *
0837    * @param buffers One or more buffers into which the data will be received.
0838    *
0839    * @param flags Flags specifying how the receive call is to be made.
0840    *
0841    * @param ec Set to indicate what error occurred, if any.
0842    *
0843    * @returns The number of bytes received.
0844    *
0845    * @note The receive operation can only be used with a connected socket. Use
0846    * the receive_from function to receive data on an unconnected raw
0847    * socket.
0848    */
0849   template <typename MutableBufferSequence>
0850   std::size_t receive(const MutableBufferSequence& buffers,
0851       socket_base::message_flags flags, boost::system::error_code& ec)
0852   {
0853     return this->impl_.get_service().receive(
0854         this->impl_.get_implementation(), buffers, flags, ec);
0855   }
0856 
0857   /// Start an asynchronous receive on a connected socket.
0858   /**
0859    * This function is used to asynchronously receive data from the raw
0860    * socket. It is an initiating function for an @ref asynchronous_operation,
0861    * and always returns immediately.
0862    *
0863    * @param buffers One or more buffers into which the data will be received.
0864    * Although the buffers object may be copied as necessary, ownership of the
0865    * underlying memory blocks is retained by the caller, which must guarantee
0866    * that they remain valid until the completion handler is called.
0867    *
0868    * @param token The @ref completion_token that will be used to produce a
0869    * completion handler, which will be called when the receive completes.
0870    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0871    * @ref yield_context, or a function object with the correct completion
0872    * signature. The function signature of the completion handler must be:
0873    * @code void handler(
0874    *   const boost::system::error_code& error, // Result of operation.
0875    *   std::size_t bytes_transferred // Number of bytes received.
0876    * ); @endcode
0877    * Regardless of whether the asynchronous operation completes immediately or
0878    * not, the completion handler will not be invoked from within this function.
0879    * On immediate completion, invocation of the handler will be performed in a
0880    * manner equivalent to using boost::asio::post().
0881    *
0882    * @par Completion Signature
0883    * @code void(boost::system::error_code, std::size_t) @endcode
0884    *
0885    * @note The async_receive operation can only be used with a connected socket.
0886    * Use the async_receive_from function to receive data on an unconnected
0887    * raw socket.
0888    *
0889    * @par Example
0890    * To receive into a single data buffer use the @ref buffer function as
0891    * follows:
0892    * @code
0893    * socket.async_receive(boost::asio::buffer(data, size), handler);
0894    * @endcode
0895    * See the @ref buffer documentation for information on receiving into
0896    * multiple buffers in one go, and how to use it with arrays, boost::array or
0897    * std::vector.
0898    *
0899    * @par Per-Operation Cancellation
0900    * On POSIX or Windows operating systems, this asynchronous operation supports
0901    * cancellation for the following boost::asio::cancellation_type values:
0902    *
0903    * @li @c cancellation_type::terminal
0904    *
0905    * @li @c cancellation_type::partial
0906    *
0907    * @li @c cancellation_type::total
0908    */
0909   template <typename MutableBufferSequence,
0910       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0911         std::size_t)) ReadToken = default_completion_token_t<executor_type>>
0912   auto async_receive(const MutableBufferSequence& buffers,
0913       ReadToken&& token = default_completion_token_t<executor_type>())
0914     -> decltype(
0915       async_initiate<ReadToken,
0916         void (boost::system::error_code, std::size_t)>(
0917           declval<initiate_async_receive>(), token,
0918           buffers, socket_base::message_flags(0)))
0919   {
0920     return async_initiate<ReadToken,
0921       void (boost::system::error_code, std::size_t)>(
0922         initiate_async_receive(this), token,
0923         buffers, socket_base::message_flags(0));
0924   }
0925 
0926   /// Start an asynchronous receive on a connected socket.
0927   /**
0928    * This function is used to asynchronously receive data from the raw
0929    * socket. It is an initiating function for an @ref asynchronous_operation,
0930    * and always returns immediately.
0931    *
0932    * @param buffers One or more buffers into which the data will be received.
0933    * Although the buffers object may be copied as necessary, ownership of the
0934    * underlying memory blocks is retained by the caller, which must guarantee
0935    * that they remain valid until the completion handler is called.
0936    *
0937    * @param flags Flags specifying how the receive call is to be made.
0938    *
0939    * @param token The @ref completion_token that will be used to produce a
0940    * completion handler, which will be called when the receive completes.
0941    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0942    * @ref yield_context, or a function object with the correct completion
0943    * signature. The function signature of the completion handler must be:
0944    * @code void handler(
0945    *   const boost::system::error_code& error, // Result of operation.
0946    *   std::size_t bytes_transferred // Number of bytes received.
0947    * ); @endcode
0948    * Regardless of whether the asynchronous operation completes immediately or
0949    * not, the completion handler will not be invoked from within this function.
0950    * On immediate completion, invocation of the handler will be performed in a
0951    * manner equivalent to using boost::asio::post().
0952    *
0953    * @par Completion Signature
0954    * @code void(boost::system::error_code, std::size_t) @endcode
0955    *
0956    * @note The async_receive operation can only be used with a connected socket.
0957    * Use the async_receive_from function to receive data on an unconnected
0958    * raw socket.
0959    *
0960    * @par Per-Operation Cancellation
0961    * On POSIX or Windows operating systems, this asynchronous operation supports
0962    * cancellation for the following boost::asio::cancellation_type values:
0963    *
0964    * @li @c cancellation_type::terminal
0965    *
0966    * @li @c cancellation_type::partial
0967    *
0968    * @li @c cancellation_type::total
0969    */
0970   template <typename MutableBufferSequence,
0971       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0972         std::size_t)) ReadToken
0973           = default_completion_token_t<executor_type>>
0974   auto async_receive(const MutableBufferSequence& buffers,
0975       socket_base::message_flags flags,
0976       ReadToken&& token = default_completion_token_t<executor_type>())
0977     -> decltype(
0978       async_initiate<ReadToken,
0979         void (boost::system::error_code, std::size_t)>(
0980           declval<initiate_async_receive>(), token, buffers, flags))
0981   {
0982     return async_initiate<ReadToken,
0983       void (boost::system::error_code, std::size_t)>(
0984         initiate_async_receive(this), token, buffers, flags);
0985   }
0986 
0987   /// Receive raw data with the endpoint of the sender.
0988   /**
0989    * This function is used to receive raw data. The function call will block
0990    * until data has been received successfully or an error occurs.
0991    *
0992    * @param buffers One or more buffers into which the data will be received.
0993    *
0994    * @param sender_endpoint An endpoint object that receives the endpoint of
0995    * the remote sender of the data.
0996    *
0997    * @returns The number of bytes received.
0998    *
0999    * @throws boost::system::system_error Thrown on failure.
1000    *
1001    * @par Example
1002    * To receive into a single data buffer use the @ref buffer function as
1003    * follows:
1004    * @code
1005    * boost::asio::ip::udp::endpoint sender_endpoint;
1006    * socket.receive_from(
1007    *     boost::asio::buffer(data, size), sender_endpoint);
1008    * @endcode
1009    * See the @ref buffer documentation for information on receiving into
1010    * multiple buffers in one go, and how to use it with arrays, boost::array or
1011    * std::vector.
1012    */
1013   template <typename MutableBufferSequence>
1014   std::size_t receive_from(const MutableBufferSequence& buffers,
1015       endpoint_type& sender_endpoint)
1016   {
1017     boost::system::error_code ec;
1018     std::size_t s = this->impl_.get_service().receive_from(
1019         this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
1020     boost::asio::detail::throw_error(ec, "receive_from");
1021     return s;
1022   }
1023   
1024   /// Receive raw data with the endpoint of the sender.
1025   /**
1026    * This function is used to receive raw data. The function call will block
1027    * until data has been received successfully or an error occurs.
1028    *
1029    * @param buffers One or more buffers into which the data will be received.
1030    *
1031    * @param sender_endpoint An endpoint object that receives the endpoint of
1032    * the remote sender of the data.
1033    *
1034    * @param flags Flags specifying how the receive call is to be made.
1035    *
1036    * @returns The number of bytes received.
1037    *
1038    * @throws boost::system::system_error Thrown on failure.
1039    */
1040   template <typename MutableBufferSequence>
1041   std::size_t receive_from(const MutableBufferSequence& buffers,
1042       endpoint_type& sender_endpoint, socket_base::message_flags flags)
1043   {
1044     boost::system::error_code ec;
1045     std::size_t s = this->impl_.get_service().receive_from(
1046         this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
1047     boost::asio::detail::throw_error(ec, "receive_from");
1048     return s;
1049   }
1050   
1051   /// Receive raw data with the endpoint of the sender.
1052   /**
1053    * This function is used to receive raw data. The function call will block
1054    * until data has been received successfully or an error occurs.
1055    *
1056    * @param buffers One or more buffers into which the data will be received.
1057    *
1058    * @param sender_endpoint An endpoint object that receives the endpoint of
1059    * the remote sender of the data.
1060    *
1061    * @param flags Flags specifying how the receive call is to be made.
1062    *
1063    * @param ec Set to indicate what error occurred, if any.
1064    *
1065    * @returns The number of bytes received.
1066    */
1067   template <typename MutableBufferSequence>
1068   std::size_t receive_from(const MutableBufferSequence& buffers,
1069       endpoint_type& sender_endpoint, socket_base::message_flags flags,
1070       boost::system::error_code& ec)
1071   {
1072     return this->impl_.get_service().receive_from(
1073         this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
1074   }
1075 
1076   /// Start an asynchronous receive.
1077   /**
1078    * This function is used to asynchronously receive raw data. It is an
1079    * initiating function for an @ref asynchronous_operation, and always returns
1080    * immediately.
1081    *
1082    * @param buffers One or more buffers into which the data will be received.
1083    * Although the buffers object may be copied as necessary, ownership of the
1084    * underlying memory blocks is retained by the caller, which must guarantee
1085    * that they remain valid until the completion handler is called.
1086    *
1087    * @param sender_endpoint An endpoint object that receives the endpoint of
1088    * the remote sender of the data. Ownership of the sender_endpoint object
1089    * is retained by the caller, which must guarantee that it is valid until the
1090    * completion handler is called.
1091    *
1092    * @param token The @ref completion_token that will be used to produce a
1093    * completion handler, which will be called when the receive completes.
1094    * Potential completion tokens include @ref use_future, @ref use_awaitable,
1095    * @ref yield_context, or a function object with the correct completion
1096    * signature. The function signature of the completion handler must be:
1097    * @code void handler(
1098    *   const boost::system::error_code& error, // Result of operation.
1099    *   std::size_t bytes_transferred // Number of bytes received.
1100    * ); @endcode
1101    * Regardless of whether the asynchronous operation completes immediately or
1102    * not, the completion handler will not be invoked from within this function.
1103    * On immediate completion, invocation of the handler will be performed in a
1104    * manner equivalent to using boost::asio::post().
1105    *
1106    * @par Completion Signature
1107    * @code void(boost::system::error_code, std::size_t) @endcode
1108    *
1109    * @par Example
1110    * To receive into a single data buffer use the @ref buffer function as
1111    * follows:
1112    * @code socket.async_receive_from(
1113    *     boost::asio::buffer(data, size), 0, sender_endpoint, handler); @endcode
1114    * See the @ref buffer documentation for information on receiving into
1115    * multiple buffers in one go, and how to use it with arrays, boost::array or
1116    * std::vector.
1117    *
1118    * @par Per-Operation Cancellation
1119    * On POSIX or Windows operating systems, this asynchronous operation supports
1120    * cancellation for the following boost::asio::cancellation_type values:
1121    *
1122    * @li @c cancellation_type::terminal
1123    *
1124    * @li @c cancellation_type::partial
1125    *
1126    * @li @c cancellation_type::total
1127    */
1128   template <typename MutableBufferSequence,
1129       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1130         std::size_t)) ReadToken = default_completion_token_t<executor_type>>
1131   auto async_receive_from(const MutableBufferSequence& buffers,
1132       endpoint_type& sender_endpoint,
1133       ReadToken&& token
1134         = default_completion_token_t<executor_type>())
1135     -> decltype(
1136       async_initiate<ReadToken,
1137         void (boost::system::error_code, std::size_t)>(
1138           declval<initiate_async_receive_from>(), token, buffers,
1139           &sender_endpoint, socket_base::message_flags(0)))
1140   {
1141     return async_initiate<ReadToken,
1142       void (boost::system::error_code, std::size_t)>(
1143         initiate_async_receive_from(this), token, buffers,
1144         &sender_endpoint, socket_base::message_flags(0));
1145   }
1146 
1147   /// Start an asynchronous receive.
1148   /**
1149    * This function is used to asynchronously receive raw data. It is an
1150    * initiating function for an @ref asynchronous_operation, and always returns
1151    * immediately.
1152    *
1153    * @param buffers One or more buffers into which the data will be received.
1154    * Although the buffers object may be copied as necessary, ownership of the
1155    * underlying memory blocks is retained by the caller, which must guarantee
1156    * that they remain valid until the completion handler is called.
1157    *
1158    * @param sender_endpoint An endpoint object that receives the endpoint of
1159    * the remote sender of the data. Ownership of the sender_endpoint object
1160    * is retained by the caller, which must guarantee that it is valid until the
1161    * completion handler is called.
1162    *
1163    * @param flags Flags specifying how the receive call is to be made.
1164    *
1165    * @param token The @ref completion_token that will be used to produce a
1166    * completion handler, which will be called when the receive completes.
1167    * Potential completion tokens include @ref use_future, @ref use_awaitable,
1168    * @ref yield_context, or a function object with the correct completion
1169    * signature. The function signature of the completion handler must be:
1170    * @code void handler(
1171    *   const boost::system::error_code& error, // Result of operation.
1172    *   std::size_t bytes_transferred // Number of bytes received.
1173    * ); @endcode
1174    * Regardless of whether the asynchronous operation completes immediately or
1175    * not, the completion handler will not be invoked from within this function.
1176    * On immediate completion, invocation of the handler will be performed in a
1177    * manner equivalent to using boost::asio::post().
1178    *
1179    * @par Completion Signature
1180    * @code void(boost::system::error_code, std::size_t) @endcode
1181    *
1182    * @par Per-Operation Cancellation
1183    * On POSIX or Windows operating systems, this asynchronous operation supports
1184    * cancellation for the following boost::asio::cancellation_type values:
1185    *
1186    * @li @c cancellation_type::terminal
1187    *
1188    * @li @c cancellation_type::partial
1189    *
1190    * @li @c cancellation_type::total
1191    */
1192   template <typename MutableBufferSequence,
1193       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1194         std::size_t)) ReadToken
1195           = default_completion_token_t<executor_type>>
1196   auto async_receive_from(const MutableBufferSequence& buffers,
1197       endpoint_type& sender_endpoint, socket_base::message_flags flags,
1198       ReadToken&& token = default_completion_token_t<executor_type>())
1199     -> decltype(
1200       async_initiate<ReadToken,
1201         void (boost::system::error_code, std::size_t)>(
1202           declval<initiate_async_receive_from>(), token,
1203           buffers, &sender_endpoint, flags))
1204   {
1205     return async_initiate<ReadToken,
1206       void (boost::system::error_code, std::size_t)>(
1207         initiate_async_receive_from(this), token,
1208         buffers, &sender_endpoint, flags);
1209   }
1210 
1211 private:
1212   // Disallow copying and assignment.
1213   basic_raw_socket(const basic_raw_socket&) = delete;
1214   basic_raw_socket& operator=(const basic_raw_socket&) = delete;
1215 
1216   class initiate_async_send
1217   {
1218   public:
1219     typedef Executor executor_type;
1220 
1221     explicit initiate_async_send(basic_raw_socket* self)
1222       : self_(self)
1223     {
1224     }
1225 
1226     const executor_type& get_executor() const noexcept
1227     {
1228       return self_->get_executor();
1229     }
1230 
1231     template <typename WriteHandler, typename ConstBufferSequence>
1232     void operator()(WriteHandler&& handler,
1233         const ConstBufferSequence& buffers,
1234         socket_base::message_flags flags) const
1235     {
1236       // If you get an error on the following line it means that your handler
1237       // does not meet the documented type requirements for a WriteHandler.
1238       BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
1239 
1240       detail::non_const_lvalue<WriteHandler> handler2(handler);
1241       self_->impl_.get_service().async_send(
1242           self_->impl_.get_implementation(), buffers, flags,
1243           handler2.value, self_->impl_.get_executor());
1244     }
1245 
1246   private:
1247     basic_raw_socket* self_;
1248   };
1249 
1250   class initiate_async_send_to
1251   {
1252   public:
1253     typedef Executor executor_type;
1254 
1255     explicit initiate_async_send_to(basic_raw_socket* self)
1256       : self_(self)
1257     {
1258     }
1259 
1260     const executor_type& get_executor() const noexcept
1261     {
1262       return self_->get_executor();
1263     }
1264 
1265     template <typename WriteHandler, typename ConstBufferSequence>
1266     void operator()(WriteHandler&& handler,
1267         const ConstBufferSequence& buffers, const endpoint_type& destination,
1268         socket_base::message_flags flags) const
1269     {
1270       // If you get an error on the following line it means that your handler
1271       // does not meet the documented type requirements for a WriteHandler.
1272       BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
1273 
1274       detail::non_const_lvalue<WriteHandler> handler2(handler);
1275       self_->impl_.get_service().async_send_to(
1276           self_->impl_.get_implementation(), buffers, destination,
1277           flags, handler2.value, self_->impl_.get_executor());
1278     }
1279 
1280   private:
1281     basic_raw_socket* self_;
1282   };
1283 
1284   class initiate_async_receive
1285   {
1286   public:
1287     typedef Executor executor_type;
1288 
1289     explicit initiate_async_receive(basic_raw_socket* self)
1290       : self_(self)
1291     {
1292     }
1293 
1294     const executor_type& get_executor() const noexcept
1295     {
1296       return self_->get_executor();
1297     }
1298 
1299     template <typename ReadHandler, typename MutableBufferSequence>
1300     void operator()(ReadHandler&& handler,
1301         const MutableBufferSequence& buffers,
1302         socket_base::message_flags flags) const
1303     {
1304       // If you get an error on the following line it means that your handler
1305       // does not meet the documented type requirements for a ReadHandler.
1306       BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
1307 
1308       detail::non_const_lvalue<ReadHandler> handler2(handler);
1309       self_->impl_.get_service().async_receive(
1310           self_->impl_.get_implementation(), buffers, flags,
1311           handler2.value, self_->impl_.get_executor());
1312     }
1313 
1314   private:
1315     basic_raw_socket* self_;
1316   };
1317 
1318   class initiate_async_receive_from
1319   {
1320   public:
1321     typedef Executor executor_type;
1322 
1323     explicit initiate_async_receive_from(basic_raw_socket* self)
1324       : self_(self)
1325     {
1326     }
1327 
1328     const executor_type& get_executor() const noexcept
1329     {
1330       return self_->get_executor();
1331     }
1332 
1333     template <typename ReadHandler, typename MutableBufferSequence>
1334     void operator()(ReadHandler&& handler,
1335         const MutableBufferSequence& buffers, endpoint_type* sender_endpoint,
1336         socket_base::message_flags flags) const
1337     {
1338       // If you get an error on the following line it means that your handler
1339       // does not meet the documented type requirements for a ReadHandler.
1340       BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
1341 
1342       detail::non_const_lvalue<ReadHandler> handler2(handler);
1343       self_->impl_.get_service().async_receive_from(
1344           self_->impl_.get_implementation(), buffers, *sender_endpoint,
1345           flags, handler2.value, self_->impl_.get_executor());
1346     }
1347 
1348   private:
1349     basic_raw_socket* self_;
1350   };
1351 };
1352 
1353 } // namespace asio
1354 } // namespace boost
1355 
1356 #include <boost/asio/detail/pop_options.hpp>
1357 
1358 #endif // BOOST_ASIO_BASIC_RAW_SOCKET_HPP