summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlutzbichler <52852266+lutzbichler@users.noreply.github.com>2022-03-15 07:15:43 +0100
committerGitHub <noreply@github.com>2022-03-15 07:15:43 +0100
commitb7a73c36b3392ea9aaa7272f4bbd955c7233297c (patch)
tree8c9c35c3c77c5b9454f1c3edb7875d16d87345de
parentcd170ace4d93cae0a550b44af744c7f9dd7d0f14 (diff)
parent3e90d6b40d3dead231444d652954d617c7985cc6 (diff)
downloadvSomeIP-b7a73c36b3392ea9aaa7272f4bbd955c7233297c.tar.gz
Merge pull request #318 from alexlarsson/boost-176-support
Support boost 1.76
-rw-r--r--CMakeLists.txt6
-rw-r--r--implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp1118
-rw-r--r--implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp2381
-rw-r--r--implementation/helper/1.76/boost/asio/basic_socket_ext.hpp1859
-rw-r--r--implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp1859
-rw-r--r--implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp996
-rw-r--r--implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp586
-rw-r--r--implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp588
-rw-r--r--implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp302
-rw-r--r--implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp302
-rw-r--r--implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp234
-rw-r--r--implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp307
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp162
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp162
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp153
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp148
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp144
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp145
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp524
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp524
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp508
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp508
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp43
-rw-r--r--implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp44
-rw-r--r--implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp62
-rw-r--r--implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp95
-rw-r--r--implementation/helper/1.76/boost/asio/ip/udp_ext.hpp115
-rw-r--r--implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp93
28 files changed, 13966 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 65148a5..645825c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -164,8 +164,10 @@ else()
endif()
message( STATUS "Using boost version: ${VSOMEIP_BOOST_VERSION}" )
-if (${VSOMEIP_BOOST_VERSION} GREATER 107400)
-message( ERROR "boost version ${VSOMEIP_BOOST_VERSION} is not (yet) supported. Latest supported version is 1.74.0" )
+if (${VSOMEIP_BOOST_VERSION} GREATER 107600)
+message( ERROR "boost version ${VSOMEIP_BOOST_VERSION} is not (yet) supported. Latest supported version is 1.76.0" )
+elseif(${VSOMEIP_BOOST_VERSION} GREATER 107500)
+set(VSOMEIP_BOOST_HELPER implementation/helper/1.76)
elseif(${VSOMEIP_BOOST_VERSION} GREATER 107300)
set(VSOMEIP_BOOST_HELPER implementation/helper/1.74)
elseif(${VSOMEIP_BOOST_VERSION} GREATER 106999)
diff --git a/implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp
new file mode 100644
index 0000000..49a4950
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp
@@ -0,0 +1,1118 @@
+//
+// basic_datagram_socket_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP
+#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/basic_socket_ext.hpp>
+#include <boost/asio/detail/handler_type_requirements_ext.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL)
+#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_datagram_socket_ext;
+
+#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL)
+
+/// Provides datagram-oriented socket functionality.
+/**
+ * The basic_datagram_socket class template provides asynchronous and blocking
+ * datagram-oriented socket functionality.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename Protocol, typename Executor>
+class basic_datagram_socket_ext
+ : public basic_socket_ext<Protocol, Executor>
+{
+public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// Rebinds the socket type to another executor.
+ template <typename Executor1>
+ struct rebind_executor
+ {
+ /// The socket type when rebound to the specified executor.
+ typedef basic_datagram_socket_ext<Protocol, Executor1> other;
+ };
+
+ /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef typename basic_socket_ext<Protocol,
+ Executor>::native_handle_type native_handle_type;
+#endif
+
+ /// The protocol type.
+ typedef Protocol protocol_type;
+
+ /// The endpoint type.
+ typedef typename Protocol::endpoint endpoint_type;
+
+ /// Construct a basic_datagram_socket without opening it.
+ /**
+ * This constructor creates a datagram socket without opening it. The open()
+ * function must be called before data can be sent or received on the socket.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ */
+ explicit basic_datagram_socket_ext(const executor_type& ex)
+ : basic_socket_ext<Protocol, Executor>(ex)
+ {
+ }
+
+ /// Construct a basic_datagram_socket without opening it.
+ /**
+ * This constructor creates a datagram socket without opening it. The open()
+ * function must be called before data can be sent or received on the socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ */
+ template <typename ExecutionContext>
+ explicit basic_datagram_socket_ext(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket_ext<Protocol, Executor>(context)
+ {
+ }
+
+ /// Construct and open a basic_datagram_socket.
+ /**
+ * This constructor creates and opens a datagram socket.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_datagram_socket_ext(const executor_type& ex, const protocol_type& protocol)
+ : basic_socket_ext<Protocol, Executor>(ex, protocol)
+ {
+ }
+
+ /// Construct and open a basic_datagram_socket.
+ /**
+ * This constructor creates and opens a datagram socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_datagram_socket_ext(ExecutionContext& context,
+ const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket_ext<Protocol, Executor>(context, protocol)
+ {
+ }
+
+ /// Construct a basic_datagram_socket, opening it and binding it to the given
+ /// local endpoint.
+ /**
+ * This constructor creates a datagram socket and automatically opens it bound
+ * to the specified endpoint on the local machine. The protocol used is the
+ * protocol associated with the given endpoint.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the datagram
+ * socket will be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_datagram_socket_ext(const executor_type& ex, const endpoint_type& endpoint)
+ : basic_socket_ext<Protocol, Executor>(ex, endpoint)
+ {
+ }
+
+ /// Construct a basic_datagram_socket, opening it and binding it to the given
+ /// local endpoint.
+ /**
+ * This constructor creates a datagram socket and automatically opens it bound
+ * to the specified endpoint on the local machine. The protocol used is the
+ * protocol associated with the given endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the datagram
+ * socket will be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_datagram_socket_ext(ExecutionContext& context,
+ const endpoint_type& endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket_ext<Protocol, Executor>(context, endpoint)
+ {
+ }
+
+ /// Construct a basic_datagram_socket on an existing native socket.
+ /**
+ * This constructor creates a datagram socket object to hold an existing
+ * native socket.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket The new underlying socket implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_datagram_socket_ext(const executor_type& ex,
+ const protocol_type& protocol, const native_handle_type& native_socket)
+ : basic_socket_ext<Protocol, Executor>(ex, protocol, native_socket)
+ {
+ }
+
+ /// Construct a basic_datagram_socket on an existing native socket.
+ /**
+ * This constructor creates a datagram socket object to hold an existing
+ * native socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket The new underlying socket implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_datagram_socket_ext(ExecutionContext& context,
+ const protocol_type& protocol, const native_handle_type& native_socket,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket_ext<Protocol, Executor>(context, protocol, native_socket)
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct a basic_datagram_socket from another.
+ /**
+ * This constructor moves a datagram socket from one object to another.
+ *
+ * @param other The other basic_datagram_socket object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_datagram_socket(const executor_type&)
+ * constructor.
+ */
+ basic_datagram_socket_ext(basic_datagram_socket_ext&& other)
+ : basic_socket_ext<Protocol, Executor>(std::move(other))
+ {
+ }
+
+ /// Move-assign a basic_datagram_socket from another.
+ /**
+ * This assignment operator moves a datagram socket from one object to
+ * another.
+ *
+ * @param other The other basic_datagram_socket object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_datagram_socket(const executor_type&)
+ * constructor.
+ */
+ basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other)
+ {
+ basic_socket_ext<Protocol, Executor>::operator=(std::move(other));
+ return *this;
+ }
+
+ /// Move-construct a basic_datagram_socket from a socket of another protocol
+ /// type.
+ /**
+ * This constructor moves a datagram socket from one object to another.
+ *
+ * @param other The other basic_datagram_socket object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_datagram_socket(const executor_type&)
+ * constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ basic_datagram_socket_ext(basic_datagram_socket_ext<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : basic_socket_ext<Protocol, Executor>(std::move(other))
+ {
+ }
+
+ /// Move-assign a basic_datagram_socket from a socket of another protocol
+ /// type.
+ /**
+ * This assignment operator moves a datagram socket from one object to
+ * another.
+ *
+ * @param other The other basic_datagram_socket object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_datagram_socket(const executor_type&)
+ * constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_datagram_socket_ext&
+ >::type operator=(basic_datagram_socket_ext<Protocol1, Executor1>&& other)
+ {
+ basic_socket_ext<Protocol, Executor>::operator=(std::move(other));
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Destroys the socket.
+ /**
+ * This function destroys the socket, cancelling any outstanding asynchronous
+ * operations associated with the socket as if by calling @c cancel.
+ */
+ ~basic_datagram_socket_ext()
+ {
+ }
+
+ /// Send some data on a connected socket.
+ /**
+ * This function is used to send data on the datagram socket. The function
+ * call will block until the data has been sent successfully or an error
+ * occurs.
+ *
+ * @param buffers One ore more data buffers to be sent on the socket.
+ *
+ * @returns The number of bytes sent.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note The send operation can only be used with a connected socket. Use
+ * the send_to function to send data on an unconnected datagram socket.
+ *
+ * @par Example
+ * To send a single data buffer use the @ref buffer function as follows:
+ * @code socket.send(boost::asio::buffer(data, size)); @endcode
+ * See the @ref buffer documentation for information on sending multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t send(const ConstBufferSequence& buffers)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, 0, ec);
+ boost::asio::detail::throw_error(ec, "send");
+ return s;
+ }
+
+ /// Send some data on a connected socket.
+ /**
+ * This function is used to send data on the datagram socket. The function
+ * call will block until the data has been sent successfully or an error
+ * occurs.
+ *
+ * @param buffers One ore more data buffers to be sent on the socket.
+ *
+ * @param flags Flags specifying how the send call is to be made.
+ *
+ * @returns The number of bytes sent.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note The send operation can only be used with a connected socket. Use
+ * the send_to function to send data on an unconnected datagram socket.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t send(const ConstBufferSequence& buffers,
+ socket_base::message_flags flags)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
+ boost::asio::detail::throw_error(ec, "send");
+ return s;
+ }
+
+ /// Send some data on a connected socket.
+ /**
+ * This function is used to send data on the datagram socket. The function
+ * call will block until the data has been sent successfully or an error
+ * occurs.
+ *
+ * @param buffers One or more data buffers to be sent on the socket.
+ *
+ * @param flags Flags specifying how the send call is to be made.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes sent.
+ *
+ * @note The send operation can only be used with a connected socket. Use
+ * the send_to function to send data on an unconnected datagram socket.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t send(const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ return this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
+ }
+
+ /// Start an asynchronous send on a connected socket.
+ /**
+ * This function is used to asynchronously send data on the datagram socket.
+ * The function call always returns immediately.
+ *
+ * @param buffers One or more data buffers to be sent on the socket. Although
+ * the buffers object may be copied as necessary, ownership of the underlying
+ * memory blocks is retained by the caller, which must guarantee that they
+ * remain valid until the handler is called.
+ *
+ * @param handler The handler to be called when the send operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes sent.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The async_send operation can only be used with a connected socket.
+ * Use the async_send_to function to send data on an unconnected datagram
+ * socket.
+ *
+ * @par Example
+ * To send a single data buffer use the @ref buffer function as follows:
+ * @code
+ * socket.async_send(boost::asio::buffer(data, size), handler);
+ * @endcode
+ * See the @ref buffer documentation for information on sending multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence, typename WriteHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+ async_send(const ConstBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+ {
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this,
+ buffers, socket_base::message_flags(0));
+ }
+
+ /// Start an asynchronous send on a connected socket.
+ /**
+ * This function is used to asynchronously send data on the datagram socket.
+ * The function call always returns immediately.
+ *
+ * @param buffers One or more data buffers to be sent on the socket. Although
+ * the buffers object may be copied as necessary, ownership of the underlying
+ * memory blocks is retained by the caller, which must guarantee that they
+ * remain valid until the handler is called.
+ *
+ * @param flags Flags specifying how the send call is to be made.
+ *
+ * @param handler The handler to be called when the send operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes sent.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The async_send operation can only be used with a connected socket.
+ * Use the async_send_to function to send data on an unconnected datagram
+ * socket.
+ */
+ template <typename ConstBufferSequence, typename WriteHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+ async_send(const ConstBufferSequence& buffers,
+ socket_base::message_flags flags,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+ {
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this, buffers, flags);
+ }
+
+ /// Send a datagram to the specified endpoint.
+ /**
+ * This function is used to send a datagram to the specified remote endpoint.
+ * The function call will block until the data has been sent successfully or
+ * an error occurs.
+ *
+ * @param buffers One or more data buffers to be sent to the remote endpoint.
+ *
+ * @param destination The remote endpoint to which the data will be sent.
+ *
+ * @returns The number of bytes sent.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * To send a single data buffer use the @ref buffer function as follows:
+ * @code
+ * boost::asio::ip::udp::endpoint destination(
+ * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+ * socket.send_to(boost::asio::buffer(data, size), destination);
+ * @endcode
+ * See the @ref buffer documentation for information on sending multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t send_to(const ConstBufferSequence& buffers,
+ const endpoint_type& destination)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().send_to(
+ this->impl_.get_implementation(), buffers, destination, 0, ec);
+ boost::asio::detail::throw_error(ec, "send_to");
+ return s;
+ }
+
+ /// Send a datagram to the specified endpoint.
+ /**
+ * This function is used to send a datagram to the specified remote endpoint.
+ * The function call will block until the data has been sent successfully or
+ * an error occurs.
+ *
+ * @param buffers One or more data buffers to be sent to the remote endpoint.
+ *
+ * @param destination The remote endpoint to which the data will be sent.
+ *
+ * @param flags Flags specifying how the send call is to be made.
+ *
+ * @returns The number of bytes sent.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t send_to(const ConstBufferSequence& buffers,
+ const endpoint_type& destination, socket_base::message_flags flags)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().send_to(
+ this->impl_.get_implementation(), buffers, destination, flags, ec);
+ boost::asio::detail::throw_error(ec, "send_to");
+ return s;
+ }
+
+ /// Send a datagram to the specified endpoint.
+ /**
+ * This function is used to send a datagram to the specified remote endpoint.
+ * The function call will block until the data has been sent successfully or
+ * an error occurs.
+ *
+ * @param buffers One or more data buffers to be sent to the remote endpoint.
+ *
+ * @param destination The remote endpoint to which the data will be sent.
+ *
+ * @param flags Flags specifying how the send call is to be made.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes sent.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t send_to(const ConstBufferSequence& buffers,
+ const endpoint_type& destination, socket_base::message_flags flags,
+ boost::system::error_code& ec)
+ {
+ return this->impl_.get_service().send_to(this->impl_.get_implementation(),
+ buffers, destination, flags, ec);
+ }
+
+ /// Start an asynchronous send.
+ /**
+ * This function is used to asynchronously send a datagram to the specified
+ * remote endpoint. The function call always returns immediately.
+ *
+ * @param buffers One or more data buffers to be sent to the remote endpoint.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param destination The remote endpoint to which the data will be sent.
+ * Copies will be made of the endpoint as required.
+ *
+ * @param handler The handler to be called when the send operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes sent.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * To send a single data buffer use the @ref buffer function as follows:
+ * @code
+ * boost::asio::ip::udp::endpoint destination(
+ * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+ * socket.async_send_to(
+ * boost::asio::buffer(data, size), destination, handler);
+ * @endcode
+ * See the @ref buffer documentation for information on sending multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence, typename WriteHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+ async_send_to(const ConstBufferSequence& buffers,
+ const endpoint_type& destination,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+ {
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send_to(), handler, this, buffers,
+ destination, socket_base::message_flags(0));
+ }
+
+ /// Start an asynchronous send.
+ /**
+ * This function is used to asynchronously send a datagram to the specified
+ * remote endpoint. The function call always returns immediately.
+ *
+ * @param buffers One or more data buffers to be sent to the remote endpoint.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param flags Flags specifying how the send call is to be made.
+ *
+ * @param destination The remote endpoint to which the data will be sent.
+ * Copies will be made of the endpoint as required.
+ *
+ * @param handler The handler to be called when the send operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes sent.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ */
+ template <typename ConstBufferSequence, typename WriteHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+ async_send_to(const ConstBufferSequence& buffers,
+ const endpoint_type& destination, socket_base::message_flags flags,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+ {
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send_to(), handler, this, buffers, destination, flags);
+ }
+
+ /// Receive some data on a connected socket.
+ /**
+ * This function is used to receive data on the datagram socket. The function
+ * call will block until data has been received successfully or an error
+ * occurs.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ *
+ * @returns The number of bytes received.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note The receive operation can only be used with a connected socket. Use
+ * the receive_from function to receive data on an unconnected datagram
+ * socket.
+ *
+ * @par Example
+ * To receive into a single data buffer use the @ref buffer function as
+ * follows:
+ * @code socket.receive(boost::asio::buffer(data, size)); @endcode
+ * See the @ref buffer documentation for information on receiving into
+ * multiple buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t receive(const MutableBufferSequence& buffers)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, 0, ec);
+ boost::asio::detail::throw_error(ec, "receive");
+ return s;
+ }
+
+ /// Receive some data on a connected socket.
+ /**
+ * This function is used to receive data on the datagram socket. The function
+ * call will block until data has been received successfully or an error
+ * occurs.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ *
+ * @param flags Flags specifying how the receive call is to be made.
+ *
+ * @returns The number of bytes received.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note The receive operation can only be used with a connected socket. Use
+ * the receive_from function to receive data on an unconnected datagram
+ * socket.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t receive(const MutableBufferSequence& buffers,
+ socket_base::message_flags flags)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
+ boost::asio::detail::throw_error(ec, "receive");
+ return s;
+ }
+
+ /// Receive some data on a connected socket.
+ /**
+ * This function is used to receive data on the datagram socket. The function
+ * call will block until data has been received successfully or an error
+ * occurs.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ *
+ * @param flags Flags specifying how the receive call is to be made.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes received.
+ *
+ * @note The receive operation can only be used with a connected socket. Use
+ * the receive_from function to receive data on an unconnected datagram
+ * socket.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t receive(const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ return this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
+ }
+
+ /// Start an asynchronous receive on a connected socket.
+ /**
+ * This function is used to asynchronously receive data from the datagram
+ * socket. The function call always returns immediately.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param handler The handler to be called when the receive operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes received.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The async_receive operation can only be used with a connected socket.
+ * Use the async_receive_from function to receive data on an unconnected
+ * datagram socket.
+ *
+ * @par Example
+ * To receive into a single data buffer use the @ref buffer function as
+ * follows:
+ * @code
+ * socket.async_receive(boost::asio::buffer(data, size), handler);
+ * @endcode
+ * See the @ref buffer documentation for information on receiving into
+ * multiple buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence, typename ReadHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t, boost::asio::ip::address))
+ async_receive(const MutableBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ {
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
+ initiate_async_receive(), handler, this,
+ buffers, socket_base::message_flags(0));
+ }
+
+ /// Start an asynchronous receive on a connected socket.
+ /**
+ * This function is used to asynchronously receive data from the datagram
+ * socket. The function call always returns immediately.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param flags Flags specifying how the receive call is to be made.
+ *
+ * @param handler The handler to be called when the receive operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes received.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The async_receive operation can only be used with a connected socket.
+ * Use the async_receive_from function to receive data on an unconnected
+ * datagram socket.
+ */
+ template <typename MutableBufferSequence, typename ReadHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t, boost::asio::ip::address))
+ async_receive(const MutableBufferSequence& buffers,
+ socket_base::message_flags flags,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ {
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
+ initiate_async_receive(), handler, this, buffers, flags);
+ }
+
+ /// Receive a datagram with the endpoint of the sender.
+ /**
+ * This function is used to receive a datagram. The function call will block
+ * until data has been received successfully or an error occurs.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ *
+ * @param sender_endpoint An endpoint object that receives the endpoint of
+ * the remote sender of the datagram.
+ *
+ * @returns The number of bytes received.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * To receive into a single data buffer use the @ref buffer function as
+ * follows:
+ * @code
+ * boost::asio::ip::udp::endpoint sender_endpoint;
+ * socket.receive_from(
+ * boost::asio::buffer(data, size), sender_endpoint);
+ * @endcode
+ * See the @ref buffer documentation for information on receiving into
+ * multiple buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t receive_from(const MutableBufferSequence& buffers,
+ endpoint_type& sender_endpoint)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().receive_from(
+ this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
+ boost::asio::detail::throw_error(ec, "receive_from");
+ return s;
+ }
+
+ /// Receive a datagram with the endpoint of the sender.
+ /**
+ * This function is used to receive a datagram. The function call will block
+ * until data has been received successfully or an error occurs.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ *
+ * @param sender_endpoint An endpoint object that receives the endpoint of
+ * the remote sender of the datagram.
+ *
+ * @param flags Flags specifying how the receive call is to be made.
+ *
+ * @returns The number of bytes received.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t receive_from(const MutableBufferSequence& buffers,
+ endpoint_type& sender_endpoint, socket_base::message_flags flags)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().receive_from(
+ this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
+ boost::asio::detail::throw_error(ec, "receive_from");
+ return s;
+ }
+
+ /// Receive a datagram with the endpoint of the sender.
+ /**
+ * This function is used to receive a datagram. The function call will block
+ * until data has been received successfully or an error occurs.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ *
+ * @param sender_endpoint An endpoint object that receives the endpoint of
+ * the remote sender of the datagram.
+ *
+ * @param flags Flags specifying how the receive call is to be made.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes received.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t receive_from(const MutableBufferSequence& buffers,
+ endpoint_type& sender_endpoint, socket_base::message_flags flags,
+ boost::system::error_code& ec)
+ {
+ return this->impl_.get_service().receive_from(
+ this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
+ }
+
+ /// Start an asynchronous receive.
+ /**
+ * This function is used to asynchronously receive a datagram. The function
+ * call always returns immediately.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param sender_endpoint An endpoint object that receives the endpoint of
+ * the remote sender of the datagram. Ownership of the sender_endpoint object
+ * is retained by the caller, which must guarantee that it is valid until the
+ * handler is called.
+ *
+ * @param handler The handler to be called when the receive operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes received.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * To receive into a single data buffer use the @ref buffer function as
+ * follows:
+ * @code socket.async_receive_from(
+ * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode
+ * See the @ref buffer documentation for information on receiving into
+ * multiple buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence, typename ReadHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t, boost::asio::ip::address))
+ async_receive_from(const MutableBufferSequence& buffers,
+ endpoint_type& sender_endpoint,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ {
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
+ initiate_async_receive_from(), handler, this, buffers,
+ &sender_endpoint, socket_base::message_flags(0));
+ }
+
+ /// Start an asynchronous receive.
+ /**
+ * This function is used to asynchronously receive a datagram. The function
+ * call always returns immediately.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param sender_endpoint An endpoint object that receives the endpoint of
+ * the remote sender of the datagram. Ownership of the sender_endpoint object
+ * is retained by the caller, which must guarantee that it is valid until the
+ * handler is called.
+ *
+ * @param flags Flags specifying how the receive call is to be made.
+ *
+ * @param handler The handler to be called when the receive operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes received.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ */
+ template <typename MutableBufferSequence, typename ReadHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t, boost::asio::ip::address))
+ async_receive_from(const MutableBufferSequence& buffers,
+ endpoint_type& sender_endpoint, socket_base::message_flags flags,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ {
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t, boost::asio::ip::address)>(
+ initiate_async_receive_from(), handler,
+ this, buffers, &sender_endpoint, flags);
+ }
+
+private:
+ struct initiate_async_send
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_datagram_socket_ext* self, const ConstBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_send(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_executor());
+ }
+ };
+
+ struct initiate_async_send_to
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_datagram_socket_ext* self, const ConstBufferSequence& buffers,
+ const endpoint_type& destination,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_send_to(
+ self->impl_.get_implementation(), buffers, destination, flags,
+ handler2.value, self->impl_.get_executor());
+ }
+ };
+
+ struct initiate_async_receive
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_datagram_socket_ext* self, const MutableBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_receive(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_executor());
+ }
+ };
+
+ struct initiate_async_receive_from
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_datagram_socket_ext* self, const MutableBufferSequence& buffers,
+ endpoint_type* sender_endpoint, socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_receive_from(
+ self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
+ handler2.value, self->impl_.get_executor());
+ }
+ };
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp
new file mode 100644
index 0000000..0a86539
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp
@@ -0,0 +1,2381 @@
+//
+// basic_socket_acceptor_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP
+#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/basic_socket_ext_local.hpp>
+#include <boost/asio/detail/handler_type_requirements_ext.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
+#include <boost/asio/socket_base.hpp>
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/null_socket_service.hpp>
+#elif defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_socket_service.hpp>
+#else
+# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
+#endif
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_socket_acceptor_ext;
+
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL)
+
+/// Provides the ability to accept new connections.
+/**
+ * The basic_socket_acceptor_ext class template is used for accepting new socket
+ * connections.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Example
+ * Opening a socket acceptor with the SO_REUSEADDR option enabled:
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
+ * acceptor.open(endpoint.protocol());
+ * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+ * acceptor.bind(endpoint);
+ * acceptor.listen();
+ * @endcode
+ */
+template <typename Protocol, typename Executor>
+class basic_socket_acceptor_ext
+ : public socket_base
+{
+public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// The native representation of an acceptor.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#elif defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ typedef typename detail::null_socket_service<
+ Protocol>::native_handle_type native_handle_type;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ typedef typename detail::win_iocp_socket_service<
+ Protocol>::native_handle_type native_handle_type;
+#else
+ typedef typename detail::reactive_socket_service_ext_local<
+ Protocol>::native_handle_type native_handle_type;
+#endif
+
+ /// The protocol type.
+ typedef Protocol protocol_type;
+
+ /// The endpoint type.
+ typedef typename Protocol::endpoint endpoint_type;
+
+ /// Construct an acceptor without opening it.
+ /**
+ * This constructor creates an acceptor without opening it to listen for new
+ * connections. The open() function must be called before the acceptor can
+ * accept new socket connections.
+ *
+ * @param ex The I/O executor that the acceptor will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * acceptor.
+ */
+ explicit basic_socket_acceptor_ext(const executor_type& ex)
+ : impl_(0, ex)
+ {
+ }
+
+ /// Construct an acceptor without opening it.
+ /**
+ * This constructor creates an acceptor without opening it to listen for new
+ * connections. The open() function must be called before the acceptor can
+ * accept new socket connections.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the acceptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the acceptor.
+ */
+ template <typename ExecutionContext>
+ explicit basic_socket_acceptor_ext(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ }
+
+ /// Construct an open acceptor.
+ /**
+ * This constructor creates an acceptor and automatically opens it.
+ *
+ * @param ex The I/O executor that the acceptor will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * acceptor.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_socket_acceptor_ext(const executor_type& ex, const protocol_type& protocol)
+ : impl_(0, ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct an open acceptor.
+ /**
+ * This constructor creates an acceptor and automatically opens it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the acceptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the acceptor.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_acceptor_ext(ExecutionContext& context,
+ const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct an acceptor opened on the given endpoint.
+ /**
+ * This constructor creates an acceptor and automatically opens it to listen
+ * for new connections on the specified endpoint.
+ *
+ * @param ex The I/O executor that the acceptor will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * acceptor.
+ *
+ * @param endpoint An endpoint on the local machine on which the acceptor
+ * will listen for new connections.
+ *
+ * @param reuse_addr Whether the constructor should set the socket option
+ * socket_base::reuse_address.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This constructor is equivalent to the following code:
+ * @code
+ * basic_socket_acceptor<Protocol> acceptor(my_context);
+ * acceptor.open(endpoint.protocol());
+ * if (reuse_addr)
+ * acceptor.set_option(socket_base::reuse_address(true));
+ * acceptor.bind(endpoint);
+ * acceptor.listen();
+ * @endcode
+ */
+ basic_socket_acceptor_ext(const executor_type& ex,
+ const endpoint_type& endpoint, bool reuse_addr = true)
+ : impl_(0, ex)
+ {
+ boost::system::error_code ec;
+ const protocol_type protocol = endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ if (reuse_addr)
+ {
+ impl_.get_service().set_option(impl_.get_implementation(),
+ socket_base::reuse_address(true), ec);
+ boost::asio::detail::throw_error(ec, "set_option");
+ }
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ impl_.get_service().listen(impl_.get_implementation(),
+ socket_base::max_listen_connections, ec);
+ boost::asio::detail::throw_error(ec, "listen");
+ }
+
+ /// Construct an acceptor opened on the given endpoint.
+ /**
+ * This constructor creates an acceptor and automatically opens it to listen
+ * for new connections on the specified endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the acceptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the acceptor.
+ *
+ * @param endpoint An endpoint on the local machine on which the acceptor
+ * will listen for new connections.
+ *
+ * @param reuse_addr Whether the constructor should set the socket option
+ * socket_base::reuse_address.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This constructor is equivalent to the following code:
+ * @code
+ * basic_socket_acceptor<Protocol> acceptor(my_context);
+ * acceptor.open(endpoint.protocol());
+ * if (reuse_addr)
+ * acceptor.set_option(socket_base::reuse_address(true));
+ * acceptor.bind(endpoint);
+ * acceptor.listen();
+ * @endcode
+ */
+ template <typename ExecutionContext>
+ basic_socket_acceptor_ext(ExecutionContext& context,
+ const endpoint_type& endpoint, bool reuse_addr = true,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ boost::system::error_code ec;
+ const protocol_type protocol = endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ if (reuse_addr)
+ {
+ impl_.get_service().set_option(impl_.get_implementation(),
+ socket_base::reuse_address(true), ec);
+ boost::asio::detail::throw_error(ec, "set_option");
+ }
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ impl_.get_service().listen(impl_.get_implementation(),
+ socket_base::max_listen_connections, ec);
+ boost::asio::detail::throw_error(ec, "listen");
+ }
+
+ /// Construct a basic_socket_acceptor on an existing native acceptor.
+ /**
+ * This constructor creates an acceptor object to hold an existing native
+ * acceptor.
+ *
+ * @param ex The I/O executor that the acceptor will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * acceptor.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_acceptor A native acceptor.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_socket_acceptor_ext(const executor_type& ex,
+ const protocol_type& protocol, const native_handle_type& native_acceptor)
+ : impl_(0, ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_acceptor, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Construct a basic_socket_acceptor on an existing native acceptor.
+ /**
+ * This constructor creates an acceptor object to hold an existing native
+ * acceptor.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the acceptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the acceptor.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_acceptor A native acceptor.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_acceptor_ext(ExecutionContext& context,
+ const protocol_type& protocol, const native_handle_type& native_acceptor,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_acceptor, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct a basic_socket_acceptor from another.
+ /**
+ * This constructor moves an acceptor from one object to another.
+ *
+ * @param other The other basic_socket_acceptor object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket_acceptor(const executor_type&)
+ * constructor.
+ */
+ basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other)
+ : impl_(std::move(other.impl_))
+ {
+ }
+
+ /// Move-assign a basic_socket_acceptor from another.
+ /**
+ * This assignment operator moves an acceptor from one object to another.
+ *
+ * @param other The other basic_socket_acceptor object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket_acceptor(const executor_type&)
+ * constructor.
+ */
+ basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other)
+ {
+ impl_ = std::move(other.impl_);
+ return *this;
+ }
+
+ // All socket acceptors have access to each other's implementations.
+ template <typename Protocol1, typename Executor1>
+ friend class basic_socket_acceptor_ext;
+
+ /// Move-construct a basic_socket_acceptor from an acceptor of another
+ /// protocol type.
+ /**
+ * This constructor moves an acceptor from one object to another.
+ *
+ * @param other The other basic_socket_acceptor object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket_acceptor(const executor_type&)
+ * constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ basic_socket_acceptor_ext(basic_socket_acceptor_ext<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : impl_(std::move(other.impl_))
+ {
+ }
+
+ /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
+ /// type.
+ /**
+ * This assignment operator moves an acceptor from one object to another.
+ *
+ * @param other The other basic_socket_acceptor object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket_acceptor(const executor_type&)
+ * constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_socket_acceptor_ext&
+ >::type operator=(basic_socket_acceptor_ext<Protocol1, Executor1>&& other)
+ {
+ basic_socket_acceptor_ext tmp(std::move(other));
+ impl_ = std::move(tmp.impl_);
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Destroys the acceptor.
+ /**
+ * This function destroys the acceptor, cancelling any outstanding
+ * asynchronous operations associated with the acceptor as if by calling
+ * @c cancel.
+ */
+ ~basic_socket_acceptor_ext()
+ {
+ }
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return impl_.get_executor();
+ }
+
+ /// Open the acceptor using the specified protocol.
+ /**
+ * This function opens the socket acceptor so that it will use the specified
+ * protocol.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * acceptor.open(boost::asio::ip::tcp::v4());
+ * @endcode
+ */
+ void open(const protocol_type& protocol = protocol_type())
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Open the acceptor using the specified protocol.
+ /**
+ * This function opens the socket acceptor so that it will use the specified
+ * protocol.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * boost::system::error_code ec;
+ * acceptor.open(boost::asio::ip::tcp::v4(), ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Assigns an existing native acceptor to the acceptor.
+ /*
+ * This function opens the acceptor to hold an existing native acceptor.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @param native_acceptor A native acceptor.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void assign(const protocol_type& protocol,
+ const native_handle_type& native_acceptor)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_acceptor, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Assigns an existing native acceptor to the acceptor.
+ /*
+ * This function opens the acceptor to hold an existing native acceptor.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @param native_acceptor A native acceptor.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
+ const native_handle_type& native_acceptor, boost::system::error_code& ec)
+ {
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_acceptor, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Determine whether the acceptor is open.
+ bool is_open() const
+ {
+ return impl_.get_service().is_open(impl_.get_implementation());
+ }
+
+ /// Bind the acceptor to the given local endpoint.
+ /**
+ * This function binds the socket acceptor to the specified endpoint on the
+ * local machine.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket
+ * acceptor will be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
+ * acceptor.open(endpoint.protocol());
+ * acceptor.bind(endpoint);
+ * @endcode
+ */
+ void bind(const endpoint_type& endpoint)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ }
+
+ /// Bind the acceptor to the given local endpoint.
+ /**
+ * This function binds the socket acceptor to the specified endpoint on the
+ * local machine.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket
+ * acceptor will be bound.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
+ * acceptor.open(endpoint.protocol());
+ * boost::system::error_code ec;
+ * acceptor.bind(endpoint, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Place the acceptor into the state where it will listen for new
+ /// connections.
+ /**
+ * This function puts the socket acceptor into the state where it may accept
+ * new connections.
+ *
+ * @param backlog The maximum length of the queue of pending connections.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void listen(int backlog = socket_base::max_listen_connections)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
+ boost::asio::detail::throw_error(ec, "listen");
+ }
+
+ /// Place the acceptor into the state where it will listen for new
+ /// connections.
+ /**
+ * This function puts the socket acceptor into the state where it may accept
+ * new connections.
+ *
+ * @param backlog The maximum length of the queue of pending connections.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec)
+ {
+ impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Close the acceptor.
+ /**
+ * This function is used to close the acceptor. Any asynchronous accept
+ * operations will be cancelled immediately.
+ *
+ * A subsequent call to open() is required before the acceptor can again be
+ * used to again perform socket accept operations.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void close()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "close");
+ }
+
+ /// Close the acceptor.
+ /**
+ * This function is used to close the acceptor. Any asynchronous accept
+ * operations will be cancelled immediately.
+ *
+ * A subsequent call to open() is required before the acceptor can again be
+ * used to again perform socket accept operations.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * acceptor.close(ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+ {
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Release ownership of the underlying native acceptor.
+ /**
+ * This function causes all outstanding asynchronous accept operations to
+ * finish immediately, and the handlers for cancelled operations will be
+ * passed the boost::asio::error::operation_aborted error. Ownership of the
+ * native acceptor is then transferred to the caller.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release()
+ {
+ boost::system::error_code ec;
+ native_handle_type s = impl_.get_service().release(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "release");
+ return s;
+ }
+
+ /// Release ownership of the underlying native acceptor.
+ /**
+ * This function causes all outstanding asynchronous accept operations to
+ * finish immediately, and the handlers for cancelled operations will be
+ * passed the boost::asio::error::operation_aborted error. Ownership of the
+ * native acceptor is then transferred to the caller.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release(boost::system::error_code& ec)
+ {
+ return impl_.get_service().release(impl_.get_implementation(), ec);
+ }
+
+ /// Get the native acceptor representation.
+ /**
+ * This function may be used to obtain the underlying representation of the
+ * acceptor. This is intended to allow access to native acceptor functionality
+ * that is not otherwise provided.
+ */
+ native_handle_type native_handle()
+ {
+ return impl_.get_service().native_handle(impl_.get_implementation());
+ }
+
+ /// Cancel all asynchronous operations associated with the acceptor.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void cancel()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "cancel");
+ }
+
+ /// Cancel all asynchronous operations associated with the acceptor.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
+ {
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Set an option on the acceptor.
+ /**
+ * This function is used to set an option on the acceptor.
+ *
+ * @param option The new option value to be set on the acceptor.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @sa SettableSocketOption @n
+ * boost::asio::socket_base::reuse_address
+ * boost::asio::socket_base::enable_connection_aborted
+ *
+ * @par Example
+ * Setting the SOL_SOCKET/SO_REUSEADDR option:
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::acceptor::reuse_address option(true);
+ * acceptor.set_option(option);
+ * @endcode
+ */
+ template <typename SettableSocketOption>
+ void set_option(const SettableSocketOption& option)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
+ boost::asio::detail::throw_error(ec, "set_option");
+ }
+
+ /// Set an option on the acceptor.
+ /**
+ * This function is used to set an option on the acceptor.
+ *
+ * @param option The new option value to be set on the acceptor.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @sa SettableSocketOption @n
+ * boost::asio::socket_base::reuse_address
+ * boost::asio::socket_base::enable_connection_aborted
+ *
+ * @par Example
+ * Setting the SOL_SOCKET/SO_REUSEADDR option:
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::acceptor::reuse_address option(true);
+ * boost::system::error_code ec;
+ * acceptor.set_option(option, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename SettableSocketOption>
+ BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Get an option from the acceptor.
+ /**
+ * This function is used to get the current value of an option on the
+ * acceptor.
+ *
+ * @param option The option value to be obtained from the acceptor.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @sa GettableSocketOption @n
+ * boost::asio::socket_base::reuse_address
+ *
+ * @par Example
+ * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::acceptor::reuse_address option;
+ * acceptor.get_option(option);
+ * bool is_set = option.get();
+ * @endcode
+ */
+ template <typename GettableSocketOption>
+ void get_option(GettableSocketOption& option) const
+ {
+ boost::system::error_code ec;
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
+ boost::asio::detail::throw_error(ec, "get_option");
+ }
+
+ /// Get an option from the acceptor.
+ /**
+ * This function is used to get the current value of an option on the
+ * acceptor.
+ *
+ * @param option The option value to be obtained from the acceptor.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @sa GettableSocketOption @n
+ * boost::asio::socket_base::reuse_address
+ *
+ * @par Example
+ * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::acceptor::reuse_address option;
+ * boost::system::error_code ec;
+ * acceptor.get_option(option, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * bool is_set = option.get();
+ * @endcode
+ */
+ template <typename GettableSocketOption>
+ BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
+ boost::system::error_code& ec) const
+ {
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Perform an IO control command on the acceptor.
+ /**
+ * This function is used to execute an IO control command on the acceptor.
+ *
+ * @param command The IO control command to be performed on the acceptor.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @sa IoControlCommand @n
+ * boost::asio::socket_base::non_blocking_io
+ *
+ * @par Example
+ * Getting the number of bytes ready to read:
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
+ * socket.io_control(command);
+ * @endcode
+ */
+ template <typename IoControlCommand>
+ void io_control(IoControlCommand& command)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
+ boost::asio::detail::throw_error(ec, "io_control");
+ }
+
+ /// Perform an IO control command on the acceptor.
+ /**
+ * This function is used to execute an IO control command on the acceptor.
+ *
+ * @param command The IO control command to be performed on the acceptor.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @sa IoControlCommand @n
+ * boost::asio::socket_base::non_blocking_io
+ *
+ * @par Example
+ * Getting the number of bytes ready to read:
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
+ * boost::system::error_code ec;
+ * socket.io_control(command, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename IoControlCommand>
+ BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Gets the non-blocking mode of the acceptor.
+ /**
+ * @returns @c true if the acceptor's synchronous operations will fail with
+ * boost::asio::error::would_block if they are unable to perform the requested
+ * operation immediately. If @c false, synchronous operations will block
+ * until complete.
+ *
+ * @note The non-blocking mode has no effect on the behaviour of asynchronous
+ * operations. Asynchronous operations will never fail with the error
+ * boost::asio::error::would_block.
+ */
+ bool non_blocking() const
+ {
+ return impl_.get_service().non_blocking(impl_.get_implementation());
+ }
+
+ /// Sets the non-blocking mode of the acceptor.
+ /**
+ * @param mode If @c true, the acceptor's synchronous operations will fail
+ * with boost::asio::error::would_block if they are unable to perform the
+ * requested operation immediately. If @c false, synchronous operations will
+ * block until complete.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note The non-blocking mode has no effect on the behaviour of asynchronous
+ * operations. Asynchronous operations will never fail with the error
+ * boost::asio::error::would_block.
+ */
+ void non_blocking(bool mode)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
+ boost::asio::detail::throw_error(ec, "non_blocking");
+ }
+
+ /// Sets the non-blocking mode of the acceptor.
+ /**
+ * @param mode If @c true, the acceptor's synchronous operations will fail
+ * with boost::asio::error::would_block if they are unable to perform the
+ * requested operation immediately. If @c false, synchronous operations will
+ * block until complete.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note The non-blocking mode has no effect on the behaviour of asynchronous
+ * operations. Asynchronous operations will never fail with the error
+ * boost::asio::error::would_block.
+ */
+ BOOST_ASIO_SYNC_OP_VOID non_blocking(
+ bool mode, boost::system::error_code& ec)
+ {
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Gets the non-blocking mode of the native acceptor implementation.
+ /**
+ * This function is used to retrieve the non-blocking mode of the underlying
+ * native acceptor. This mode has no effect on the behaviour of the acceptor
+ * object's synchronous operations.
+ *
+ * @returns @c true if the underlying acceptor is in non-blocking mode and
+ * direct system calls may fail with boost::asio::error::would_block (or the
+ * equivalent system error).
+ *
+ * @note The current non-blocking mode is cached by the acceptor object.
+ * Consequently, the return value may be incorrect if the non-blocking mode
+ * was set directly on the native acceptor.
+ */
+ bool native_non_blocking() const
+ {
+ return impl_.get_service().native_non_blocking(impl_.get_implementation());
+ }
+
+ /// Sets the non-blocking mode of the native acceptor implementation.
+ /**
+ * This function is used to modify the non-blocking mode of the underlying
+ * native acceptor. It has no effect on the behaviour of the acceptor object's
+ * synchronous operations.
+ *
+ * @param mode If @c true, the underlying acceptor is put into non-blocking
+ * mode and direct system calls may fail with boost::asio::error::would_block
+ * (or the equivalent system error).
+ *
+ * @throws boost::system::system_error Thrown on failure. If the @c mode is
+ * @c false, but the current value of @c non_blocking() is @c true, this
+ * function fails with boost::asio::error::invalid_argument, as the
+ * combination does not make sense.
+ */
+ void native_non_blocking(bool mode)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
+ boost::asio::detail::throw_error(ec, "native_non_blocking");
+ }
+
+ /// Sets the non-blocking mode of the native acceptor implementation.
+ /**
+ * This function is used to modify the non-blocking mode of the underlying
+ * native acceptor. It has no effect on the behaviour of the acceptor object's
+ * synchronous operations.
+ *
+ * @param mode If @c true, the underlying acceptor is put into non-blocking
+ * mode and direct system calls may fail with boost::asio::error::would_block
+ * (or the equivalent system error).
+ *
+ * @param ec Set to indicate what error occurred, if any. If the @c mode is
+ * @c false, but the current value of @c non_blocking() is @c true, this
+ * function fails with boost::asio::error::invalid_argument, as the
+ * combination does not make sense.
+ */
+ BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
+ bool mode, boost::system::error_code& ec)
+ {
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Get the local endpoint of the acceptor.
+ /**
+ * This function is used to obtain the locally bound endpoint of the acceptor.
+ *
+ * @returns An object that represents the local endpoint of the acceptor.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
+ * @endcode
+ */
+ endpoint_type local_endpoint() const
+ {
+ boost::system::error_code ec;
+ endpoint_type ep = impl_.get_service().local_endpoint(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "local_endpoint");
+ return ep;
+ }
+
+ /// Get the local endpoint of the acceptor.
+ /**
+ * This function is used to obtain the locally bound endpoint of the acceptor.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns An object that represents the local endpoint of the acceptor.
+ * Returns a default-constructed endpoint object if an error occurred and the
+ * error handler did not throw an exception.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ endpoint_type local_endpoint(boost::system::error_code& ec) const
+ {
+ return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
+ }
+
+ /// Wait for the acceptor to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for an acceptor to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired acceptor state.
+ *
+ * @par Example
+ * Waiting for an acceptor to become readable.
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read);
+ * @endcode
+ */
+ void wait(wait_type w)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
+ boost::asio::detail::throw_error(ec, "wait");
+ }
+
+ /// Wait for the acceptor to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for an acceptor to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired acceptor state.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * Waiting for an acceptor to become readable.
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec);
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
+ {
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Asynchronously wait for the acceptor to become ready to read, ready to
+ /// write, or to have pending error conditions.
+ /**
+ * This function is used to perform an asynchronous wait for an acceptor to
+ * enter a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired acceptor state.
+ *
+ * @param handler The handler to be called when the wait operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error // Result of operation
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void wait_handler(const boost::system::error_code& error)
+ * {
+ * if (!error)
+ * {
+ * // Wait succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * acceptor.async_wait(
+ * boost::asio::ip::tcp::acceptor::wait_read,
+ * wait_handler);
+ * @endcode
+ */
+ template <typename WaitHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+ void (boost::system::error_code))
+ async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+ {
+ return async_initiate<WaitHandler, void (boost::system::error_code)>(
+ initiate_async_wait(), handler, this, w);
+ }
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer into the
+ * given socket. The function call will block until a new connection has been
+ * accepted successfully or an error occurs.
+ *
+ * @param peer The socket into which the new connection will be accepted.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * acceptor.accept(socket);
+ * @endcode
+ */
+ template <typename Protocol1, typename Executor1>
+ void accept(basic_socket_ext_local<Protocol1, Executor1>& peer,
+ typename enable_if<
+ is_convertible<Protocol, Protocol1>::value
+ >::type* = 0)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, static_cast<endpoint_type*>(0), ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer into the
+ * given socket. The function call will block until a new connection has been
+ * accepted successfully or an error occurs.
+ *
+ * @param peer The socket into which the new connection will be accepted.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::system::error_code ec;
+ * acceptor.accept(socket, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename Protocol1, typename Executor1>
+ BOOST_ASIO_SYNC_OP_VOID accept(
+ basic_socket_ext_local<Protocol1, Executor1>& peer, boost::system::error_code& ec,
+ typename enable_if<
+ is_convertible<Protocol, Protocol1>::value
+ >::type* = 0)
+ {
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, static_cast<endpoint_type*>(0), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection into a
+ * socket. The function call always returns immediately.
+ *
+ * @param peer The socket into which the new connection will be accepted.
+ * Ownership of the peer object is retained by the caller, which must
+ * guarantee that it is valid until the handler is called.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error // Result of operation.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * acceptor.async_accept(socket, accept_handler);
+ * @endcode
+ */
+ template <typename Protocol1, typename Executor1, typename AcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
+ void (boost::system::error_code))
+ async_accept(basic_socket_ext_local<Protocol1, Executor1>& peer,
+ BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
+ typename enable_if<
+ is_convertible<Protocol, Protocol1>::value
+ >::type* = 0)
+ {
+ return async_initiate<AcceptHandler, void (boost::system::error_code)>(
+ initiate_async_accept(), handler, this,
+ &peer, static_cast<endpoint_type*>(0));
+ }
+
+ /// Accept a new connection and obtain the endpoint of the peer
+ /**
+ * This function is used to accept a new connection from a peer into the
+ * given socket, and additionally provide the endpoint of the remote peer.
+ * The function call will block until a new connection has been accepted
+ * successfully or an error occurs.
+ *
+ * @param peer The socket into which the new connection will be accepted.
+ *
+ * @param peer_endpoint An endpoint object which will receive the endpoint of
+ * the remote peer.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * acceptor.accept(socket, endpoint);
+ * @endcode
+ */
+ template <typename Executor1>
+ void accept(basic_socket_ext_local<protocol_type, Executor1>& peer,
+ endpoint_type& peer_endpoint)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ }
+
+ /// Accept a new connection and obtain the endpoint of the peer
+ /**
+ * This function is used to accept a new connection from a peer into the
+ * given socket, and additionally provide the endpoint of the remote peer.
+ * The function call will block until a new connection has been accepted
+ * successfully or an error occurs.
+ *
+ * @param peer The socket into which the new connection will be accepted.
+ *
+ * @param peer_endpoint An endpoint object which will receive the endpoint of
+ * the remote peer.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::system::error_code ec;
+ * acceptor.accept(socket, endpoint, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename Executor1>
+ BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local<protocol_type, Executor1>& peer,
+ endpoint_type& peer_endpoint, boost::system::error_code& ec)
+ {
+ impl_.get_service().accept(
+ impl_.get_implementation(), peer, &peer_endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection into a
+ * socket, and additionally obtain the endpoint of the remote peer. The
+ * function call always returns immediately.
+ *
+ * @param peer The socket into which the new connection will be accepted.
+ * Ownership of the peer object is retained by the caller, which must
+ * guarantee that it is valid until the handler is called.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written. Ownership of the peer_endpoint object is
+ * retained by the caller, which must guarantee that it is valid until the
+ * handler is called.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error // Result of operation.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ */
+ template <typename Executor1, typename AcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
+ void (boost::system::error_code))
+ async_accept(basic_socket_ext_local<protocol_type, Executor1>& peer,
+ endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
+ {
+ return async_initiate<AcceptHandler, void (boost::system::error_code)>(
+ initiate_async_accept(), handler, this, &peer, &peer_endpoint);
+ }
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept());
+ * @endcode
+ */
+ typename Protocol::socket accept()
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket peer(impl_.get_executor());
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ typename Protocol::socket accept(boost::system::error_code& ec)
+ {
+ typename Protocol::socket peer(impl_.get_executor());
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ return peer;
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection. The
+ * function call always returns immediately.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket peer // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * acceptor.async_accept(accept_handler);
+ * @endcode
+ */
+ template <typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket))
+ async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+ {
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket)>(
+ initiate_async_move_accept(), handler, this,
+ impl_.get_executor(), static_cast<endpoint_type*>(0),
+ static_cast<typename Protocol::socket*>(0));
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param ex The I/O executor object to be used for the newly
+ * accepted socket.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept());
+ * @endcode
+ */
+ template <typename Executor1>
+ typename Protocol::socket::template rebind_executor<Executor1>::other
+ accept(const Executor1& ex,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket::template
+ rebind_executor<Executor1>::other peer(ex);
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept());
+ * @endcode
+ */
+ template <typename ExecutionContext>
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other
+ accept(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other peer(context);
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param ex The I/O executor object to be used for the newly accepted
+ * socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename Executor1>
+ typename Protocol::socket::template rebind_executor<Executor1>::other
+ accept(const Executor1& ex, boost::system::error_code& ec,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
+ {
+ typename Protocol::socket::template
+ rebind_executor<Executor1>::other peer(ex);
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename ExecutionContext>
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other
+ accept(ExecutionContext& context, boost::system::error_code& ec,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other peer(context);
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ return peer;
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection. The
+ * function call always returns immediately.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param ex The I/O executor object to be used for the newly accepted
+ * socket.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket::template rebind_executor<
+ * Executor1>::other peer // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * acceptor.async_accept(my_context2, accept_handler);
+ * @endcode
+ */
+ template <typename Executor1, typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket::template rebind_executor<
+ Executor1>::other))
+ async_accept(const Executor1& ex,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
+ {
+ typedef typename Protocol::socket::template rebind_executor<
+ Executor1>::other other_socket_type;
+
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, other_socket_type)>(
+ initiate_async_move_accept(), handler, this,
+ ex, static_cast<endpoint_type*>(0),
+ static_cast<other_socket_type*>(0));
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection. The
+ * function call always returns immediately.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket::template rebind_executor<
+ * typename ExecutionContext::executor_type>::other peer
+ * // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * acceptor.async_accept(my_context2, accept_handler);
+ * @endcode
+ */
+ template <typename ExecutionContext, typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other))
+ async_accept(ExecutionContext& context,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ typedef typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other other_socket_type;
+
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, other_socket_type)>(
+ initiate_async_move_accept(), handler, this,
+ context.get_executor(), static_cast<endpoint_type*>(0),
+ static_cast<other_socket_type*>(0));
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint));
+ * @endcode
+ */
+ typename Protocol::socket accept(endpoint_type& peer_endpoint)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket peer(impl_.get_executor());
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ typename Protocol::socket accept(
+ endpoint_type& peer_endpoint, boost::system::error_code& ec)
+ {
+ typename Protocol::socket peer(impl_.get_executor());
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ return peer;
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection. The
+ * function call always returns immediately.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written. Ownership of the peer_endpoint object is
+ * retained by the caller, which must guarantee that it is valid until the
+ * handler is called.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket peer // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * acceptor.async_accept(endpoint, accept_handler);
+ * @endcode
+ */
+ template <typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket))
+ async_accept(endpoint_type& peer_endpoint,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+ {
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket)>(
+ initiate_async_move_accept(), handler, this,
+ impl_.get_executor(), &peer_endpoint,
+ static_cast<typename Protocol::socket*>(0));
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param ex The I/O executor object to be used for the newly accepted
+ * socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(
+ * acceptor.accept(my_context2, endpoint));
+ * @endcode
+ */
+ template <typename Executor1>
+ typename Protocol::socket::template rebind_executor<Executor1>::other
+ accept(const Executor1& ex, endpoint_type& peer_endpoint,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket::template
+ rebind_executor<Executor1>::other peer(ex);
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(
+ * acceptor.accept(my_context2, endpoint));
+ * @endcode
+ */
+ template <typename ExecutionContext>
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other
+ accept(ExecutionContext& context, endpoint_type& peer_endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other peer(context);
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param ex The I/O executor object to be used for the newly accepted
+ * socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(
+ * acceptor.accept(my_context2, endpoint, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename Executor1>
+ typename Protocol::socket::template rebind_executor<Executor1>::other
+ accept(const executor_type& ex,
+ endpoint_type& peer_endpoint, boost::system::error_code& ec,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
+ {
+ typename Protocol::socket::template
+ rebind_executor<Executor1>::other peer(ex);
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(
+ * acceptor.accept(my_context2, endpoint, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename ExecutionContext>
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other
+ accept(ExecutionContext& context,
+ endpoint_type& peer_endpoint, boost::system::error_code& ec,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other peer(context);
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ return peer;
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection. The
+ * function call always returns immediately.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param ex The I/O executor object to be used for the newly accepted
+ * socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written. Ownership of the peer_endpoint object is
+ * retained by the caller, which must guarantee that it is valid until the
+ * handler is called.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket::template rebind_executor<
+ * Executor1>::other peer // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * acceptor.async_accept(my_context2, endpoint, accept_handler);
+ * @endcode
+ */
+ template <typename Executor1, typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket::template rebind_executor<
+ Executor1>::other))
+ async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
+ {
+ typedef typename Protocol::socket::template rebind_executor<
+ Executor1>::other other_socket_type;
+
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, other_socket_type)>(
+ initiate_async_move_accept(), handler, this,
+ ex, &peer_endpoint,
+ static_cast<other_socket_type*>(0));
+ }
+
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection. The
+ * function call always returns immediately.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written. Ownership of the peer_endpoint object is
+ * retained by the caller, which must guarantee that it is valid until the
+ * handler is called.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket::template rebind_executor<
+ * typename ExecutionContext::executor_type>::other peer
+ * // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * acceptor.async_accept(my_context2, endpoint, accept_handler);
+ * @endcode
+ */
+ template <typename ExecutionContext, typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other))
+ async_accept(ExecutionContext& context,
+ endpoint_type& peer_endpoint,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ typedef typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other other_socket_type;
+
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, other_socket_type)>(
+ initiate_async_move_accept(), handler, this,
+ context.get_executor(), &peer_endpoint,
+ static_cast<other_socket_type*>(0));
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+private:
+ // Disallow copying and assignment.
+ basic_socket_acceptor_ext(const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED;
+ basic_socket_acceptor_ext& operator=(
+ const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_wait
+ {
+ template <typename WaitHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
+ basic_socket_acceptor_ext* self, wait_type w) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+ detail::non_const_lvalue<WaitHandler> handler2(handler);
+ self->impl_.get_service().async_wait(
+ self->impl_.get_implementation(), w, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_accept
+ {
+ template <typename AcceptHandler, typename Protocol1, typename Executor1>
+ void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
+ basic_socket_acceptor_ext* self, basic_socket_ext_local<Protocol1, Executor1>* peer,
+ endpoint_type* peer_endpoint) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a AcceptHandler.
+ BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
+
+ detail::non_const_lvalue<AcceptHandler> handler2(handler);
+ self->impl_.get_service().async_accept(
+ self->impl_.get_implementation(), *peer, peer_endpoint,
+ handler2.value, self->impl_.get_executor());
+ }
+ };
+
+ struct initiate_async_move_accept
+ {
+ template <typename MoveAcceptHandler, typename Executor1, typename Socket>
+ void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ basic_socket_acceptor_ext* self, const Executor1& peer_ex,
+ endpoint_type* peer_endpoint, Socket*) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a MoveAcceptHandler.
+ BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(
+ MoveAcceptHandler, handler, Socket) type_check;
+
+ detail::non_const_lvalue<MoveAcceptHandler> handler2(handler);
+ self->impl_.get_service().async_move_accept(
+ self->impl_.get_implementation(), peer_ex, peer_endpoint,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ detail::io_object_impl<
+ detail::null_socket_service<Protocol>, Executor> impl_;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ detail::io_object_impl<
+ detail::win_iocp_socket_service<Protocol>, Executor> impl_;
+#else
+ detail::io_object_impl<
+ detail::reactive_socket_service_ext_local<Protocol>, Executor> impl_;
+#endif
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.76/boost/asio/basic_socket_ext.hpp
new file mode 100644
index 0000000..777a0bf
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/basic_socket_ext.hpp
@@ -0,0 +1,1859 @@
+//
+// basic_socket_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_HPP
+#define BOOST_ASIO_BASIC_SOCKET_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
+#include <boost/asio/post.hpp>
+#include <boost/asio/socket_base.hpp>
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/null_socket_service.hpp>
+#elif defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_socket_service.hpp>
+#else
+# include <boost/asio/detail/reactive_socket_service_ext.hpp>
+#endif
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_socket_ext;
+
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL)
+
+/// Provides socket functionality.
+/**
+ * The basic_socket class template provides functionality that is common to both
+ * stream-oriented and datagram-oriented sockets.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename Protocol, typename Executor>
+class basic_socket_ext
+ : public socket_base
+{
+public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// Rebinds the socket type to another executor.
+ template <typename Executor1>
+ struct rebind_executor
+ {
+ /// The socket type when rebound to the specified executor.
+ typedef basic_socket_ext<Protocol, Executor1> other;
+ };
+
+ /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#elif defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ typedef typename detail::null_socket_service<
+ Protocol>::native_handle_type native_handle_type;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ typedef typename detail::win_iocp_socket_service<
+ Protocol>::native_handle_type native_handle_type;
+#else
+ typedef typename detail::reactive_socket_service_ext<
+ Protocol>::native_handle_type native_handle_type;
+#endif
+
+ /// The protocol type.
+ typedef Protocol protocol_type;
+
+ /// The endpoint type.
+ typedef typename Protocol::endpoint endpoint_type;
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+ /// A basic_socket is always the lowest layer.
+ typedef basic_socket_ext<Protocol, Executor> lowest_layer_type;
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+ /// Construct a basic_socket without opening it.
+ /**
+ * This constructor creates a socket without opening it.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ */
+ explicit basic_socket_ext(const executor_type& ex)
+ : impl_(0, ex)
+ {
+ }
+
+ /// Construct a basic_socket without opening it.
+ /**
+ * This constructor creates a socket without opening it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ */
+ template <typename ExecutionContext>
+ explicit basic_socket_ext(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ }
+
+ /// Construct and open a basic_socket.
+ /**
+ * This constructor creates and opens a socket.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_socket_ext(const executor_type& ex, const protocol_type& protocol)
+ : impl_(0, ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct and open a basic_socket.
+ /**
+ * This constructor creates and opens a socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_ext(ExecutionContext& context, const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct a basic_socket, opening it and binding it to the given local
+ /// endpoint.
+ /**
+ * This constructor creates a socket and automatically opens it bound to the
+ * specified endpoint on the local machine. The protocol used is the protocol
+ * associated with the given endpoint.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket will
+ * be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_socket_ext(const executor_type& ex, const endpoint_type& endpoint)
+ : impl_(0, ex)
+ {
+ boost::system::error_code ec;
+ const protocol_type protocol = endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ }
+
+ /// Construct a basic_socket, opening it and binding it to the given local
+ /// endpoint.
+ /**
+ * This constructor creates a socket and automatically opens it bound to the
+ * specified endpoint on the local machine. The protocol used is the protocol
+ * associated with the given endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket will
+ * be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ boost::system::error_code ec;
+ const protocol_type protocol = endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ }
+
+ /// Construct a basic_socket on an existing native socket.
+ /**
+ * This constructor creates a socket object to hold an existing native socket.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket A native socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_socket_ext(const executor_type& ex, const protocol_type& protocol,
+ const native_handle_type& native_socket)
+ : impl_(0, ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_socket, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Construct a basic_socket on an existing native socket.
+ /**
+ * This constructor creates a socket object to hold an existing native socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket A native socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_ext(ExecutionContext& context, const protocol_type& protocol,
+ const native_handle_type& native_socket,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_socket, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct a basic_socket from another.
+ /**
+ * This constructor moves a socket from one object to another.
+ *
+ * @param other The other basic_socket object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket(const executor_type&) constructor.
+ */
+ basic_socket_ext(basic_socket_ext&& other)
+ : impl_(std::move(other.impl_))
+ {
+ }
+
+ /// Move-assign a basic_socket from another.
+ /**
+ * This assignment operator moves a socket from one object to another.
+ *
+ * @param other The other basic_socket object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket(const executor_type&) constructor.
+ */
+ basic_socket_ext& operator=(basic_socket_ext&& other)
+ {
+ impl_ = std::move(other.impl_);
+ return *this;
+ }
+
+ // All sockets have access to each other's implementations.
+ template <typename Protocol1, typename Executor1>
+ friend class basic_socket_ext;
+
+ /// Move-construct a basic_socket from a socket of another protocol type.
+ /**
+ * This constructor moves a socket from one object to another.
+ *
+ * @param other The other basic_socket object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket(const executor_type&) constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ basic_socket_ext(basic_socket_ext<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : impl_(std::move(other.impl_))
+ {
+ }
+
+ /// Move-assign a basic_socket from a socket of another protocol type.
+ /**
+ * This assignment operator moves a socket from one object to another.
+ *
+ * @param other The other basic_socket object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket(const executor_type&) constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_socket_ext&
+ >::type operator=(basic_socket_ext<Protocol1, Executor1> && other)
+ {
+ basic_socket_ext tmp(std::move(other));
+ impl_ = std::move(tmp.impl_);
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return impl_.get_executor();
+ }
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+ /// Get a reference to the lowest layer.
+ /**
+ * This function returns a reference to the lowest layer in a stack of
+ * layers. Since a basic_socket cannot contain any further layers, it simply
+ * returns a reference to itself.
+ *
+ * @return A reference to the lowest layer in the stack of layers. Ownership
+ * is not transferred to the caller.
+ */
+ lowest_layer_type& lowest_layer()
+ {
+ return *this;
+ }
+
+ /// Get a const reference to the lowest layer.
+ /**
+ * This function returns a const reference to the lowest layer in a stack of
+ * layers. Since a basic_socket cannot contain any further layers, it simply
+ * returns a reference to itself.
+ *
+ * @return A const reference to the lowest layer in the stack of layers.
+ * Ownership is not transferred to the caller.
+ */
+ const lowest_layer_type& lowest_layer() const
+ {
+ return *this;
+ }
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+ /// Open the socket using the specified protocol.
+ /**
+ * This function opens the socket so that it will use the specified protocol.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * socket.open(boost::asio::ip::tcp::v4());
+ * @endcode
+ */
+ void open(const protocol_type& protocol = protocol_type())
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Open the socket using the specified protocol.
+ /**
+ * This function opens the socket so that it will use the specified protocol.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::system::error_code ec;
+ * socket.open(boost::asio::ip::tcp::v4(), ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Assign an existing native socket to the socket.
+ /*
+ * This function opens the socket to hold an existing native socket.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @param native_socket A native socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void assign(const protocol_type& protocol,
+ const native_handle_type& native_socket)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_socket, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Assign an existing native socket to the socket.
+ /*
+ * This function opens the socket to hold an existing native socket.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @param native_socket A native socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
+ const native_handle_type& native_socket, boost::system::error_code& ec)
+ {
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_socket, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Determine whether the socket is open.
+ bool is_open() const
+ {
+ return impl_.get_service().is_open(impl_.get_implementation());
+ }
+
+ /// Close the socket.
+ /**
+ * This function is used to close the socket. Any asynchronous send, receive
+ * or connect operations will be cancelled immediately, and will complete
+ * with the boost::asio::error::operation_aborted error.
+ *
+ * @throws boost::system::system_error Thrown on failure. Note that, even if
+ * the function indicates an error, the underlying descriptor is closed.
+ *
+ * @note For portable behaviour with respect to graceful closure of a
+ * connected socket, call shutdown() before closing the socket.
+ */
+ void close()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "close");
+ }
+
+ /// Close the socket.
+ /**
+ * This function is used to close the socket. Any asynchronous send, receive
+ * or connect operations will be cancelled immediately, and will complete
+ * with the boost::asio::error::operation_aborted error.
+ *
+ * @param ec Set to indicate what error occurred, if any. Note that, even if
+ * the function indicates an error, the underlying descriptor is closed.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * socket.close(ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ *
+ * @note For portable behaviour with respect to graceful closure of a
+ * connected socket, call shutdown() before closing the socket.
+ */
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+ {
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Release ownership of the underlying native socket.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error. Ownership
+ * of the native socket is then transferred to the caller.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release()
+ {
+ boost::system::error_code ec;
+ native_handle_type s = impl_.get_service().release(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "release");
+ return s;
+ }
+
+ /// Release ownership of the underlying native socket.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error. Ownership
+ * of the native socket is then transferred to the caller.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release(boost::system::error_code& ec)
+ {
+ return impl_.get_service().release(impl_.get_implementation(), ec);
+ }
+
+ /// Get the native socket representation.
+ /**
+ * This function may be used to obtain the underlying representation of the
+ * socket. This is intended to allow access to native socket functionality
+ * that is not otherwise provided.
+ */
+ native_handle_type native_handle()
+ {
+ return impl_.get_service().native_handle(impl_.get_implementation());
+ }
+
+ /// Cancel all asynchronous operations associated with the socket.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note Calls to cancel() will always fail with
+ * boost::asio::error::operation_not_supported when run on Windows XP, Windows
+ * Server 2003, and earlier versions of Windows, unless
+ * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
+ * two issues that should be considered before enabling its use:
+ *
+ * @li It will only cancel asynchronous operations that were initiated in the
+ * current thread.
+ *
+ * @li It can appear to complete without error, but the request to cancel the
+ * unfinished operations may be silently ignored by the operating system.
+ * Whether it works or not seems to depend on the drivers that are installed.
+ *
+ * For portable cancellation, consider using one of the following
+ * alternatives:
+ *
+ * @li Disable asio's I/O completion port backend by defining
+ * BOOST_ASIO_DISABLE_IOCP.
+ *
+ * @li Use the close() function to simultaneously cancel the outstanding
+ * operations and close the socket.
+ *
+ * When running on Windows Vista, Windows Server 2008, and later, the
+ * CancelIoEx function is always used. This function does not have the
+ * problems described above.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
+ && !defined(BOOST_ASIO_ENABLE_CANCELIO)
+ __declspec(deprecated("By default, this function always fails with "
+ "operation_not_supported when used on Windows XP, Windows Server 2003, "
+ "or earlier. Consult documentation for details."))
+#endif
+ void cancel()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "cancel");
+ }
+
+ /// Cancel all asynchronous operations associated with the socket.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note Calls to cancel() will always fail with
+ * boost::asio::error::operation_not_supported when run on Windows XP, Windows
+ * Server 2003, and earlier versions of Windows, unless
+ * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
+ * two issues that should be considered before enabling its use:
+ *
+ * @li It will only cancel asynchronous operations that were initiated in the
+ * current thread.
+ *
+ * @li It can appear to complete without error, but the request to cancel the
+ * unfinished operations may be silently ignored by the operating system.
+ * Whether it works or not seems to depend on the drivers that are installed.
+ *
+ * For portable cancellation, consider using one of the following
+ * alternatives:
+ *
+ * @li Disable asio's I/O completion port backend by defining
+ * BOOST_ASIO_DISABLE_IOCP.
+ *
+ * @li Use the close() function to simultaneously cancel the outstanding
+ * operations and close the socket.
+ *
+ * When running on Windows Vista, Windows Server 2008, and later, the
+ * CancelIoEx function is always used. This function does not have the
+ * problems described above.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
+ && !defined(BOOST_ASIO_ENABLE_CANCELIO)
+ __declspec(deprecated("By default, this function always fails with "
+ "operation_not_supported when used on Windows XP, Windows Server 2003, "
+ "or earlier. Consult documentation for details."))
+#endif
+ BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
+ {
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Determine whether the socket is at the out-of-band data mark.
+ /**
+ * This function is used to check whether the socket input is currently
+ * positioned at the out-of-band data mark.
+ *
+ * @return A bool indicating whether the socket is at the out-of-band data
+ * mark.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ bool at_mark() const
+ {
+ boost::system::error_code ec;
+ bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "at_mark");
+ return b;
+ }
+
+ /// Determine whether the socket is at the out-of-band data mark.
+ /**
+ * This function is used to check whether the socket input is currently
+ * positioned at the out-of-band data mark.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @return A bool indicating whether the socket is at the out-of-band data
+ * mark.
+ */
+ bool at_mark(boost::system::error_code& ec) const
+ {
+ return impl_.get_service().at_mark(impl_.get_implementation(), ec);
+ }
+
+ /// Determine the number of bytes available for reading.
+ /**
+ * This function is used to determine the number of bytes that may be read
+ * without blocking.
+ *
+ * @return The number of bytes that may be read without blocking, or 0 if an
+ * error occurs.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ std::size_t available() const
+ {
+ boost::system::error_code ec;
+ std::size_t s = impl_.get_service().available(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "available");
+ return s;
+ }
+
+ /// Determine the number of bytes available for reading.
+ /**
+ * This function is used to determine the number of bytes that may be read
+ * without blocking.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @return The number of bytes that may be read without blocking, or 0 if an
+ * error occurs.
+ */
+ std::size_t available(boost::system::error_code& ec) const
+ {
+ return impl_.get_service().available(impl_.get_implementation(), ec);
+ }
+
+ /// Bind the socket to the given local endpoint.
+ /**
+ * This function binds the socket to the specified endpoint on the local
+ * machine.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket will
+ * be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * socket.open(boost::asio::ip::tcp::v4());
+ * socket.bind(boost::asio::ip::tcp::endpoint(
+ * boost::asio::ip::tcp::v4(), 12345));
+ * @endcode
+ */
+ void bind(const endpoint_type& endpoint)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ }
+
+ /// Bind the socket to the given local endpoint.
+ /**
+ * This function binds the socket to the specified endpoint on the local
+ * machine.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket will
+ * be bound.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * socket.open(boost::asio::ip::tcp::v4());
+ * boost::system::error_code ec;
+ * socket.bind(boost::asio::ip::tcp::endpoint(
+ * boost::asio::ip::tcp::v4(), 12345), ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Connect the socket to the specified endpoint.
+ /**
+ * This function is used to connect a socket to the specified remote endpoint.
+ * The function call will block until the connection is successfully made or
+ * an error occurs.
+ *
+ * The socket is automatically opened if it is not already open. If the
+ * connect fails, and the socket was automatically opened, the socket is
+ * not returned to the closed state.
+ *
+ * @param peer_endpoint The remote endpoint to which the socket will be
+ * connected.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint(
+ * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+ * socket.connect(endpoint);
+ * @endcode
+ */
+ void connect(const endpoint_type& peer_endpoint)
+ {
+ boost::system::error_code ec;
+ if (!is_open())
+ {
+ impl_.get_service().open(impl_.get_implementation(),
+ peer_endpoint.protocol(), ec);
+ boost::asio::detail::throw_error(ec, "connect");
+ }
+ impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
+ boost::asio::detail::throw_error(ec, "connect");
+ }
+
+ /// Connect the socket to the specified endpoint.
+ /**
+ * This function is used to connect a socket to the specified remote endpoint.
+ * The function call will block until the connection is successfully made or
+ * an error occurs.
+ *
+ * The socket is automatically opened if it is not already open. If the
+ * connect fails, and the socket was automatically opened, the socket is
+ * not returned to the closed state.
+ *
+ * @param peer_endpoint The remote endpoint to which the socket will be
+ * connected.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint(
+ * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+ * boost::system::error_code ec;
+ * socket.connect(endpoint, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint,
+ boost::system::error_code& ec)
+ {
+ if (!is_open())
+ {
+ impl_.get_service().open(impl_.get_implementation(),
+ peer_endpoint.protocol(), ec);
+ if (ec)
+ {
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+ }
+
+ impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Start an asynchronous connect.
+ /**
+ * This function is used to asynchronously connect a socket to the specified
+ * remote endpoint. The function call always returns immediately.
+ *
+ * The socket is automatically opened if it is not already open. If the
+ * connect fails, and the socket was automatically opened, the socket is
+ * not returned to the closed state.
+ *
+ * @param peer_endpoint The remote endpoint to which the socket will be
+ * connected. Copies will be made of the endpoint object as required.
+ *
+ * @param handler The handler to be called when the connection operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error // Result of operation
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void connect_handler(const boost::system::error_code& error)
+ * {
+ * if (!error)
+ * {
+ * // Connect succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint(
+ * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+ * socket.async_connect(endpoint, connect_handler);
+ * @endcode
+ */
+ template <typename ConnectHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
+ void (boost::system::error_code))
+ async_connect(const endpoint_type& peer_endpoint,
+ BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
+ {
+ boost::system::error_code open_ec;
+ if (!is_open())
+ {
+ const protocol_type protocol = peer_endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);
+ }
+
+ return async_initiate<ConnectHandler, void (boost::system::error_code)>(
+ initiate_async_connect(), handler, this, peer_endpoint, open_ec);
+ }
+
+ /// Set an option on the socket.
+ /**
+ * This function is used to set an option on the socket.
+ *
+ * @param option The new option value to be set on the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @sa SettableSocketOption @n
+ * boost::asio::socket_base::broadcast @n
+ * boost::asio::socket_base::do_not_route @n
+ * boost::asio::socket_base::keep_alive @n
+ * boost::asio::socket_base::linger @n
+ * boost::asio::socket_base::receive_buffer_size @n
+ * boost::asio::socket_base::receive_low_watermark @n
+ * boost::asio::socket_base::reuse_address @n
+ * boost::asio::socket_base::send_buffer_size @n
+ * boost::asio::socket_base::send_low_watermark @n
+ * boost::asio::ip::multicast::join_group @n
+ * boost::asio::ip::multicast::leave_group @n
+ * boost::asio::ip::multicast::enable_loopback @n
+ * boost::asio::ip::multicast::outbound_interface @n
+ * boost::asio::ip::multicast::hops @n
+ * boost::asio::ip::tcp::no_delay
+ *
+ * @par Example
+ * Setting the IPPROTO_TCP/TCP_NODELAY option:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::no_delay option(true);
+ * socket.set_option(option);
+ * @endcode
+ */
+ template <typename SettableSocketOption>
+ void set_option(const SettableSocketOption& option)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
+ boost::asio::detail::throw_error(ec, "set_option");
+ }
+
+ /// Set an option on the socket.
+ /**
+ * This function is used to set an option on the socket.
+ *
+ * @param option The new option value to be set on the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @sa SettableSocketOption @n
+ * boost::asio::socket_base::broadcast @n
+ * boost::asio::socket_base::do_not_route @n
+ * boost::asio::socket_base::keep_alive @n
+ * boost::asio::socket_base::linger @n
+ * boost::asio::socket_base::receive_buffer_size @n
+ * boost::asio::socket_base::receive_low_watermark @n
+ * boost::asio::socket_base::reuse_address @n
+ * boost::asio::socket_base::send_buffer_size @n
+ * boost::asio::socket_base::send_low_watermark @n
+ * boost::asio::ip::multicast::join_group @n
+ * boost::asio::ip::multicast::leave_group @n
+ * boost::asio::ip::multicast::enable_loopback @n
+ * boost::asio::ip::multicast::outbound_interface @n
+ * boost::asio::ip::multicast::hops @n
+ * boost::asio::ip::tcp::no_delay
+ *
+ * @par Example
+ * Setting the IPPROTO_TCP/TCP_NODELAY option:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::no_delay option(true);
+ * boost::system::error_code ec;
+ * socket.set_option(option, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename SettableSocketOption>
+ BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Get an option from the socket.
+ /**
+ * This function is used to get the current value of an option on the socket.
+ *
+ * @param option The option value to be obtained from the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @sa GettableSocketOption @n
+ * boost::asio::socket_base::broadcast @n
+ * boost::asio::socket_base::do_not_route @n
+ * boost::asio::socket_base::keep_alive @n
+ * boost::asio::socket_base::linger @n
+ * boost::asio::socket_base::receive_buffer_size @n
+ * boost::asio::socket_base::receive_low_watermark @n
+ * boost::asio::socket_base::reuse_address @n
+ * boost::asio::socket_base::send_buffer_size @n
+ * boost::asio::socket_base::send_low_watermark @n
+ * boost::asio::ip::multicast::join_group @n
+ * boost::asio::ip::multicast::leave_group @n
+ * boost::asio::ip::multicast::enable_loopback @n
+ * boost::asio::ip::multicast::outbound_interface @n
+ * boost::asio::ip::multicast::hops @n
+ * boost::asio::ip::tcp::no_delay
+ *
+ * @par Example
+ * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket::keep_alive option;
+ * socket.get_option(option);
+ * bool is_set = option.value();
+ * @endcode
+ */
+ template <typename GettableSocketOption>
+ void get_option(GettableSocketOption& option) const
+ {
+ boost::system::error_code ec;
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
+ boost::asio::detail::throw_error(ec, "get_option");
+ }
+
+ /// Get an option from the socket.
+ /**
+ * This function is used to get the current value of an option on the socket.
+ *
+ * @param option The option value to be obtained from the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @sa GettableSocketOption @n
+ * boost::asio::socket_base::broadcast @n
+ * boost::asio::socket_base::do_not_route @n
+ * boost::asio::socket_base::keep_alive @n
+ * boost::asio::socket_base::linger @n
+ * boost::asio::socket_base::receive_buffer_size @n
+ * boost::asio::socket_base::receive_low_watermark @n
+ * boost::asio::socket_base::reuse_address @n
+ * boost::asio::socket_base::send_buffer_size @n
+ * boost::asio::socket_base::send_low_watermark @n
+ * boost::asio::ip::multicast::join_group @n
+ * boost::asio::ip::multicast::leave_group @n
+ * boost::asio::ip::multicast::enable_loopback @n
+ * boost::asio::ip::multicast::outbound_interface @n
+ * boost::asio::ip::multicast::hops @n
+ * boost::asio::ip::tcp::no_delay
+ *
+ * @par Example
+ * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket::keep_alive option;
+ * boost::system::error_code ec;
+ * socket.get_option(option, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * bool is_set = option.value();
+ * @endcode
+ */
+ template <typename GettableSocketOption>
+ BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
+ boost::system::error_code& ec) const
+ {
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Perform an IO control command on the socket.
+ /**
+ * This function is used to execute an IO control command on the socket.
+ *
+ * @param command The IO control command to be performed on the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @sa IoControlCommand @n
+ * boost::asio::socket_base::bytes_readable @n
+ * boost::asio::socket_base::non_blocking_io
+ *
+ * @par Example
+ * Getting the number of bytes ready to read:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket::bytes_readable command;
+ * socket.io_control(command);
+ * std::size_t bytes_readable = command.get();
+ * @endcode
+ */
+ template <typename IoControlCommand>
+ void io_control(IoControlCommand& command)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
+ boost::asio::detail::throw_error(ec, "io_control");
+ }
+
+ /// Perform an IO control command on the socket.
+ /**
+ * This function is used to execute an IO control command on the socket.
+ *
+ * @param command The IO control command to be performed on the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @sa IoControlCommand @n
+ * boost::asio::socket_base::bytes_readable @n
+ * boost::asio::socket_base::non_blocking_io
+ *
+ * @par Example
+ * Getting the number of bytes ready to read:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket::bytes_readable command;
+ * boost::system::error_code ec;
+ * socket.io_control(command, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * std::size_t bytes_readable = command.get();
+ * @endcode
+ */
+ template <typename IoControlCommand>
+ BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Gets the non-blocking mode of the socket.
+ /**
+ * @returns @c true if the socket's synchronous operations will fail with
+ * boost::asio::error::would_block if they are unable to perform the requested
+ * operation immediately. If @c false, synchronous operations will block
+ * until complete.
+ *
+ * @note The non-blocking mode has no effect on the behaviour of asynchronous
+ * operations. Asynchronous operations will never fail with the error
+ * boost::asio::error::would_block.
+ */
+ bool non_blocking() const
+ {
+ return impl_.get_service().non_blocking(impl_.get_implementation());
+ }
+
+ /// Sets the non-blocking mode of the socket.
+ /**
+ * @param mode If @c true, the socket's synchronous operations will fail with
+ * boost::asio::error::would_block if they are unable to perform the requested
+ * operation immediately. If @c false, synchronous operations will block
+ * until complete.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note The non-blocking mode has no effect on the behaviour of asynchronous
+ * operations. Asynchronous operations will never fail with the error
+ * boost::asio::error::would_block.
+ */
+ void non_blocking(bool mode)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
+ boost::asio::detail::throw_error(ec, "non_blocking");
+ }
+
+ /// Sets the non-blocking mode of the socket.
+ /**
+ * @param mode If @c true, the socket's synchronous operations will fail with
+ * boost::asio::error::would_block if they are unable to perform the requested
+ * operation immediately. If @c false, synchronous operations will block
+ * until complete.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note The non-blocking mode has no effect on the behaviour of asynchronous
+ * operations. Asynchronous operations will never fail with the error
+ * boost::asio::error::would_block.
+ */
+ BOOST_ASIO_SYNC_OP_VOID non_blocking(
+ bool mode, boost::system::error_code& ec)
+ {
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Gets the non-blocking mode of the native socket implementation.
+ /**
+ * This function is used to retrieve the non-blocking mode of the underlying
+ * native socket. This mode has no effect on the behaviour of the socket
+ * object's synchronous operations.
+ *
+ * @returns @c true if the underlying socket is in non-blocking mode and
+ * direct system calls may fail with boost::asio::error::would_block (or the
+ * equivalent system error).
+ *
+ * @note The current non-blocking mode is cached by the socket object.
+ * Consequently, the return value may be incorrect if the non-blocking mode
+ * was set directly on the native socket.
+ *
+ * @par Example
+ * This function is intended to allow the encapsulation of arbitrary
+ * non-blocking system calls as asynchronous operations, in a way that is
+ * transparent to the user of the socket object. The following example
+ * illustrates how Linux's @c sendfile system call might be encapsulated:
+ * @code template <typename Handler>
+ * struct sendfile_op
+ * {
+ * tcp::socket& sock_;
+ * int fd_;
+ * Handler handler_;
+ * off_t offset_;
+ * std::size_t total_bytes_transferred_;
+ *
+ * // Function call operator meeting WriteHandler requirements.
+ * // Used as the handler for the async_write_some operation.
+ * void operator()(boost::system::error_code ec, std::size_t)
+ * {
+ * // Put the underlying socket into non-blocking mode.
+ * if (!ec)
+ * if (!sock_.native_non_blocking())
+ * sock_.native_non_blocking(true, ec);
+ *
+ * if (!ec)
+ * {
+ * for (;;)
+ * {
+ * // Try the system call.
+ * errno = 0;
+ * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ * ec = boost::system::error_code(n < 0 ? errno : 0,
+ * boost::asio::error::get_system_category());
+ * total_bytes_transferred_ += ec ? 0 : n;
+ *
+ * // Retry operation immediately if interrupted by signal.
+ * if (ec == boost::asio::error::interrupted)
+ * continue;
+ *
+ * // Check if we need to run the operation again.
+ * if (ec == boost::asio::error::would_block
+ * || ec == boost::asio::error::try_again)
+ * {
+ * // We have to wait for the socket to become ready again.
+ * sock_.async_wait(tcp::socket::wait_write, *this);
+ * return;
+ * }
+ *
+ * if (ec || n == 0)
+ * {
+ * // An error occurred, or we have reached the end of the file.
+ * // Either way we must exit the loop so we can call the handler.
+ * break;
+ * }
+ *
+ * // Loop around to try calling sendfile again.
+ * }
+ * }
+ *
+ * // Pass result back to user's handler.
+ * handler_(ec, total_bytes_transferred_);
+ * }
+ * };
+ *
+ * template <typename Handler>
+ * void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ * {
+ * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ * sock.async_wait(tcp::socket::wait_write, op);
+ * } @endcode
+ */
+ bool native_non_blocking() const
+ {
+ return impl_.get_service().native_non_blocking(impl_.get_implementation());
+ }
+
+ /// Sets the non-blocking mode of the native socket implementation.
+ /**
+ * This function is used to modify the non-blocking mode of the underlying
+ * native socket. It has no effect on the behaviour of the socket object's
+ * synchronous operations.
+ *
+ * @param mode If @c true, the underlying socket is put into non-blocking
+ * mode and direct system calls may fail with boost::asio::error::would_block
+ * (or the equivalent system error).
+ *
+ * @throws boost::system::system_error Thrown on failure. If the @c mode is
+ * @c false, but the current value of @c non_blocking() is @c true, this
+ * function fails with boost::asio::error::invalid_argument, as the
+ * combination does not make sense.
+ *
+ * @par Example
+ * This function is intended to allow the encapsulation of arbitrary
+ * non-blocking system calls as asynchronous operations, in a way that is
+ * transparent to the user of the socket object. The following example
+ * illustrates how Linux's @c sendfile system call might be encapsulated:
+ * @code template <typename Handler>
+ * struct sendfile_op
+ * {
+ * tcp::socket& sock_;
+ * int fd_;
+ * Handler handler_;
+ * off_t offset_;
+ * std::size_t total_bytes_transferred_;
+ *
+ * // Function call operator meeting WriteHandler requirements.
+ * // Used as the handler for the async_write_some operation.
+ * void operator()(boost::system::error_code ec, std::size_t)
+ * {
+ * // Put the underlying socket into non-blocking mode.
+ * if (!ec)
+ * if (!sock_.native_non_blocking())
+ * sock_.native_non_blocking(true, ec);
+ *
+ * if (!ec)
+ * {
+ * for (;;)
+ * {
+ * // Try the system call.
+ * errno = 0;
+ * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ * ec = boost::system::error_code(n < 0 ? errno : 0,
+ * boost::asio::error::get_system_category());
+ * total_bytes_transferred_ += ec ? 0 : n;
+ *
+ * // Retry operation immediately if interrupted by signal.
+ * if (ec == boost::asio::error::interrupted)
+ * continue;
+ *
+ * // Check if we need to run the operation again.
+ * if (ec == boost::asio::error::would_block
+ * || ec == boost::asio::error::try_again)
+ * {
+ * // We have to wait for the socket to become ready again.
+ * sock_.async_wait(tcp::socket::wait_write, *this);
+ * return;
+ * }
+ *
+ * if (ec || n == 0)
+ * {
+ * // An error occurred, or we have reached the end of the file.
+ * // Either way we must exit the loop so we can call the handler.
+ * break;
+ * }
+ *
+ * // Loop around to try calling sendfile again.
+ * }
+ * }
+ *
+ * // Pass result back to user's handler.
+ * handler_(ec, total_bytes_transferred_);
+ * }
+ * };
+ *
+ * template <typename Handler>
+ * void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ * {
+ * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ * sock.async_wait(tcp::socket::wait_write, op);
+ * } @endcode
+ */
+ void native_non_blocking(bool mode)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
+ boost::asio::detail::throw_error(ec, "native_non_blocking");
+ }
+
+ /// Sets the non-blocking mode of the native socket implementation.
+ /**
+ * This function is used to modify the non-blocking mode of the underlying
+ * native socket. It has no effect on the behaviour of the socket object's
+ * synchronous operations.
+ *
+ * @param mode If @c true, the underlying socket is put into non-blocking
+ * mode and direct system calls may fail with boost::asio::error::would_block
+ * (or the equivalent system error).
+ *
+ * @param ec Set to indicate what error occurred, if any. If the @c mode is
+ * @c false, but the current value of @c non_blocking() is @c true, this
+ * function fails with boost::asio::error::invalid_argument, as the
+ * combination does not make sense.
+ *
+ * @par Example
+ * This function is intended to allow the encapsulation of arbitrary
+ * non-blocking system calls as asynchronous operations, in a way that is
+ * transparent to the user of the socket object. The following example
+ * illustrates how Linux's @c sendfile system call might be encapsulated:
+ * @code template <typename Handler>
+ * struct sendfile_op
+ * {
+ * tcp::socket& sock_;
+ * int fd_;
+ * Handler handler_;
+ * off_t offset_;
+ * std::size_t total_bytes_transferred_;
+ *
+ * // Function call operator meeting WriteHandler requirements.
+ * // Used as the handler for the async_write_some operation.
+ * void operator()(boost::system::error_code ec, std::size_t)
+ * {
+ * // Put the underlying socket into non-blocking mode.
+ * if (!ec)
+ * if (!sock_.native_non_blocking())
+ * sock_.native_non_blocking(true, ec);
+ *
+ * if (!ec)
+ * {
+ * for (;;)
+ * {
+ * // Try the system call.
+ * errno = 0;
+ * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ * ec = boost::system::error_code(n < 0 ? errno : 0,
+ * boost::asio::error::get_system_category());
+ * total_bytes_transferred_ += ec ? 0 : n;
+ *
+ * // Retry operation immediately if interrupted by signal.
+ * if (ec == boost::asio::error::interrupted)
+ * continue;
+ *
+ * // Check if we need to run the operation again.
+ * if (ec == boost::asio::error::would_block
+ * || ec == boost::asio::error::try_again)
+ * {
+ * // We have to wait for the socket to become ready again.
+ * sock_.async_wait(tcp::socket::wait_write, *this);
+ * return;
+ * }
+ *
+ * if (ec || n == 0)
+ * {
+ * // An error occurred, or we have reached the end of the file.
+ * // Either way we must exit the loop so we can call the handler.
+ * break;
+ * }
+ *
+ * // Loop around to try calling sendfile again.
+ * }
+ * }
+ *
+ * // Pass result back to user's handler.
+ * handler_(ec, total_bytes_transferred_);
+ * }
+ * };
+ *
+ * template <typename Handler>
+ * void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ * {
+ * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ * sock.async_wait(tcp::socket::wait_write, op);
+ * } @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
+ bool mode, boost::system::error_code& ec)
+ {
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Get the local endpoint of the socket.
+ /**
+ * This function is used to obtain the locally bound endpoint of the socket.
+ *
+ * @returns An object that represents the local endpoint of the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
+ * @endcode
+ */
+ endpoint_type local_endpoint() const
+ {
+ boost::system::error_code ec;
+ endpoint_type ep = impl_.get_service().local_endpoint(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "local_endpoint");
+ return ep;
+ }
+
+ /// Get the local endpoint of the socket.
+ /**
+ * This function is used to obtain the locally bound endpoint of the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns An object that represents the local endpoint of the socket.
+ * Returns a default-constructed endpoint object if an error occurred.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ endpoint_type local_endpoint(boost::system::error_code& ec) const
+ {
+ return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
+ }
+
+ /// Get the remote endpoint of the socket.
+ /**
+ * This function is used to obtain the remote endpoint of the socket.
+ *
+ * @returns An object that represents the remote endpoint of the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
+ * @endcode
+ */
+ endpoint_type remote_endpoint() const
+ {
+ boost::system::error_code ec;
+ endpoint_type ep = impl_.get_service().remote_endpoint(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "remote_endpoint");
+ return ep;
+ }
+
+ /// Get the remote endpoint of the socket.
+ /**
+ * This function is used to obtain the remote endpoint of the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns An object that represents the remote endpoint of the socket.
+ * Returns a default-constructed endpoint object if an error occurred.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ endpoint_type remote_endpoint(boost::system::error_code& ec) const
+ {
+ return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec);
+ }
+
+ /// Disable sends or receives on the socket.
+ /**
+ * This function is used to disable send operations, receive operations, or
+ * both.
+ *
+ * @param what Determines what types of operation will no longer be allowed.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * Shutting down the send side of the socket:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
+ * @endcode
+ */
+ void shutdown(shutdown_type what)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
+ boost::asio::detail::throw_error(ec, "shutdown");
+ }
+
+ /// Disable sends or receives on the socket.
+ /**
+ * This function is used to disable send operations, receive operations, or
+ * both.
+ *
+ * @param what Determines what types of operation will no longer be allowed.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * Shutting down the send side of the socket:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Wait for the socket to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for a socket to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired socket state.
+ *
+ * @par Example
+ * Waiting for a socket to become readable.
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * socket.wait(boost::asio::ip::tcp::socket::wait_read);
+ * @endcode
+ */
+ void wait(wait_type w)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
+ boost::asio::detail::throw_error(ec, "wait");
+ }
+
+ /// Wait for the socket to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for a socket to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired socket state.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * Waiting for a socket to become readable.
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec);
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
+ {
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Asynchronously wait for the socket to become ready to read, ready to
+ /// write, or to have pending error conditions.
+ /**
+ * This function is used to perform an asynchronous wait for a socket to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired socket state.
+ *
+ * @param handler The handler to be called when the wait operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error // Result of operation
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void wait_handler(const boost::system::error_code& error)
+ * {
+ * if (!error)
+ * {
+ * // Wait succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
+ * @endcode
+ */
+ template <typename WaitHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+ void (boost::system::error_code))
+ async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+ {
+ return async_initiate<WaitHandler, void (boost::system::error_code)>(
+ initiate_async_wait(), handler, this, w);
+ }
+
+protected:
+ /// Protected destructor to prevent deletion through this type.
+ /**
+ * This function destroys the socket, cancelling any outstanding asynchronous
+ * operations associated with the socket as if by calling @c cancel.
+ */
+ ~basic_socket_ext()
+ {
+ }
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ detail::io_object_impl<
+ detail::null_socket_service<Protocol>, Executor> impl_;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ detail::io_object_impl<
+ detail::win_iocp_socket_service<Protocol>, Executor> impl_;
+#else
+ detail::io_object_impl<
+ detail::reactive_socket_service_ext<Protocol>, Executor> impl_;
+#endif
+
+private:
+ // Disallow copying and assignment.
+ basic_socket_ext(const basic_socket_ext&) BOOST_ASIO_DELETED;
+ basic_socket_ext& operator=(const basic_socket_ext&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_connect
+ {
+ template <typename ConnectHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler,
+ basic_socket_ext* self, const endpoint_type& peer_endpoint,
+ const boost::system::error_code& open_ec) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ConnectHandler.
+ BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
+
+ if (open_ec)
+ {
+ boost::asio::post(self->impl_.get_executor(),
+ boost::asio::detail::bind_handler(
+ BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));
+ }
+ else
+ {
+ detail::non_const_lvalue<ConnectHandler> handler2(handler);
+ self->impl_.get_service().async_connect(
+ self->impl_.get_implementation(), peer_endpoint,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ }
+ };
+
+ struct initiate_async_wait
+ {
+ template <typename WaitHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
+ basic_socket_ext* self, wait_type w) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+ detail::non_const_lvalue<WaitHandler> handler2(handler);
+ self->impl_.get_service().async_wait(
+ self->impl_.get_implementation(), w, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp b/implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp
new file mode 100644
index 0000000..2c898fc
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp
@@ -0,0 +1,1859 @@
+//
+// basic_socket_ext_local.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP
+#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/handler_type_requirements_ext.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
+#include <boost/asio/post.hpp>
+#include <boost/asio/socket_base.hpp>
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/null_socket_service.hpp>
+#elif defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_socket_service.hpp>
+#else
+# include <boost/asio/detail/reactive_socket_service_ext_local.hpp>
+#endif
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_socket_ext_local;
+
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL)
+
+/// Provides socket functionality.
+/**
+ * The basic_socket class template provides functionality that is common to both
+ * stream-oriented and datagram-oriented sockets.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename Protocol, typename Executor>
+class basic_socket_ext_local
+ : public socket_base
+{
+public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// Rebinds the socket type to another executor.
+ template <typename Executor1>
+ struct rebind_executor
+ {
+ /// The socket type when rebound to the specified executor.
+ typedef basic_socket_ext_local<Protocol, Executor1> other;
+ };
+
+ /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#elif defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ typedef typename detail::null_socket_service<
+ Protocol>::native_handle_type native_handle_type;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ typedef typename detail::win_iocp_socket_service<
+ Protocol>::native_handle_type native_handle_type;
+#else
+ typedef typename detail::reactive_socket_service_ext_local<
+ Protocol>::native_handle_type native_handle_type;
+#endif
+
+ /// The protocol type.
+ typedef Protocol protocol_type;
+
+ /// The endpoint type.
+ typedef typename Protocol::endpoint endpoint_type;
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+ /// A basic_socket is always the lowest layer.
+ typedef basic_socket_ext_local<Protocol, Executor> lowest_layer_type;
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+ /// Construct a basic_socket without opening it.
+ /**
+ * This constructor creates a socket without opening it.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ */
+ explicit basic_socket_ext_local(const executor_type& ex)
+ : impl_(0, ex)
+ {
+ }
+
+ /// Construct a basic_socket without opening it.
+ /**
+ * This constructor creates a socket without opening it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ */
+ template <typename ExecutionContext>
+ explicit basic_socket_ext_local(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ }
+
+ /// Construct and open a basic_socket.
+ /**
+ * This constructor creates and opens a socket.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol)
+ : impl_(0, ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct and open a basic_socket.
+ /**
+ * This constructor creates and opens a socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct a basic_socket, opening it and binding it to the given local
+ /// endpoint.
+ /**
+ * This constructor creates a socket and automatically opens it bound to the
+ * specified endpoint on the local machine. The protocol used is the protocol
+ * associated with the given endpoint.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket will
+ * be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_socket_ext_local(const executor_type& ex, const endpoint_type& endpoint)
+ : impl_(0, ex)
+ {
+ boost::system::error_code ec;
+ const protocol_type protocol = endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ }
+
+ /// Construct a basic_socket, opening it and binding it to the given local
+ /// endpoint.
+ /**
+ * This constructor creates a socket and automatically opens it bound to the
+ * specified endpoint on the local machine. The protocol used is the protocol
+ * associated with the given endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket will
+ * be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ boost::system::error_code ec;
+ const protocol_type protocol = endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ }
+
+ /// Construct a basic_socket on an existing native socket.
+ /**
+ * This constructor creates a socket object to hold an existing native socket.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket A native socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol,
+ const native_handle_type& native_socket)
+ : impl_(0, ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_socket, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Construct a basic_socket on an existing native socket.
+ /**
+ * This constructor creates a socket object to hold an existing native socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket A native socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol,
+ const native_handle_type& native_socket,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(0, 0, context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_socket, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct a basic_socket from another.
+ /**
+ * This constructor moves a socket from one object to another.
+ *
+ * @param other The other basic_socket object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket(const executor_type&) constructor.
+ */
+ basic_socket_ext_local(basic_socket_ext_local&& other)
+ : impl_(std::move(other.impl_))
+ {
+ }
+
+ /// Move-assign a basic_socket from another.
+ /**
+ * This assignment operator moves a socket from one object to another.
+ *
+ * @param other The other basic_socket object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket(const executor_type&) constructor.
+ */
+ basic_socket_ext_local& operator=(basic_socket_ext_local&& other)
+ {
+ impl_ = std::move(other.impl_);
+ return *this;
+ }
+
+ // All sockets have access to each other's implementations.
+ template <typename Protocol1, typename Executor1>
+ friend class basic_socket_ext_local;
+
+ /// Move-construct a basic_socket from a socket of another protocol type.
+ /**
+ * This constructor moves a socket from one object to another.
+ *
+ * @param other The other basic_socket object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket(const executor_type&) constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ basic_socket_ext_local(basic_socket_ext_local<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : impl_(std::move(other.impl_))
+ {
+ }
+
+ /// Move-assign a basic_socket from a socket of another protocol type.
+ /**
+ * This assignment operator moves a socket from one object to another.
+ *
+ * @param other The other basic_socket object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_socket(const executor_type&) constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_socket_ext_local&
+ >::type operator=(basic_socket_ext_local<Protocol1, Executor1> && other)
+ {
+ basic_socket_ext_local tmp(std::move(other));
+ impl_ = std::move(tmp.impl_);
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return impl_.get_executor();
+ }
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+ /// Get a reference to the lowest layer.
+ /**
+ * This function returns a reference to the lowest layer in a stack of
+ * layers. Since a basic_socket cannot contain any further layers, it simply
+ * returns a reference to itself.
+ *
+ * @return A reference to the lowest layer in the stack of layers. Ownership
+ * is not transferred to the caller.
+ */
+ lowest_layer_type& lowest_layer()
+ {
+ return *this;
+ }
+
+ /// Get a const reference to the lowest layer.
+ /**
+ * This function returns a const reference to the lowest layer in a stack of
+ * layers. Since a basic_socket cannot contain any further layers, it simply
+ * returns a reference to itself.
+ *
+ * @return A const reference to the lowest layer in the stack of layers.
+ * Ownership is not transferred to the caller.
+ */
+ const lowest_layer_type& lowest_layer() const
+ {
+ return *this;
+ }
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+ /// Open the socket using the specified protocol.
+ /**
+ * This function opens the socket so that it will use the specified protocol.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * socket.open(boost::asio::ip::tcp::v4());
+ * @endcode
+ */
+ void open(const protocol_type& protocol = protocol_type())
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Open the socket using the specified protocol.
+ /**
+ * This function opens the socket so that it will use the specified protocol.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::system::error_code ec;
+ * socket.open(boost::asio::ip::tcp::v4(), ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Assign an existing native socket to the socket.
+ /*
+ * This function opens the socket to hold an existing native socket.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @param native_socket A native socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void assign(const protocol_type& protocol,
+ const native_handle_type& native_socket)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_socket, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Assign an existing native socket to the socket.
+ /*
+ * This function opens the socket to hold an existing native socket.
+ *
+ * @param protocol An object specifying which protocol is to be used.
+ *
+ * @param native_socket A native socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
+ const native_handle_type& native_socket, boost::system::error_code& ec)
+ {
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_socket, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Determine whether the socket is open.
+ bool is_open() const
+ {
+ return impl_.get_service().is_open(impl_.get_implementation());
+ }
+
+ /// Close the socket.
+ /**
+ * This function is used to close the socket. Any asynchronous send, receive
+ * or connect operations will be cancelled immediately, and will complete
+ * with the boost::asio::error::operation_aborted error.
+ *
+ * @throws boost::system::system_error Thrown on failure. Note that, even if
+ * the function indicates an error, the underlying descriptor is closed.
+ *
+ * @note For portable behaviour with respect to graceful closure of a
+ * connected socket, call shutdown() before closing the socket.
+ */
+ void close()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "close");
+ }
+
+ /// Close the socket.
+ /**
+ * This function is used to close the socket. Any asynchronous send, receive
+ * or connect operations will be cancelled immediately, and will complete
+ * with the boost::asio::error::operation_aborted error.
+ *
+ * @param ec Set to indicate what error occurred, if any. Note that, even if
+ * the function indicates an error, the underlying descriptor is closed.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * socket.close(ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ *
+ * @note For portable behaviour with respect to graceful closure of a
+ * connected socket, call shutdown() before closing the socket.
+ */
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+ {
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Release ownership of the underlying native socket.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error. Ownership
+ * of the native socket is then transferred to the caller.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release()
+ {
+ boost::system::error_code ec;
+ native_handle_type s = impl_.get_service().release(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "release");
+ return s;
+ }
+
+ /// Release ownership of the underlying native socket.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error. Ownership
+ * of the native socket is then transferred to the caller.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note This function is unsupported on Windows versions prior to Windows
+ * 8.1, and will fail with boost::asio::error::operation_not_supported on
+ * these platforms.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+ __declspec(deprecated("This function always fails with "
+ "operation_not_supported when used on Windows versions "
+ "prior to Windows 8.1."))
+#endif
+ native_handle_type release(boost::system::error_code& ec)
+ {
+ return impl_.get_service().release(impl_.get_implementation(), ec);
+ }
+
+ /// Get the native socket representation.
+ /**
+ * This function may be used to obtain the underlying representation of the
+ * socket. This is intended to allow access to native socket functionality
+ * that is not otherwise provided.
+ */
+ native_handle_type native_handle()
+ {
+ return impl_.get_service().native_handle(impl_.get_implementation());
+ }
+
+ /// Cancel all asynchronous operations associated with the socket.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note Calls to cancel() will always fail with
+ * boost::asio::error::operation_not_supported when run on Windows XP, Windows
+ * Server 2003, and earlier versions of Windows, unless
+ * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
+ * two issues that should be considered before enabling its use:
+ *
+ * @li It will only cancel asynchronous operations that were initiated in the
+ * current thread.
+ *
+ * @li It can appear to complete without error, but the request to cancel the
+ * unfinished operations may be silently ignored by the operating system.
+ * Whether it works or not seems to depend on the drivers that are installed.
+ *
+ * For portable cancellation, consider using one of the following
+ * alternatives:
+ *
+ * @li Disable asio's I/O completion port backend by defining
+ * BOOST_ASIO_DISABLE_IOCP.
+ *
+ * @li Use the close() function to simultaneously cancel the outstanding
+ * operations and close the socket.
+ *
+ * When running on Windows Vista, Windows Server 2008, and later, the
+ * CancelIoEx function is always used. This function does not have the
+ * problems described above.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
+ && !defined(BOOST_ASIO_ENABLE_CANCELIO)
+ __declspec(deprecated("By default, this function always fails with "
+ "operation_not_supported when used on Windows XP, Windows Server 2003, "
+ "or earlier. Consult documentation for details."))
+#endif
+ void cancel()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "cancel");
+ }
+
+ /// Cancel all asynchronous operations associated with the socket.
+ /**
+ * This function causes all outstanding asynchronous connect, send and receive
+ * operations to finish immediately, and the handlers for cancelled operations
+ * will be passed the boost::asio::error::operation_aborted error.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note Calls to cancel() will always fail with
+ * boost::asio::error::operation_not_supported when run on Windows XP, Windows
+ * Server 2003, and earlier versions of Windows, unless
+ * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
+ * two issues that should be considered before enabling its use:
+ *
+ * @li It will only cancel asynchronous operations that were initiated in the
+ * current thread.
+ *
+ * @li It can appear to complete without error, but the request to cancel the
+ * unfinished operations may be silently ignored by the operating system.
+ * Whether it works or not seems to depend on the drivers that are installed.
+ *
+ * For portable cancellation, consider using one of the following
+ * alternatives:
+ *
+ * @li Disable asio's I/O completion port backend by defining
+ * BOOST_ASIO_DISABLE_IOCP.
+ *
+ * @li Use the close() function to simultaneously cancel the outstanding
+ * operations and close the socket.
+ *
+ * When running on Windows Vista, Windows Server 2008, and later, the
+ * CancelIoEx function is always used. This function does not have the
+ * problems described above.
+ */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+ && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
+ && !defined(BOOST_ASIO_ENABLE_CANCELIO)
+ __declspec(deprecated("By default, this function always fails with "
+ "operation_not_supported when used on Windows XP, Windows Server 2003, "
+ "or earlier. Consult documentation for details."))
+#endif
+ BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
+ {
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Determine whether the socket is at the out-of-band data mark.
+ /**
+ * This function is used to check whether the socket input is currently
+ * positioned at the out-of-band data mark.
+ *
+ * @return A bool indicating whether the socket is at the out-of-band data
+ * mark.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ bool at_mark() const
+ {
+ boost::system::error_code ec;
+ bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "at_mark");
+ return b;
+ }
+
+ /// Determine whether the socket is at the out-of-band data mark.
+ /**
+ * This function is used to check whether the socket input is currently
+ * positioned at the out-of-band data mark.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @return A bool indicating whether the socket is at the out-of-band data
+ * mark.
+ */
+ bool at_mark(boost::system::error_code& ec) const
+ {
+ return impl_.get_service().at_mark(impl_.get_implementation(), ec);
+ }
+
+ /// Determine the number of bytes available for reading.
+ /**
+ * This function is used to determine the number of bytes that may be read
+ * without blocking.
+ *
+ * @return The number of bytes that may be read without blocking, or 0 if an
+ * error occurs.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ std::size_t available() const
+ {
+ boost::system::error_code ec;
+ std::size_t s = impl_.get_service().available(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "available");
+ return s;
+ }
+
+ /// Determine the number of bytes available for reading.
+ /**
+ * This function is used to determine the number of bytes that may be read
+ * without blocking.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @return The number of bytes that may be read without blocking, or 0 if an
+ * error occurs.
+ */
+ std::size_t available(boost::system::error_code& ec) const
+ {
+ return impl_.get_service().available(impl_.get_implementation(), ec);
+ }
+
+ /// Bind the socket to the given local endpoint.
+ /**
+ * This function binds the socket to the specified endpoint on the local
+ * machine.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket will
+ * be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * socket.open(boost::asio::ip::tcp::v4());
+ * socket.bind(boost::asio::ip::tcp::endpoint(
+ * boost::asio::ip::tcp::v4(), 12345));
+ * @endcode
+ */
+ void bind(const endpoint_type& endpoint)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ }
+
+ /// Bind the socket to the given local endpoint.
+ /**
+ * This function binds the socket to the specified endpoint on the local
+ * machine.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket will
+ * be bound.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * socket.open(boost::asio::ip::tcp::v4());
+ * boost::system::error_code ec;
+ * socket.bind(boost::asio::ip::tcp::endpoint(
+ * boost::asio::ip::tcp::v4(), 12345), ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Connect the socket to the specified endpoint.
+ /**
+ * This function is used to connect a socket to the specified remote endpoint.
+ * The function call will block until the connection is successfully made or
+ * an error occurs.
+ *
+ * The socket is automatically opened if it is not already open. If the
+ * connect fails, and the socket was automatically opened, the socket is
+ * not returned to the closed state.
+ *
+ * @param peer_endpoint The remote endpoint to which the socket will be
+ * connected.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint(
+ * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+ * socket.connect(endpoint);
+ * @endcode
+ */
+ void connect(const endpoint_type& peer_endpoint)
+ {
+ boost::system::error_code ec;
+ if (!is_open())
+ {
+ impl_.get_service().open(impl_.get_implementation(),
+ peer_endpoint.protocol(), ec);
+ boost::asio::detail::throw_error(ec, "connect");
+ }
+ impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
+ boost::asio::detail::throw_error(ec, "connect");
+ }
+
+ /// Connect the socket to the specified endpoint.
+ /**
+ * This function is used to connect a socket to the specified remote endpoint.
+ * The function call will block until the connection is successfully made or
+ * an error occurs.
+ *
+ * The socket is automatically opened if it is not already open. If the
+ * connect fails, and the socket was automatically opened, the socket is
+ * not returned to the closed state.
+ *
+ * @param peer_endpoint The remote endpoint to which the socket will be
+ * connected.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint(
+ * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+ * boost::system::error_code ec;
+ * socket.connect(endpoint, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint,
+ boost::system::error_code& ec)
+ {
+ if (!is_open())
+ {
+ impl_.get_service().open(impl_.get_implementation(),
+ peer_endpoint.protocol(), ec);
+ if (ec)
+ {
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+ }
+
+ impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Start an asynchronous connect.
+ /**
+ * This function is used to asynchronously connect a socket to the specified
+ * remote endpoint. The function call always returns immediately.
+ *
+ * The socket is automatically opened if it is not already open. If the
+ * connect fails, and the socket was automatically opened, the socket is
+ * not returned to the closed state.
+ *
+ * @param peer_endpoint The remote endpoint to which the socket will be
+ * connected. Copies will be made of the endpoint object as required.
+ *
+ * @param handler The handler to be called when the connection operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error // Result of operation
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void connect_handler(const boost::system::error_code& error)
+ * {
+ * if (!error)
+ * {
+ * // Connect succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * boost::asio::ip::tcp::endpoint endpoint(
+ * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+ * socket.async_connect(endpoint, connect_handler);
+ * @endcode
+ */
+ template <typename ConnectHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
+ void (boost::system::error_code))
+ async_connect(const endpoint_type& peer_endpoint,
+ BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
+ {
+ boost::system::error_code open_ec;
+ if (!is_open())
+ {
+ const protocol_type protocol = peer_endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);
+ }
+
+ return async_initiate<ConnectHandler, void (boost::system::error_code)>(
+ initiate_async_connect(), handler, this, peer_endpoint, open_ec);
+ }
+
+ /// Set an option on the socket.
+ /**
+ * This function is used to set an option on the socket.
+ *
+ * @param option The new option value to be set on the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @sa SettableSocketOption @n
+ * boost::asio::socket_base::broadcast @n
+ * boost::asio::socket_base::do_not_route @n
+ * boost::asio::socket_base::keep_alive @n
+ * boost::asio::socket_base::linger @n
+ * boost::asio::socket_base::receive_buffer_size @n
+ * boost::asio::socket_base::receive_low_watermark @n
+ * boost::asio::socket_base::reuse_address @n
+ * boost::asio::socket_base::send_buffer_size @n
+ * boost::asio::socket_base::send_low_watermark @n
+ * boost::asio::ip::multicast::join_group @n
+ * boost::asio::ip::multicast::leave_group @n
+ * boost::asio::ip::multicast::enable_loopback @n
+ * boost::asio::ip::multicast::outbound_interface @n
+ * boost::asio::ip::multicast::hops @n
+ * boost::asio::ip::tcp::no_delay
+ *
+ * @par Example
+ * Setting the IPPROTO_TCP/TCP_NODELAY option:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::no_delay option(true);
+ * socket.set_option(option);
+ * @endcode
+ */
+ template <typename SettableSocketOption>
+ void set_option(const SettableSocketOption& option)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
+ boost::asio::detail::throw_error(ec, "set_option");
+ }
+
+ /// Set an option on the socket.
+ /**
+ * This function is used to set an option on the socket.
+ *
+ * @param option The new option value to be set on the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @sa SettableSocketOption @n
+ * boost::asio::socket_base::broadcast @n
+ * boost::asio::socket_base::do_not_route @n
+ * boost::asio::socket_base::keep_alive @n
+ * boost::asio::socket_base::linger @n
+ * boost::asio::socket_base::receive_buffer_size @n
+ * boost::asio::socket_base::receive_low_watermark @n
+ * boost::asio::socket_base::reuse_address @n
+ * boost::asio::socket_base::send_buffer_size @n
+ * boost::asio::socket_base::send_low_watermark @n
+ * boost::asio::ip::multicast::join_group @n
+ * boost::asio::ip::multicast::leave_group @n
+ * boost::asio::ip::multicast::enable_loopback @n
+ * boost::asio::ip::multicast::outbound_interface @n
+ * boost::asio::ip::multicast::hops @n
+ * boost::asio::ip::tcp::no_delay
+ *
+ * @par Example
+ * Setting the IPPROTO_TCP/TCP_NODELAY option:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::no_delay option(true);
+ * boost::system::error_code ec;
+ * socket.set_option(option, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename SettableSocketOption>
+ BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Get an option from the socket.
+ /**
+ * This function is used to get the current value of an option on the socket.
+ *
+ * @param option The option value to be obtained from the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @sa GettableSocketOption @n
+ * boost::asio::socket_base::broadcast @n
+ * boost::asio::socket_base::do_not_route @n
+ * boost::asio::socket_base::keep_alive @n
+ * boost::asio::socket_base::linger @n
+ * boost::asio::socket_base::receive_buffer_size @n
+ * boost::asio::socket_base::receive_low_watermark @n
+ * boost::asio::socket_base::reuse_address @n
+ * boost::asio::socket_base::send_buffer_size @n
+ * boost::asio::socket_base::send_low_watermark @n
+ * boost::asio::ip::multicast::join_group @n
+ * boost::asio::ip::multicast::leave_group @n
+ * boost::asio::ip::multicast::enable_loopback @n
+ * boost::asio::ip::multicast::outbound_interface @n
+ * boost::asio::ip::multicast::hops @n
+ * boost::asio::ip::tcp::no_delay
+ *
+ * @par Example
+ * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket::keep_alive option;
+ * socket.get_option(option);
+ * bool is_set = option.value();
+ * @endcode
+ */
+ template <typename GettableSocketOption>
+ void get_option(GettableSocketOption& option) const
+ {
+ boost::system::error_code ec;
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
+ boost::asio::detail::throw_error(ec, "get_option");
+ }
+
+ /// Get an option from the socket.
+ /**
+ * This function is used to get the current value of an option on the socket.
+ *
+ * @param option The option value to be obtained from the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @sa GettableSocketOption @n
+ * boost::asio::socket_base::broadcast @n
+ * boost::asio::socket_base::do_not_route @n
+ * boost::asio::socket_base::keep_alive @n
+ * boost::asio::socket_base::linger @n
+ * boost::asio::socket_base::receive_buffer_size @n
+ * boost::asio::socket_base::receive_low_watermark @n
+ * boost::asio::socket_base::reuse_address @n
+ * boost::asio::socket_base::send_buffer_size @n
+ * boost::asio::socket_base::send_low_watermark @n
+ * boost::asio::ip::multicast::join_group @n
+ * boost::asio::ip::multicast::leave_group @n
+ * boost::asio::ip::multicast::enable_loopback @n
+ * boost::asio::ip::multicast::outbound_interface @n
+ * boost::asio::ip::multicast::hops @n
+ * boost::asio::ip::tcp::no_delay
+ *
+ * @par Example
+ * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket::keep_alive option;
+ * boost::system::error_code ec;
+ * socket.get_option(option, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * bool is_set = option.value();
+ * @endcode
+ */
+ template <typename GettableSocketOption>
+ BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
+ boost::system::error_code& ec) const
+ {
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Perform an IO control command on the socket.
+ /**
+ * This function is used to execute an IO control command on the socket.
+ *
+ * @param command The IO control command to be performed on the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @sa IoControlCommand @n
+ * boost::asio::socket_base::bytes_readable @n
+ * boost::asio::socket_base::non_blocking_io
+ *
+ * @par Example
+ * Getting the number of bytes ready to read:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket::bytes_readable command;
+ * socket.io_control(command);
+ * std::size_t bytes_readable = command.get();
+ * @endcode
+ */
+ template <typename IoControlCommand>
+ void io_control(IoControlCommand& command)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
+ boost::asio::detail::throw_error(ec, "io_control");
+ }
+
+ /// Perform an IO control command on the socket.
+ /**
+ * This function is used to execute an IO control command on the socket.
+ *
+ * @param command The IO control command to be performed on the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @sa IoControlCommand @n
+ * boost::asio::socket_base::bytes_readable @n
+ * boost::asio::socket_base::non_blocking_io
+ *
+ * @par Example
+ * Getting the number of bytes ready to read:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket::bytes_readable command;
+ * boost::system::error_code ec;
+ * socket.io_control(command, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * std::size_t bytes_readable = command.get();
+ * @endcode
+ */
+ template <typename IoControlCommand>
+ BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Gets the non-blocking mode of the socket.
+ /**
+ * @returns @c true if the socket's synchronous operations will fail with
+ * boost::asio::error::would_block if they are unable to perform the requested
+ * operation immediately. If @c false, synchronous operations will block
+ * until complete.
+ *
+ * @note The non-blocking mode has no effect on the behaviour of asynchronous
+ * operations. Asynchronous operations will never fail with the error
+ * boost::asio::error::would_block.
+ */
+ bool non_blocking() const
+ {
+ return impl_.get_service().non_blocking(impl_.get_implementation());
+ }
+
+ /// Sets the non-blocking mode of the socket.
+ /**
+ * @param mode If @c true, the socket's synchronous operations will fail with
+ * boost::asio::error::would_block if they are unable to perform the requested
+ * operation immediately. If @c false, synchronous operations will block
+ * until complete.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note The non-blocking mode has no effect on the behaviour of asynchronous
+ * operations. Asynchronous operations will never fail with the error
+ * boost::asio::error::would_block.
+ */
+ void non_blocking(bool mode)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
+ boost::asio::detail::throw_error(ec, "non_blocking");
+ }
+
+ /// Sets the non-blocking mode of the socket.
+ /**
+ * @param mode If @c true, the socket's synchronous operations will fail with
+ * boost::asio::error::would_block if they are unable to perform the requested
+ * operation immediately. If @c false, synchronous operations will block
+ * until complete.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @note The non-blocking mode has no effect on the behaviour of asynchronous
+ * operations. Asynchronous operations will never fail with the error
+ * boost::asio::error::would_block.
+ */
+ BOOST_ASIO_SYNC_OP_VOID non_blocking(
+ bool mode, boost::system::error_code& ec)
+ {
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Gets the non-blocking mode of the native socket implementation.
+ /**
+ * This function is used to retrieve the non-blocking mode of the underlying
+ * native socket. This mode has no effect on the behaviour of the socket
+ * object's synchronous operations.
+ *
+ * @returns @c true if the underlying socket is in non-blocking mode and
+ * direct system calls may fail with boost::asio::error::would_block (or the
+ * equivalent system error).
+ *
+ * @note The current non-blocking mode is cached by the socket object.
+ * Consequently, the return value may be incorrect if the non-blocking mode
+ * was set directly on the native socket.
+ *
+ * @par Example
+ * This function is intended to allow the encapsulation of arbitrary
+ * non-blocking system calls as asynchronous operations, in a way that is
+ * transparent to the user of the socket object. The following example
+ * illustrates how Linux's @c sendfile system call might be encapsulated:
+ * @code template <typename Handler>
+ * struct sendfile_op
+ * {
+ * tcp::socket& sock_;
+ * int fd_;
+ * Handler handler_;
+ * off_t offset_;
+ * std::size_t total_bytes_transferred_;
+ *
+ * // Function call operator meeting WriteHandler requirements.
+ * // Used as the handler for the async_write_some operation.
+ * void operator()(boost::system::error_code ec, std::size_t)
+ * {
+ * // Put the underlying socket into non-blocking mode.
+ * if (!ec)
+ * if (!sock_.native_non_blocking())
+ * sock_.native_non_blocking(true, ec);
+ *
+ * if (!ec)
+ * {
+ * for (;;)
+ * {
+ * // Try the system call.
+ * errno = 0;
+ * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ * ec = boost::system::error_code(n < 0 ? errno : 0,
+ * boost::asio::error::get_system_category());
+ * total_bytes_transferred_ += ec ? 0 : n;
+ *
+ * // Retry operation immediately if interrupted by signal.
+ * if (ec == boost::asio::error::interrupted)
+ * continue;
+ *
+ * // Check if we need to run the operation again.
+ * if (ec == boost::asio::error::would_block
+ * || ec == boost::asio::error::try_again)
+ * {
+ * // We have to wait for the socket to become ready again.
+ * sock_.async_wait(tcp::socket::wait_write, *this);
+ * return;
+ * }
+ *
+ * if (ec || n == 0)
+ * {
+ * // An error occurred, or we have reached the end of the file.
+ * // Either way we must exit the loop so we can call the handler.
+ * break;
+ * }
+ *
+ * // Loop around to try calling sendfile again.
+ * }
+ * }
+ *
+ * // Pass result back to user's handler.
+ * handler_(ec, total_bytes_transferred_);
+ * }
+ * };
+ *
+ * template <typename Handler>
+ * void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ * {
+ * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ * sock.async_wait(tcp::socket::wait_write, op);
+ * } @endcode
+ */
+ bool native_non_blocking() const
+ {
+ return impl_.get_service().native_non_blocking(impl_.get_implementation());
+ }
+
+ /// Sets the non-blocking mode of the native socket implementation.
+ /**
+ * This function is used to modify the non-blocking mode of the underlying
+ * native socket. It has no effect on the behaviour of the socket object's
+ * synchronous operations.
+ *
+ * @param mode If @c true, the underlying socket is put into non-blocking
+ * mode and direct system calls may fail with boost::asio::error::would_block
+ * (or the equivalent system error).
+ *
+ * @throws boost::system::system_error Thrown on failure. If the @c mode is
+ * @c false, but the current value of @c non_blocking() is @c true, this
+ * function fails with boost::asio::error::invalid_argument, as the
+ * combination does not make sense.
+ *
+ * @par Example
+ * This function is intended to allow the encapsulation of arbitrary
+ * non-blocking system calls as asynchronous operations, in a way that is
+ * transparent to the user of the socket object. The following example
+ * illustrates how Linux's @c sendfile system call might be encapsulated:
+ * @code template <typename Handler>
+ * struct sendfile_op
+ * {
+ * tcp::socket& sock_;
+ * int fd_;
+ * Handler handler_;
+ * off_t offset_;
+ * std::size_t total_bytes_transferred_;
+ *
+ * // Function call operator meeting WriteHandler requirements.
+ * // Used as the handler for the async_write_some operation.
+ * void operator()(boost::system::error_code ec, std::size_t)
+ * {
+ * // Put the underlying socket into non-blocking mode.
+ * if (!ec)
+ * if (!sock_.native_non_blocking())
+ * sock_.native_non_blocking(true, ec);
+ *
+ * if (!ec)
+ * {
+ * for (;;)
+ * {
+ * // Try the system call.
+ * errno = 0;
+ * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ * ec = boost::system::error_code(n < 0 ? errno : 0,
+ * boost::asio::error::get_system_category());
+ * total_bytes_transferred_ += ec ? 0 : n;
+ *
+ * // Retry operation immediately if interrupted by signal.
+ * if (ec == boost::asio::error::interrupted)
+ * continue;
+ *
+ * // Check if we need to run the operation again.
+ * if (ec == boost::asio::error::would_block
+ * || ec == boost::asio::error::try_again)
+ * {
+ * // We have to wait for the socket to become ready again.
+ * sock_.async_wait(tcp::socket::wait_write, *this);
+ * return;
+ * }
+ *
+ * if (ec || n == 0)
+ * {
+ * // An error occurred, or we have reached the end of the file.
+ * // Either way we must exit the loop so we can call the handler.
+ * break;
+ * }
+ *
+ * // Loop around to try calling sendfile again.
+ * }
+ * }
+ *
+ * // Pass result back to user's handler.
+ * handler_(ec, total_bytes_transferred_);
+ * }
+ * };
+ *
+ * template <typename Handler>
+ * void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ * {
+ * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ * sock.async_wait(tcp::socket::wait_write, op);
+ * } @endcode
+ */
+ void native_non_blocking(bool mode)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
+ boost::asio::detail::throw_error(ec, "native_non_blocking");
+ }
+
+ /// Sets the non-blocking mode of the native socket implementation.
+ /**
+ * This function is used to modify the non-blocking mode of the underlying
+ * native socket. It has no effect on the behaviour of the socket object's
+ * synchronous operations.
+ *
+ * @param mode If @c true, the underlying socket is put into non-blocking
+ * mode and direct system calls may fail with boost::asio::error::would_block
+ * (or the equivalent system error).
+ *
+ * @param ec Set to indicate what error occurred, if any. If the @c mode is
+ * @c false, but the current value of @c non_blocking() is @c true, this
+ * function fails with boost::asio::error::invalid_argument, as the
+ * combination does not make sense.
+ *
+ * @par Example
+ * This function is intended to allow the encapsulation of arbitrary
+ * non-blocking system calls as asynchronous operations, in a way that is
+ * transparent to the user of the socket object. The following example
+ * illustrates how Linux's @c sendfile system call might be encapsulated:
+ * @code template <typename Handler>
+ * struct sendfile_op
+ * {
+ * tcp::socket& sock_;
+ * int fd_;
+ * Handler handler_;
+ * off_t offset_;
+ * std::size_t total_bytes_transferred_;
+ *
+ * // Function call operator meeting WriteHandler requirements.
+ * // Used as the handler for the async_write_some operation.
+ * void operator()(boost::system::error_code ec, std::size_t)
+ * {
+ * // Put the underlying socket into non-blocking mode.
+ * if (!ec)
+ * if (!sock_.native_non_blocking())
+ * sock_.native_non_blocking(true, ec);
+ *
+ * if (!ec)
+ * {
+ * for (;;)
+ * {
+ * // Try the system call.
+ * errno = 0;
+ * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+ * ec = boost::system::error_code(n < 0 ? errno : 0,
+ * boost::asio::error::get_system_category());
+ * total_bytes_transferred_ += ec ? 0 : n;
+ *
+ * // Retry operation immediately if interrupted by signal.
+ * if (ec == boost::asio::error::interrupted)
+ * continue;
+ *
+ * // Check if we need to run the operation again.
+ * if (ec == boost::asio::error::would_block
+ * || ec == boost::asio::error::try_again)
+ * {
+ * // We have to wait for the socket to become ready again.
+ * sock_.async_wait(tcp::socket::wait_write, *this);
+ * return;
+ * }
+ *
+ * if (ec || n == 0)
+ * {
+ * // An error occurred, or we have reached the end of the file.
+ * // Either way we must exit the loop so we can call the handler.
+ * break;
+ * }
+ *
+ * // Loop around to try calling sendfile again.
+ * }
+ * }
+ *
+ * // Pass result back to user's handler.
+ * handler_(ec, total_bytes_transferred_);
+ * }
+ * };
+ *
+ * template <typename Handler>
+ * void async_sendfile(tcp::socket& sock, int fd, Handler h)
+ * {
+ * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+ * sock.async_wait(tcp::socket::wait_write, op);
+ * } @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
+ bool mode, boost::system::error_code& ec)
+ {
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Get the local endpoint of the socket.
+ /**
+ * This function is used to obtain the locally bound endpoint of the socket.
+ *
+ * @returns An object that represents the local endpoint of the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
+ * @endcode
+ */
+ endpoint_type local_endpoint() const
+ {
+ boost::system::error_code ec;
+ endpoint_type ep = impl_.get_service().local_endpoint(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "local_endpoint");
+ return ep;
+ }
+
+ /// Get the local endpoint of the socket.
+ /**
+ * This function is used to obtain the locally bound endpoint of the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns An object that represents the local endpoint of the socket.
+ * Returns a default-constructed endpoint object if an error occurred.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ endpoint_type local_endpoint(boost::system::error_code& ec) const
+ {
+ return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
+ }
+
+ /// Get the remote endpoint of the socket.
+ /**
+ * This function is used to obtain the remote endpoint of the socket.
+ *
+ * @returns An object that represents the remote endpoint of the socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
+ * @endcode
+ */
+ endpoint_type remote_endpoint() const
+ {
+ boost::system::error_code ec;
+ endpoint_type ep = impl_.get_service().remote_endpoint(
+ impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "remote_endpoint");
+ return ep;
+ }
+
+ /// Get the remote endpoint of the socket.
+ /**
+ * This function is used to obtain the remote endpoint of the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns An object that represents the remote endpoint of the socket.
+ * Returns a default-constructed endpoint object if an error occurred.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ endpoint_type remote_endpoint(boost::system::error_code& ec) const
+ {
+ return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec);
+ }
+
+ /// Disable sends or receives on the socket.
+ /**
+ * This function is used to disable send operations, receive operations, or
+ * both.
+ *
+ * @param what Determines what types of operation will no longer be allowed.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * Shutting down the send side of the socket:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
+ * @endcode
+ */
+ void shutdown(shutdown_type what)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
+ boost::asio::detail::throw_error(ec, "shutdown");
+ }
+
+ /// Disable sends or receives on the socket.
+ /**
+ * This function is used to disable send operations, receive operations, or
+ * both.
+ *
+ * @param what Determines what types of operation will no longer be allowed.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * Shutting down the send side of the socket:
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Wait for the socket to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for a socket to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired socket state.
+ *
+ * @par Example
+ * Waiting for a socket to become readable.
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * socket.wait(boost::asio::ip::tcp::socket::wait_read);
+ * @endcode
+ */
+ void wait(wait_type w)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
+ boost::asio::detail::throw_error(ec, "wait");
+ }
+
+ /// Wait for the socket to become ready to read, ready to write, or to have
+ /// pending error conditions.
+ /**
+ * This function is used to perform a blocking wait for a socket to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired socket state.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @par Example
+ * Waiting for a socket to become readable.
+ * @code
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * boost::system::error_code ec;
+ * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec);
+ * @endcode
+ */
+ BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
+ {
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Asynchronously wait for the socket to become ready to read, ready to
+ /// write, or to have pending error conditions.
+ /**
+ * This function is used to perform an asynchronous wait for a socket to enter
+ * a ready to read, write or error condition state.
+ *
+ * @param w Specifies the desired socket state.
+ *
+ * @param handler The handler to be called when the wait operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error // Result of operation
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void wait_handler(const boost::system::error_code& error)
+ * {
+ * if (!error)
+ * {
+ * // Wait succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::socket socket(my_context);
+ * ...
+ * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
+ * @endcode
+ */
+ template <typename WaitHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+ void (boost::system::error_code))
+ async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+ {
+ return async_initiate<WaitHandler, void (boost::system::error_code)>(
+ initiate_async_wait(), handler, this, w);
+ }
+
+protected:
+ /// Protected destructor to prevent deletion through this type.
+ /**
+ * This function destroys the socket, cancelling any outstanding asynchronous
+ * operations associated with the socket as if by calling @c cancel.
+ */
+ ~basic_socket_ext_local()
+ {
+ }
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ detail::io_object_impl<
+ detail::null_socket_service<Protocol>, Executor> impl_;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ detail::io_object_impl<
+ detail::win_iocp_socket_service<Protocol>, Executor> impl_;
+#else
+ detail::io_object_impl<
+ detail::reactive_socket_service_ext_local<Protocol>, Executor> impl_;
+#endif
+
+private:
+ // Disallow copying and assignment.
+ basic_socket_ext_local(const basic_socket_ext_local&) BOOST_ASIO_DELETED;
+ basic_socket_ext_local& operator=(const basic_socket_ext_local&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_connect
+ {
+ template <typename ConnectHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler,
+ basic_socket_ext_local* self, const endpoint_type& peer_endpoint,
+ const boost::system::error_code& open_ec) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ConnectHandler.
+ BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
+
+ if (open_ec)
+ {
+ boost::asio::post(self->impl_.get_executor(),
+ boost::asio::detail::bind_handler(
+ BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));
+ }
+ else
+ {
+ detail::non_const_lvalue<ConnectHandler> handler2(handler);
+ self->impl_.get_service().async_connect(
+ self->impl_.get_implementation(), peer_endpoint,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ }
+ };
+
+ struct initiate_async_wait
+ {
+ template <typename WaitHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
+ basic_socket_ext_local* self, wait_type w) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+ detail::non_const_lvalue<WaitHandler> handler2(handler);
+ self->impl_.get_service().async_wait(
+ self->impl_.get_implementation(), w, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP
diff --git a/implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp
new file mode 100644
index 0000000..e77f5eb
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp
@@ -0,0 +1,996 @@
+//
+// basic_stream_socket_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP
+#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/basic_socket_ext_local.hpp>
+#include <boost/asio/detail/handler_type_requirements_ext_local.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL)
+#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_stream_socket_ext;
+
+#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL)
+
+/// Provides stream-oriented socket functionality.
+/**
+ * The basic_stream_socket_ext class template provides asynchronous and blocking
+ * stream-oriented socket functionality.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Concepts:
+ * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
+ */
+template <typename Protocol, typename Executor>
+class basic_stream_socket_ext
+ : public basic_socket_ext_local<Protocol, Executor>
+{
+public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// Rebinds the socket type to another executor.
+ template <typename Executor1>
+ struct rebind_executor
+ {
+ /// The socket type when rebound to the specified executor.
+ typedef basic_stream_socket_ext<Protocol, Executor1> other;
+ };
+
+ /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef typename basic_socket<Protocol,
+ Executor>::native_handle_type native_handle_type;
+#endif
+
+ /// The protocol type.
+ typedef Protocol protocol_type;
+
+ /// The endpoint type.
+ typedef typename Protocol::endpoint endpoint_type;
+
+ /// Construct a basic_stream_socket without opening it.
+ /**
+ * This constructor creates a stream socket without opening it. The socket
+ * needs to be opened and then connected or accepted before data can be sent
+ * or received on it.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ */
+ explicit basic_stream_socket_ext(const executor_type& ex)
+ : basic_socket_ext_local<Protocol, Executor>(ex)
+ {
+ }
+
+ /// Construct a basic_stream_socket without opening it.
+ /**
+ * This constructor creates a stream socket without opening it. The socket
+ * needs to be opened and then connected or accepted before data can be sent
+ * or received on it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ */
+ template <typename ExecutionContext>
+ explicit basic_stream_socket_ext(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket_ext_local<Protocol, Executor>(context)
+ {
+ }
+
+ /// Construct and open a basic_stream_socket.
+ /**
+ * This constructor creates and opens a stream socket. The socket needs to be
+ * connected or accepted before data can be sent or received on it.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_stream_socket_ext(const executor_type& ex, const protocol_type& protocol)
+ : basic_socket_ext_local<Protocol, Executor>(ex, protocol)
+ {
+ }
+
+ /// Construct and open a basic_stream_socket.
+ /**
+ * This constructor creates and opens a stream socket. The socket needs to be
+ * connected or accepted before data can be sent or received on it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket_ext_local<Protocol, Executor>(context, protocol)
+ {
+ }
+
+ /// Construct a basic_stream_socket, opening it and binding it to the given
+ /// local endpoint.
+ /**
+ * This constructor creates a stream socket and automatically opens it bound
+ * to the specified endpoint on the local machine. The protocol used is the
+ * protocol associated with the given endpoint.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the stream
+ * socket will be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_stream_socket_ext(const executor_type& ex, const endpoint_type& endpoint)
+ : basic_socket_ext_local<Protocol, Executor>(ex, endpoint)
+ {
+ }
+
+ /// Construct a basic_stream_socket, opening it and binding it to the given
+ /// local endpoint.
+ /**
+ * This constructor creates a stream socket and automatically opens it bound
+ * to the specified endpoint on the local machine. The protocol used is the
+ * protocol associated with the given endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the stream
+ * socket will be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket_ext_local<Protocol, Executor>(context, endpoint)
+ {
+ }
+
+ /// Construct a basic_stream_socket on an existing native socket.
+ /**
+ * This constructor creates a stream socket object to hold an existing native
+ * socket.
+ *
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket The new underlying socket implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_stream_socket_ext(const executor_type& ex,
+ const protocol_type& protocol, const native_handle_type& native_socket)
+ : basic_socket_ext_local<Protocol, Executor>(ex, protocol, native_socket)
+ {
+ }
+
+ /// Construct a basic_stream_socket on an existing native socket.
+ /**
+ * This constructor creates a stream socket object to hold an existing native
+ * socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket The new underlying socket implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_stream_socket_ext(ExecutionContext& context,
+ const protocol_type& protocol, const native_handle_type& native_socket,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket_ext_local<Protocol, Executor>(context, protocol, native_socket)
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct a basic_stream_socket from another.
+ /**
+ * This constructor moves a stream socket from one object to another.
+ *
+ * @param other The other basic_stream_socket object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_stream_socket(const executor_type&)
+ * constructor.
+ */
+ basic_stream_socket_ext(basic_stream_socket_ext&& other)
+ : basic_socket_ext_local<Protocol, Executor>(std::move(other))
+ {
+ }
+
+ /// Move-assign a basic_stream_socket from another.
+ /**
+ * This assignment operator moves a stream socket from one object to another.
+ *
+ * @param other The other basic_stream_socket object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_stream_socket(const executor_type&)
+ * constructor.
+ */
+ basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other)
+ {
+ basic_socket_ext_local<Protocol, Executor>::operator=(std::move(other));
+ return *this;
+ }
+
+ /// Move-construct a basic_stream_socket from a socket of another protocol
+ /// type.
+ /**
+ * This constructor moves a stream socket from one object to another.
+ *
+ * @param other The other basic_stream_socket object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_stream_socket(const executor_type&)
+ * constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ basic_stream_socket_ext(basic_stream_socket_ext<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : basic_socket_ext_local<Protocol, Executor>(std::move(other))
+ {
+ }
+
+ /// Move-assign a basic_stream_socket from a socket of another protocol type.
+ /**
+ * This assignment operator moves a stream socket from one object to another.
+ *
+ * @param other The other basic_stream_socket object from which the move
+ * will occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c basic_stream_socket(const executor_type&)
+ * constructor.
+ */
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_stream_socket_ext&
+ >::type operator=(basic_stream_socket_ext<Protocol1, Executor1>&& other)
+ {
+ basic_socket_ext_local<Protocol, Executor>::operator=(std::move(other));
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Destroys the socket.
+ /**
+ * This function destroys the socket, cancelling any outstanding asynchronous
+ * operations associated with the socket as if by calling @c cancel.
+ */
+ ~basic_stream_socket_ext()
+ {
+ }
+
+ /// Send some data on the socket.
+ /**
+ * This function is used to send data on the stream socket. The function
+ * call will block until one or more bytes of the data has been sent
+ * successfully, or an until error occurs.
+ *
+ * @param buffers One or more data buffers to be sent on the socket.
+ *
+ * @returns The number of bytes sent.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note The send operation may not transmit all of the data to the peer.
+ * Consider using the @ref write function if you need to ensure that all data
+ * is written before the blocking operation completes.
+ *
+ * @par Example
+ * To send a single data buffer use the @ref buffer function as follows:
+ * @code
+ * socket.send(boost::asio::buffer(data, size));
+ * @endcode
+ * See the @ref buffer documentation for information on sending multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t send(const ConstBufferSequence& buffers)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, 0, ec);
+ boost::asio::detail::throw_error(ec, "send");
+ return s;
+ }
+
+ /// Send some data on the socket.
+ /**
+ * This function is used to send data on the stream socket. The function
+ * call will block until one or more bytes of the data has been sent
+ * successfully, or an until error occurs.
+ *
+ * @param buffers One or more data buffers to be sent on the socket.
+ *
+ * @param flags Flags specifying how the send call is to be made.
+ *
+ * @returns The number of bytes sent.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note The send operation may not transmit all of the data to the peer.
+ * Consider using the @ref write function if you need to ensure that all data
+ * is written before the blocking operation completes.
+ *
+ * @par Example
+ * To send a single data buffer use the @ref buffer function as follows:
+ * @code
+ * socket.send(boost::asio::buffer(data, size), 0);
+ * @endcode
+ * See the @ref buffer documentation for information on sending multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t send(const ConstBufferSequence& buffers,
+ socket_base::message_flags flags)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
+ boost::asio::detail::throw_error(ec, "send");
+ return s;
+ }
+
+ /// Send some data on the socket.
+ /**
+ * This function is used to send data on the stream socket. The function
+ * call will block until one or more bytes of the data has been sent
+ * successfully, or an until error occurs.
+ *
+ * @param buffers One or more data buffers to be sent on the socket.
+ *
+ * @param flags Flags specifying how the send call is to be made.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes sent. Returns 0 if an error occurred.
+ *
+ * @note The send operation may not transmit all of the data to the peer.
+ * Consider using the @ref write function if you need to ensure that all data
+ * is written before the blocking operation completes.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t send(const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ return this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
+ }
+
+ /// Start an asynchronous send.
+ /**
+ * This function is used to asynchronously send data on the stream socket.
+ * The function call always returns immediately.
+ *
+ * @param buffers One or more data buffers to be sent on the socket. Although
+ * the buffers object may be copied as necessary, ownership of the underlying
+ * memory blocks is retained by the caller, which must guarantee that they
+ * remain valid until the handler is called.
+ *
+ * @param handler The handler to be called when the send operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes sent.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The send operation may not transmit all of the data to the peer.
+ * Consider using the @ref async_write function if you need to ensure that all
+ * data is written before the asynchronous operation completes.
+ *
+ * @par Example
+ * To send a single data buffer use the @ref buffer function as follows:
+ * @code
+ * socket.async_send(boost::asio::buffer(data, size), handler);
+ * @endcode
+ * See the @ref buffer documentation for information on sending multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence, typename WriteHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+ async_send(const ConstBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+ {
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this,
+ buffers, socket_base::message_flags(0));
+ }
+
+ /// Start an asynchronous send.
+ /**
+ * This function is used to asynchronously send data on the stream socket.
+ * The function call always returns immediately.
+ *
+ * @param buffers One or more data buffers to be sent on the socket. Although
+ * the buffers object may be copied as necessary, ownership of the underlying
+ * memory blocks is retained by the caller, which must guarantee that they
+ * remain valid until the handler is called.
+ *
+ * @param flags Flags specifying how the send call is to be made.
+ *
+ * @param handler The handler to be called when the send operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes sent.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The send operation may not transmit all of the data to the peer.
+ * Consider using the @ref async_write function if you need to ensure that all
+ * data is written before the asynchronous operation completes.
+ *
+ * @par Example
+ * To send a single data buffer use the @ref buffer function as follows:
+ * @code
+ * socket.async_send(boost::asio::buffer(data, size), 0, handler);
+ * @endcode
+ * See the @ref buffer documentation for information on sending multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence, typename WriteHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+ async_send(const ConstBufferSequence& buffers,
+ socket_base::message_flags flags,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+ {
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this, buffers, flags);
+ }
+
+ /// Receive some data on the socket.
+ /**
+ * This function is used to receive data on the stream socket. The function
+ * call will block until one or more bytes of data has been received
+ * successfully, or until an error occurs.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ *
+ * @returns The number of bytes received.
+ *
+ * @throws boost::system::system_error Thrown on failure. An error code of
+ * boost::asio::error::eof indicates that the connection was closed by the
+ * peer.
+ *
+ * @note The receive operation may not receive all of the requested number of
+ * bytes. Consider using the @ref read function if you need to ensure that the
+ * requested amount of data is read before the blocking operation completes.
+ *
+ * @par Example
+ * To receive into a single data buffer use the @ref buffer function as
+ * follows:
+ * @code
+ * socket.receive(boost::asio::buffer(data, size));
+ * @endcode
+ * See the @ref buffer documentation for information on receiving into
+ * multiple buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t receive(const MutableBufferSequence& buffers)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, 0, ec);
+ boost::asio::detail::throw_error(ec, "receive");
+ return s;
+ }
+
+ /// Receive some data on the socket.
+ /**
+ * This function is used to receive data on the stream socket. The function
+ * call will block until one or more bytes of data has been received
+ * successfully, or until an error occurs.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ *
+ * @param flags Flags specifying how the receive call is to be made.
+ *
+ * @returns The number of bytes received.
+ *
+ * @throws boost::system::system_error Thrown on failure. An error code of
+ * boost::asio::error::eof indicates that the connection was closed by the
+ * peer.
+ *
+ * @note The receive operation may not receive all of the requested number of
+ * bytes. Consider using the @ref read function if you need to ensure that the
+ * requested amount of data is read before the blocking operation completes.
+ *
+ * @par Example
+ * To receive into a single data buffer use the @ref buffer function as
+ * follows:
+ * @code
+ * socket.receive(boost::asio::buffer(data, size), 0);
+ * @endcode
+ * See the @ref buffer documentation for information on receiving into
+ * multiple buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t receive(const MutableBufferSequence& buffers,
+ socket_base::message_flags flags)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
+ boost::asio::detail::throw_error(ec, "receive");
+ return s;
+ }
+
+ /// Receive some data on a connected socket.
+ /**
+ * This function is used to receive data on the stream socket. The function
+ * call will block until one or more bytes of data has been received
+ * successfully, or until an error occurs.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ *
+ * @param flags Flags specifying how the receive call is to be made.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes received. Returns 0 if an error occurred.
+ *
+ * @note The receive operation may not receive all of the requested number of
+ * bytes. Consider using the @ref read function if you need to ensure that the
+ * requested amount of data is read before the blocking operation completes.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t receive(const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ return this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
+ }
+
+ /// Start an asynchronous receive.
+ /**
+ * This function is used to asynchronously receive data from the stream
+ * socket. The function call always returns immediately.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param handler The handler to be called when the receive operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes received.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The receive operation may not receive all of the requested number of
+ * bytes. Consider using the @ref async_read function if you need to ensure
+ * that the requested amount of data is received before the asynchronous
+ * operation completes.
+ *
+ * @par Example
+ * To receive into a single data buffer use the @ref buffer function as
+ * follows:
+ * @code
+ * socket.async_receive(boost::asio::buffer(data, size), handler);
+ * @endcode
+ * See the @ref buffer documentation for information on receiving into
+ * multiple buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence, typename ReadHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t))
+ async_receive(const MutableBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ {
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
+ initiate_async_receive(), handler, this,
+ buffers, socket_base::message_flags(0));
+ }
+
+ /// Start an asynchronous receive.
+ /**
+ * This function is used to asynchronously receive data from the stream
+ * socket. The function call always returns immediately.
+ *
+ * @param buffers One or more buffers into which the data will be received.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param flags Flags specifying how the receive call is to be made.
+ *
+ * @param handler The handler to be called when the receive operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes received.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The receive operation may not receive all of the requested number of
+ * bytes. Consider using the @ref async_read function if you need to ensure
+ * that the requested amount of data is received before the asynchronous
+ * operation completes.
+ *
+ * @par Example
+ * To receive into a single data buffer use the @ref buffer function as
+ * follows:
+ * @code
+ * socket.async_receive(boost::asio::buffer(data, size), 0, handler);
+ * @endcode
+ * See the @ref buffer documentation for information on receiving into
+ * multiple buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence, typename ReadHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t))
+ async_receive(const MutableBufferSequence& buffers,
+ socket_base::message_flags flags,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ {
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
+ initiate_async_receive(), handler, this, buffers, flags);
+ }
+
+ /// Write some data to the socket.
+ /**
+ * This function is used to write data to the stream socket. The function call
+ * will block until one or more bytes of the data has been written
+ * successfully, or until an error occurs.
+ *
+ * @param buffers One or more data buffers to be written to the socket.
+ *
+ * @returns The number of bytes written.
+ *
+ * @throws boost::system::system_error Thrown on failure. An error code of
+ * boost::asio::error::eof indicates that the connection was closed by the
+ * peer.
+ *
+ * @note The write_some operation may not transmit all of the data to the
+ * peer. Consider using the @ref write function if you need to ensure that
+ * all data is written before the blocking operation completes.
+ *
+ * @par Example
+ * To write a single data buffer use the @ref buffer function as follows:
+ * @code
+ * socket.write_some(boost::asio::buffer(data, size));
+ * @endcode
+ * See the @ref buffer documentation for information on writing multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t write_some(const ConstBufferSequence& buffers)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, 0, ec);
+ boost::asio::detail::throw_error(ec, "write_some");
+ return s;
+ }
+
+ /// Write some data to the socket.
+ /**
+ * This function is used to write data to the stream socket. The function call
+ * will block until one or more bytes of the data has been written
+ * successfully, or until an error occurs.
+ *
+ * @param buffers One or more data buffers to be written to the socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes written. Returns 0 if an error occurred.
+ *
+ * @note The write_some operation may not transmit all of the data to the
+ * peer. Consider using the @ref write function if you need to ensure that
+ * all data is written before the blocking operation completes.
+ */
+ template <typename ConstBufferSequence>
+ std::size_t write_some(const ConstBufferSequence& buffers,
+ boost::system::error_code& ec)
+ {
+ return this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, 0, ec);
+ }
+
+ /// Start an asynchronous write.
+ /**
+ * This function is used to asynchronously write data to the stream socket.
+ * The function call always returns immediately.
+ *
+ * @param buffers One or more data buffers to be written to the socket.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param handler The handler to be called when the write operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes written.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The write operation may not transmit all of the data to the peer.
+ * Consider using the @ref async_write function if you need to ensure that all
+ * data is written before the asynchronous operation completes.
+ *
+ * @par Example
+ * To write a single data buffer use the @ref buffer function as follows:
+ * @code
+ * socket.async_write_some(boost::asio::buffer(data, size), handler);
+ * @endcode
+ * See the @ref buffer documentation for information on writing multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename ConstBufferSequence, typename WriteHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t))
+ async_write_some(const ConstBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+ {
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
+ initiate_async_send(), handler, this,
+ buffers, socket_base::message_flags(0));
+ }
+
+ /// Read some data from the socket.
+ /**
+ * This function is used to read data from the stream socket. The function
+ * call will block until one or more bytes of data has been read successfully,
+ * or until an error occurs.
+ *
+ * @param buffers One or more buffers into which the data will be read.
+ *
+ * @returns The number of bytes read.
+ *
+ * @throws boost::system::system_error Thrown on failure. An error code of
+ * boost::asio::error::eof indicates that the connection was closed by the
+ * peer.
+ *
+ * @note The read_some operation may not read all of the requested number of
+ * bytes. Consider using the @ref read function if you need to ensure that
+ * the requested amount of data is read before the blocking operation
+ * completes.
+ *
+ * @par Example
+ * To read into a single data buffer use the @ref buffer function as follows:
+ * @code
+ * socket.read_some(boost::asio::buffer(data, size));
+ * @endcode
+ * See the @ref buffer documentation for information on reading into multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t read_some(const MutableBufferSequence& buffers)
+ {
+ boost::system::error_code ec;
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, 0, ec);
+ boost::asio::detail::throw_error(ec, "read_some");
+ return s;
+ }
+
+ /// Read some data from the socket.
+ /**
+ * This function is used to read data from the stream socket. The function
+ * call will block until one or more bytes of data has been read successfully,
+ * or until an error occurs.
+ *
+ * @param buffers One or more buffers into which the data will be read.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes read. Returns 0 if an error occurred.
+ *
+ * @note The read_some operation may not read all of the requested number of
+ * bytes. Consider using the @ref read function if you need to ensure that
+ * the requested amount of data is read before the blocking operation
+ * completes.
+ */
+ template <typename MutableBufferSequence>
+ std::size_t read_some(const MutableBufferSequence& buffers,
+ boost::system::error_code& ec)
+ {
+ return this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, 0, ec);
+ }
+
+ /// Start an asynchronous read.
+ /**
+ * This function is used to asynchronously read data from the stream socket.
+ * The function call always returns immediately.
+ *
+ * @param buffers One or more buffers into which the data will be read.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * std::size_t bytes_transferred // Number of bytes read.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note The read operation may not read all of the requested number of bytes.
+ * Consider using the @ref async_read function if you need to ensure that the
+ * requested amount of data is read before the asynchronous operation
+ * completes.
+ *
+ * @par Example
+ * To read into a single data buffer use the @ref buffer function as follows:
+ * @code
+ * socket.async_read_some(boost::asio::buffer(data, size), handler);
+ * @endcode
+ * See the @ref buffer documentation for information on reading into multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+ template <typename MutableBufferSequence, typename ReadHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t))
+ async_read_some(const MutableBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ {
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)>(
+ initiate_async_receive(), handler, this,
+ buffers, socket_base::message_flags(0));
+ }
+
+private:
+ struct initiate_async_send
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_stream_socket_ext* self, const ConstBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_send(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_executor());
+ }
+ };
+
+ struct initiate_async_receive
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_stream_socket_ext* self, const MutableBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_receive(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_executor());
+ }
+ };
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp
new file mode 100644
index 0000000..67fe6bd
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp
@@ -0,0 +1,586 @@
+//
+// detail/handler_type_requirements_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP
+#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+// Older versions of gcc have difficulty compiling the sizeof expressions where
+// we test the handler type requirements. We'll disable checking of handler type
+// requirements for those compilers, but otherwise enable it by default.
+#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
+# if !defined(__GNUC__) || (__GNUC__ >= 4)
+# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1
+# endif // !defined(__GNUC__) || (__GNUC__ >= 4)
+#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
+
+// With C++0x we can use a combination of enhanced SFINAE and static_assert to
+// generate better template error messages. As this technique is not yet widely
+// portable, we'll only enable it for tested compilers.
+#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+# if defined(__GNUC__)
+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+# if defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
+# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+# endif // defined(__GNUC__)
+# if defined(BOOST_ASIO_MSVC)
+# if (_MSC_VER >= 1600)
+# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
+# endif // (_MSC_VER >= 1600)
+# endif // defined(BOOST_ASIO_MSVC)
+# if defined(__clang__)
+# if __has_feature(__cxx_static_assert__)
+# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
+# endif // __has_feature(cxx_static_assert)
+# endif // defined(__clang__)
+#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
+
+#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+# include <boost/asio/async_result.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+
+template <typename Handler>
+auto zero_arg_copyable_handler_test(Handler h, void*)
+ -> decltype(
+ sizeof(Handler(static_cast<const Handler&>(h))),
+ ((h)()),
+ char(0));
+
+template <typename Handler>
+char (&zero_arg_copyable_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1>
+auto one_arg_handler_test(Handler h, Arg1* a1)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1)),
+ char(0));
+
+template <typename Handler>
+char (&one_arg_handler_test(Handler h, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2>
+auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1, *a2)),
+ char(0));
+
+template <typename Handler>
+char (&two_arg_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2>
+auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))),
+ char(0));
+
+template <typename Handler>
+char (&two_arg_move_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
+auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1, *a2, *a3)),
+ char(0));
+
+template <typename Handler>
+char (&three_arg_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
+auto three_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3 *a3)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3))),
+ char(0));
+
+template <typename Handler>
+char (&three_arg_move_handler_test(Handler, ...))[2];
+
+# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \
+ static_assert(expr, msg);
+
+# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+
+# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg)
+
+# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+
+template <typename T> T& lvref();
+template <typename T> T& lvref(T);
+template <typename T> const T& clvref();
+template <typename T> const T& clvref(T);
+#if defined(BOOST_ASIO_HAS_MOVE)
+template <typename T> T rvref();
+template <typename T> T rvref(T);
+#else // defined(BOOST_ASIO_HAS_MOVE)
+template <typename T> const T& rvref();
+template <typename T> const T& rvref(T);
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+template <typename T> char argbyv(T);
+
+#if 0
+template <int>
+struct handler_type_requirements
+{
+};
+#endif
+
+#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void()) asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \
+ boost::asio::detail::clvref< \
+ asio_true_handler_type>(), 0)) == 1, \
+ "CompletionHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::clvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()(), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, std::size_t, \
+ boost::asio::ip::address)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::three_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const std::size_t*>(0), \
+ static_cast<const boost::asio::ip::address*>(0))) == 1, \
+ "ReadHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const std::size_t>(), \
+ boost::asio::detail::lvref<const boost::asio::ip::address>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WRITE_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, std::size_t)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const std::size_t*>(0))) == 1, \
+ "WriteHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const std::size_t>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#if 0
+#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "AcceptHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \
+ handler_type, handler, socket_type) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, socket_type)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_move_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<socket_type*>(0))) == 1, \
+ "MoveAcceptHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::rvref<socket_type>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+#endif
+
+#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "ConnectHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \
+ handler_type, handler, endpoint_type) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, endpoint_type)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const endpoint_type*>(0))) == 1, \
+ "RangeConnectHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const endpoint_type>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \
+ handler_type, handler, iter_type) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, iter_type)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const iter_type*>(0))) == 1, \
+ "IteratorConnectHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const iter_type>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \
+ handler_type, handler, range_type) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, range_type)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const range_type*>(0))) == 1, \
+ "ResolveHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const range_type>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WAIT_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "WaitHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, int)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const int*>(0))) == 1, \
+ "SignalHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const int>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "HandshakeHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, std::size_t)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const std::size_t*>(0))) == 1, \
+ "BufferedHandshakeHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const std::size_t>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "ShutdownHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_READ_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WRITE_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \
+ handler_type, handler, socket_type) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \
+ handler_type, handler, iter_type) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \
+ handler_type, handler, iter_type) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \
+ handler_type, handler, iter_type) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WAIT_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp
new file mode 100644
index 0000000..65640ad
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp
@@ -0,0 +1,588 @@
+//
+// detail/handler_type_requirements_ext_local.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP
+#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+// Older versions of gcc have difficulty compiling the sizeof expressions where
+// we test the handler type requirements. We'll disable checking of handler type
+// requirements for those compilers, but otherwise enable it by default.
+#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
+# if !defined(__GNUC__) || (__GNUC__ >= 4)
+# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1
+# endif // !defined(__GNUC__) || (__GNUC__ >= 4)
+#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
+
+// With C++0x we can use a combination of enhanced SFINAE and static_assert to
+// generate better template error messages. As this technique is not yet widely
+// portable, we'll only enable it for tested compilers.
+#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+# if defined(__GNUC__)
+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+# if defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
+# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+# endif // defined(__GNUC__)
+# if defined(BOOST_ASIO_MSVC)
+# if (_MSC_VER >= 1600)
+# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
+# endif // (_MSC_VER >= 1600)
+# endif // defined(BOOST_ASIO_MSVC)
+# if defined(__clang__)
+# if __has_feature(__cxx_static_assert__)
+# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
+# endif // __has_feature(cxx_static_assert)
+# endif // defined(__clang__)
+#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
+
+#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+# include <boost/asio/async_result.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+
+template <typename Handler>
+auto zero_arg_copyable_handler_test(Handler h, void*)
+ -> decltype(
+ sizeof(Handler(static_cast<const Handler&>(h))),
+ ((h)()),
+ char(0));
+
+template <typename Handler>
+char (&zero_arg_copyable_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1>
+auto one_arg_handler_test(Handler h, Arg1* a1)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1)),
+ char(0));
+
+template <typename Handler>
+char (&one_arg_handler_test(Handler h, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2>
+auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1, *a2)),
+ char(0));
+
+template <typename Handler>
+char (&two_arg_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2>
+auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))),
+ char(0));
+
+template <typename Handler>
+char (&two_arg_move_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1, *a2, *a3, *a4)),
+ char(0));
+
+template <typename Handler>
+char (&four_arg_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+auto four_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4)
+ -> decltype(
+ sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+ ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3), BOOST_ASIO_MOVE_CAST(Arg4)(*a4))),
+ char(0));
+
+template <typename Handler>
+char (&four_arg_move_handler_test(Handler, ...))[2];
+
+# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \
+ static_assert(expr, msg);
+
+# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+
+# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg)
+
+# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+
+template <typename T> T& lvref();
+template <typename T> T& lvref(T);
+template <typename T> const T& clvref();
+template <typename T> const T& clvref(T);
+#if defined(BOOST_ASIO_HAS_MOVE)
+template <typename T> T rvref();
+template <typename T> T rvref(T);
+#else // defined(BOOST_ASIO_HAS_MOVE)
+template <typename T> const T& rvref();
+template <typename T> const T& rvref(T);
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+template <typename T> char argbyv(T);
+
+#if 0
+template <int>
+struct handler_type_requirements
+{
+};
+#endif
+
+#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void()) asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \
+ boost::asio::detail::clvref< \
+ asio_true_handler_type>(), 0)) == 1, \
+ "CompletionHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::clvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()(), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, std::size_t, \
+ std::uint32_t, std::uint32_t)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::four_arg_handler_test( \
+ boost::asio::detail::clvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const std::size_t*>(0), \
+ static_cast<const std::uint32_t*>(0), \
+ static_cast<const std::uint32_t*>(0))) == 1, \
+ "ReadHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::clvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const std::size_t>(), \
+ boost::asio::detail::lvref<const std::uint32_t>(), \
+ boost::asio::detail::lvref<const std::uint32_t>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WRITE_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, std::size_t)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const std::size_t*>(0))) == 1, \
+ "WriteHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const std::size_t>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#if 0
+#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "AcceptHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \
+ handler_type, handler, socket_type) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, socket_type)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_move_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<socket_type*>(0))) == 1, \
+ "MoveAcceptHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::rvref<socket_type>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+#endif
+
+#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "ConnectHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \
+ handler_type, handler, endpoint_type) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, endpoint_type)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const endpoint_type*>(0))) == 1, \
+ "RangeConnectHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const endpoint_type>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \
+ handler_type, handler, iter_type) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, iter_type)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const iter_type*>(0))) == 1, \
+ "IteratorConnectHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const iter_type>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \
+ handler_type, handler, range_type) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, range_type)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const range_type*>(0))) == 1, \
+ "ResolveHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const range_type>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WAIT_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "WaitHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, int)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const int*>(0))) == 1, \
+ "SignalHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const int>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "HandshakeHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code, std::size_t)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::two_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0), \
+ static_cast<const std::size_t*>(0))) == 1, \
+ "BufferedHandshakeHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>(), \
+ boost::asio::detail::lvref<const std::size_t>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \
+ handler_type, handler) \
+ \
+ typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+ void(boost::system::error_code)) \
+ asio_true_handler_type; \
+ \
+ BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+ sizeof(boost::asio::detail::one_arg_handler_test( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>(), \
+ static_cast<const boost::system::error_code*>(0))) == 1, \
+ "ShutdownHandler type requirements not met") \
+ \
+ typedef boost::asio::detail::handler_type_requirements< \
+ sizeof( \
+ boost::asio::detail::argbyv( \
+ boost::asio::detail::rvref< \
+ asio_true_handler_type>())) + \
+ sizeof( \
+ boost::asio::detail::lvref< \
+ asio_true_handler_type>()( \
+ boost::asio::detail::lvref<const boost::system::error_code>()), \
+ char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_READ_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WRITE_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \
+ handler_type, handler, socket_type) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \
+ handler_type, handler, iter_type) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \
+ handler_type, handler, iter_type) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \
+ handler_type, handler, iter_type) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WAIT_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \
+ handler_type, handler) \
+ typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp
new file mode 100644
index 0000000..04036ad
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp
@@ -0,0 +1,302 @@
+//
+// detail/reactive_socket_service_base_ext.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP
+#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP) \
+ && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+reactive_socket_service_base_ext::reactive_socket_service_base_ext(
+ execution_context& context)
+ : reactor_(use_service<reactor>(context))
+{
+ reactor_.init_task();
+}
+
+void reactive_socket_service_base_ext::base_shutdown()
+{
+}
+
+void reactive_socket_service_base_ext::construct(
+ reactive_socket_service_base_ext::base_implementation_type& impl)
+{
+ impl.socket_ = invalid_socket;
+ impl.state_ = 0;
+}
+
+void reactive_socket_service_base_ext::base_move_construct(
+ reactive_socket_service_base_ext::base_implementation_type& impl,
+ reactive_socket_service_base_ext::base_implementation_type& other_impl)
+{
+ impl.socket_ = other_impl.socket_;
+ other_impl.socket_ = invalid_socket;
+
+ impl.state_ = other_impl.state_;
+ other_impl.state_ = 0;
+
+ reactor_.move_descriptor(impl.socket_,
+ impl.reactor_data_, other_impl.reactor_data_);
+}
+
+void reactive_socket_service_base_ext::base_move_assign(
+ reactive_socket_service_base_ext::base_implementation_type& impl,
+ reactive_socket_service_base_ext& other_service,
+ reactive_socket_service_base_ext::base_implementation_type& other_impl)
+{
+ destroy(impl);
+
+ impl.socket_ = other_impl.socket_;
+ other_impl.socket_ = invalid_socket;
+
+ impl.state_ = other_impl.state_;
+ other_impl.state_ = 0;
+
+ other_service.reactor_.move_descriptor(impl.socket_,
+ impl.reactor_data_, other_impl.reactor_data_);
+}
+
+void reactive_socket_service_base_ext::destroy(
+ reactive_socket_service_base_ext::base_implementation_type& impl)
+{
+ if (impl.socket_ != invalid_socket)
+ {
+ BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+ "socket", &impl, impl.socket_, "close"));
+
+ reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_,
+ (impl.state_ & socket_ops::possible_dup) == 0);
+
+ boost::system::error_code ignored_ec;
+ socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
+
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
+ }
+}
+
+boost::system::error_code reactive_socket_service_base_ext::close(
+ reactive_socket_service_base_ext::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+ "socket", &impl, impl.socket_, "close"));
+
+ reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_,
+ (impl.state_ & socket_ops::possible_dup) == 0);
+
+ socket_ops::close(impl.socket_, impl.state_, false, ec);
+
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
+
+ // The descriptor is closed by the OS even if close() returns an error.
+ //
+ // (Actually, POSIX says the state of the descriptor is unspecified. On
+ // Linux the descriptor is apparently closed anyway; e.g. see
+ // http://lkml.org/lkml/2005/9/10/129
+ // We'll just have to assume that other OSes follow the same behaviour. The
+ // known exception is when Windows's closesocket() function fails with
+ // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close().
+ construct(impl);
+
+ return ec;
+}
+/*
+socket_type reactive_socket_service_base::release(
+ reactive_socket_service_base::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return invalid_socket;
+ }
+
+ BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+ "socket", &impl, impl.socket_, "release"));
+
+ reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false);
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
+ socket_type sock = impl.socket_;
+ construct(impl);
+ ec = boost::system::error_code();
+ return sock;
+}
+*/
+boost::system::error_code reactive_socket_service_base_ext::cancel(
+ reactive_socket_service_base_ext::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return ec;
+ }
+
+ BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+ "socket", &impl, impl.socket_, "cancel"));
+
+ reactor_.cancel_ops(impl.socket_, impl.reactor_data_);
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code reactive_socket_service_base_ext::do_open(
+ reactive_socket_service_base_ext::base_implementation_type& impl,
+ int af, int type, int protocol, boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ socket_holder sock(socket_ops::socket(af, type, protocol, ec));
+ if (sock.get() == invalid_socket)
+ return ec;
+
+ if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_))
+ {
+ ec = boost::system::error_code(err,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ impl.socket_ = sock.release();
+ switch (type)
+ {
+ case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
+ case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
+ default: impl.state_ = 0; break;
+ }
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code reactive_socket_service_base_ext::do_assign(
+ reactive_socket_service_base_ext::base_implementation_type& impl, int type,
+ const reactive_socket_service_base_ext::native_handle_type& native_socket,
+ boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ if (int err = reactor_.register_descriptor(
+ native_socket, impl.reactor_data_))
+ {
+ ec = boost::system::error_code(err,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ impl.socket_ = native_socket;
+ switch (type)
+ {
+ case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
+ case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
+ default: impl.state_ = 0; break;
+ }
+ impl.state_ |= socket_ops::possible_dup;
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void reactive_socket_service_base_ext::start_op(
+ reactive_socket_service_base_ext::base_implementation_type& impl,
+ int op_type, reactor_op* op, bool is_continuation,
+ bool is_non_blocking, bool noop)
+{
+ if (!noop)
+ {
+ if ((impl.state_ & socket_ops::non_blocking)
+ || socket_ops::set_internal_non_blocking(
+ impl.socket_, impl.state_, true, op->ec_))
+ {
+ reactor_.start_op(op_type, impl.socket_,
+ impl.reactor_data_, op, is_continuation, is_non_blocking);
+ return;
+ }
+ }
+
+ reactor_.post_immediate_completion(op, is_continuation);
+}
+
+void reactive_socket_service_base_ext::start_accept_op(
+ reactive_socket_service_base_ext::base_implementation_type& impl,
+ reactor_op* op, bool is_continuation, bool peer_is_open)
+{
+ if (!peer_is_open)
+ start_op(impl, reactor::read_op, op, is_continuation, true, false);
+ else
+ {
+ op->ec_ = boost::asio::error::already_open;
+ reactor_.post_immediate_completion(op, is_continuation);
+ }
+}
+
+void reactive_socket_service_base_ext::start_connect_op(
+ reactive_socket_service_base_ext::base_implementation_type& impl,
+ reactor_op* op, bool is_continuation,
+ const socket_addr_type* addr, size_t addrlen)
+{
+ if ((impl.state_ & socket_ops::non_blocking)
+ || socket_ops::set_internal_non_blocking(
+ impl.socket_, impl.state_, true, op->ec_))
+ {
+ if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0)
+ {
+ if (op->ec_ == boost::asio::error::in_progress
+ || op->ec_ == boost::asio::error::would_block)
+ {
+ op->ec_ = boost::system::error_code();
+ reactor_.start_op(reactor::connect_op, impl.socket_,
+ impl.reactor_data_, op, is_continuation, false);
+ return;
+ }
+ }
+ }
+
+ reactor_.post_immediate_completion(op, is_continuation);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+ // && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP
diff --git a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp
new file mode 100644
index 0000000..288cf19
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp
@@ -0,0 +1,302 @@
+//
+// detail/reactive_socket_service_base_ext_local.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP
+#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP) \
+ && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local(
+ execution_context& context)
+ : reactor_(use_service<reactor>(context))
+{
+ reactor_.init_task();
+}
+
+void reactive_socket_service_base_ext_local::base_shutdown()
+{
+}
+
+void reactive_socket_service_base_ext_local::construct(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl)
+{
+ impl.socket_ = invalid_socket;
+ impl.state_ = 0;
+}
+
+void reactive_socket_service_base_ext_local::base_move_construct(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl,
+ reactive_socket_service_base_ext_local::base_implementation_type& other_impl)
+{
+ impl.socket_ = other_impl.socket_;
+ other_impl.socket_ = invalid_socket;
+
+ impl.state_ = other_impl.state_;
+ other_impl.state_ = 0;
+
+ reactor_.move_descriptor(impl.socket_,
+ impl.reactor_data_, other_impl.reactor_data_);
+}
+
+void reactive_socket_service_base_ext_local::base_move_assign(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl,
+ reactive_socket_service_base_ext_local& other_service,
+ reactive_socket_service_base_ext_local::base_implementation_type& other_impl)
+{
+ destroy(impl);
+
+ impl.socket_ = other_impl.socket_;
+ other_impl.socket_ = invalid_socket;
+
+ impl.state_ = other_impl.state_;
+ other_impl.state_ = 0;
+
+ other_service.reactor_.move_descriptor(impl.socket_,
+ impl.reactor_data_, other_impl.reactor_data_);
+}
+
+void reactive_socket_service_base_ext_local::destroy(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl)
+{
+ if (impl.socket_ != invalid_socket)
+ {
+ BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+ "socket", &impl, impl.socket_, "close"));
+
+ reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_,
+ (impl.state_ & socket_ops::possible_dup) == 0);
+
+ boost::system::error_code ignored_ec;
+ socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
+
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
+ }
+}
+
+boost::system::error_code reactive_socket_service_base_ext_local::close(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+ "socket", &impl, impl.socket_, "close"));
+
+ reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_,
+ (impl.state_ & socket_ops::possible_dup) == 0);
+
+ socket_ops::close(impl.socket_, impl.state_, false, ec);
+
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
+
+ // The descriptor is closed by the OS even if close() returns an error.
+ //
+ // (Actually, POSIX says the state of the descriptor is unspecified. On
+ // Linux the descriptor is apparently closed anyway; e.g. see
+ // http://lkml.org/lkml/2005/9/10/129
+ // We'll just have to assume that other OSes follow the same behaviour. The
+ // known exception is when Windows's closesocket() function fails with
+ // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close().
+ construct(impl);
+
+ return ec;
+}
+/*
+socket_type reactive_socket_service_base::release(
+ reactive_socket_service_base::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return invalid_socket;
+ }
+
+ BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+ "socket", &impl, impl.socket_, "release"));
+
+ reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false);
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
+ socket_type sock = impl.socket_;
+ construct(impl);
+ ec = boost::system::error_code();
+ return sock;
+}
+*/
+boost::system::error_code reactive_socket_service_base_ext_local::cancel(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return ec;
+ }
+
+ BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+ "socket", &impl, impl.socket_, "cancel"));
+
+ reactor_.cancel_ops(impl.socket_, impl.reactor_data_);
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code reactive_socket_service_base_ext_local::do_open(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl,
+ int af, int type, int protocol, boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ socket_holder sock(socket_ops::socket(af, type, protocol, ec));
+ if (sock.get() == invalid_socket)
+ return ec;
+
+ if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_))
+ {
+ ec = boost::system::error_code(err,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ impl.socket_ = sock.release();
+ switch (type)
+ {
+ case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
+ case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
+ default: impl.state_ = 0; break;
+ }
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code reactive_socket_service_base_ext_local::do_assign(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl, int type,
+ const reactive_socket_service_base_ext_local::native_handle_type& native_socket,
+ boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ if (int err = reactor_.register_descriptor(
+ native_socket, impl.reactor_data_))
+ {
+ ec = boost::system::error_code(err,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ impl.socket_ = native_socket;
+ switch (type)
+ {
+ case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
+ case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
+ default: impl.state_ = 0; break;
+ }
+ impl.state_ |= socket_ops::possible_dup;
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void reactive_socket_service_base_ext_local::start_op(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl,
+ int op_type, reactor_op* op, bool is_continuation,
+ bool is_non_blocking, bool noop)
+{
+ if (!noop)
+ {
+ if ((impl.state_ & socket_ops::non_blocking)
+ || socket_ops::set_internal_non_blocking(
+ impl.socket_, impl.state_, true, op->ec_))
+ {
+ reactor_.start_op(op_type, impl.socket_,
+ impl.reactor_data_, op, is_continuation, is_non_blocking);
+ return;
+ }
+ }
+
+ reactor_.post_immediate_completion(op, is_continuation);
+}
+
+void reactive_socket_service_base_ext_local::start_accept_op(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl,
+ reactor_op* op, bool is_continuation, bool peer_is_open)
+{
+ if (!peer_is_open)
+ start_op(impl, reactor::read_op, op, is_continuation, true, false);
+ else
+ {
+ op->ec_ = boost::asio::error::already_open;
+ reactor_.post_immediate_completion(op, is_continuation);
+ }
+}
+
+void reactive_socket_service_base_ext_local::start_connect_op(
+ reactive_socket_service_base_ext_local::base_implementation_type& impl,
+ reactor_op* op, bool is_continuation,
+ const socket_addr_type* addr, size_t addrlen)
+{
+ if ((impl.state_ & socket_ops::non_blocking)
+ || socket_ops::set_internal_non_blocking(
+ impl.socket_, impl.state_, true, op->ec_))
+ {
+ if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0)
+ {
+ if (op->ec_ == boost::asio::error::in_progress
+ || op->ec_ == boost::asio::error::would_block)
+ {
+ op->ec_ = boost::system::error_code();
+ reactor_.start_op(reactor::connect_op, impl.socket_,
+ impl.reactor_data_, op, is_continuation, false);
+ return;
+ }
+ }
+ }
+
+ reactor_.post_immediate_completion(op, is_continuation);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+ // && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP
diff --git a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp
new file mode 100644
index 0000000..39e2ed8
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp
@@ -0,0 +1,234 @@
+//
+// detail/impl/socket_ops_ext.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP
+#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP
+
+#include <boost/asio/detail/impl/socket_ops.ipp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+namespace socket_ops {
+
+signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
+ int flags, socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec, boost::asio::ip::address& da)
+{
+
+#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+ GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
+ LPFN_WSARECVMSG WSARecvMsg;
+ DWORD NumberOfBytes;
+ signed_size_type result;
+
+ result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
+ &WSARecvMsg, sizeof WSARecvMsg,
+ &NumberOfBytes, NULL, NULL);
+ get_last_error(ec, true);
+ if (ec.value() == SOCKET_ERROR) {
+ WSARecvMsg = NULL;
+ return 0;
+ }
+
+ WSABUF wsaBuf;
+ WSAMSG msg;
+ char controlBuffer[1024];
+ msg.name = addr;
+ msg.namelen = *addrlen;
+ wsaBuf.buf = bufs->buf;
+ wsaBuf.len = bufs->len;
+ msg.lpBuffers = &wsaBuf;
+ msg.dwBufferCount = count;
+ msg.Control.len = sizeof controlBuffer;
+ msg.Control.buf = controlBuffer;
+ msg.dwFlags = flags;
+
+ DWORD dwNumberOfBytesRecvd;
+ result = WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL);
+ get_last_error(ec, true);
+
+ if (result >= 0) {
+ ec = boost::system::error_code();
+
+ // Find destination address
+ for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg);
+ cmsg != NULL;
+ cmsg = WSA_CMSG_NXTHDR(&msg, cmsg))
+ {
+ if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
+ {
+ struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg);
+ if (pi)
+ {
+ da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr));
+ }
+ } else
+ if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO)
+ {
+ struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg);
+ if (pi)
+ {
+ boost::asio::ip::address_v6::bytes_type b;
+ memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr));
+ da = boost::asio::ip::address_v6(b);
+ }
+ }
+ }
+ } else {
+ dwNumberOfBytesRecvd = -1;
+ }
+ return dwNumberOfBytesRecvd;
+#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+ char cmbuf[0x100];
+ msghdr msg = msghdr();
+ init_msghdr_msg_name(msg.msg_name, addr);
+ msg.msg_namelen = static_cast<int>(*addrlen);
+ msg.msg_iov = bufs;
+ msg.msg_iovlen = static_cast<int>(count);
+ msg.msg_control = cmbuf;
+ msg.msg_controllen = sizeof(cmbuf);
+ signed_size_type result = ::recvmsg(s, &msg, flags);
+ get_last_error(ec, true);
+ *addrlen = msg.msg_namelen;
+ if (result >= 0) {
+ ec.assign(0, ec.category());
+
+ // Find destination address
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg))
+ {
+ if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
+ {
+ struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg);
+ if (pi)
+ {
+ da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr));
+ }
+ } else
+ if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO)
+ {
+ struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg);
+ if (pi)
+ {
+ boost::asio::ip::address_v6::bytes_type b;
+ memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr));
+ da = boost::asio::ip::address_v6(b);
+ }
+ }
+ }
+ }
+ return result;
+#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+}
+
+size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
+ size_t count, int flags, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // Read some data.
+ for (;;)
+ {
+ // Try to complete the operation without blocking.
+ signed_size_type bytes = socket_ops::recvfrom(
+ s, bufs, count, flags, addr, addrlen, ec, da);
+
+ // Check if operation succeeded.
+ if (bytes >= 0)
+ return bytes;
+
+ // Operation failed.
+ if ((state & user_set_non_blocking)
+ || (ec != boost::asio::error::would_block
+ && ec != boost::asio::error::try_again))
+ return 0;
+
+ // Wait for socket to become ready.
+ if (socket_ops::poll_read(s, 0, -1, ec) < 0)
+ return 0;
+ }
+}
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+void complete_iocp_recvfrom(
+ const weak_cancel_token_type& cancel_token,
+ boost::system::error_code& ec, boost::asio::ip::address& da)
+{
+ // Map non-portable errors to their portable counterparts.
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ {
+ if (cancel_token.expired())
+ ec = boost::asio::error::operation_aborted;
+ else
+ ec = boost::asio::error::connection_reset;
+ }
+ else if (ec.value() == ERROR_PORT_UNREACHABLE)
+ {
+ ec = boost::asio::error::connection_refused;
+ }
+}
+
+#else // defined(BOOST_ASIO_HAS_IOCP)
+
+bool non_blocking_recvfrom(socket_type s,
+ buf* bufs, size_t count, int flags,
+ socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da)
+{
+ for (;;)
+ {
+ // Read some data.
+ signed_size_type bytes = socket_ops::recvfrom(
+ s, bufs, count, flags, addr, addrlen, ec, da);
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ // Operation is complete.
+ if (bytes >= 0)
+ {
+ ec = boost::system::error_code();
+ bytes_transferred = bytes;
+ }
+ else
+ bytes_transferred = 0;
+
+ return true;
+ }
+}
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+} // namespace socket_ops
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP
diff --git a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp
new file mode 100644
index 0000000..83a673b
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp
@@ -0,0 +1,307 @@
+//
+// detail/impl/socket_ops_ext_local.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP
+#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP
+
+#include <boost/asio/detail/impl/socket_ops.ipp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+namespace socket_ops {
+
+signed_size_type recv(socket_type s, buf* bufs, size_t count,
+ int flags, boost::system::error_code& ec,
+ std::uint32_t& uid, std::uint32_t& gid)
+{
+ uid = 0xFFFFFFFF;
+ gid = 0xFFFFFFFF;
+ struct ucred *ucredp;
+
+#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+ // Receive some data.
+ DWORD recv_buf_count = static_cast<DWORD>(count);
+ DWORD bytes_transferred = 0;
+ DWORD recv_flags = flags;
+ int result = ::WSARecv(s, bufs,
+ recv_buf_count, &bytes_transferred, &recv_flags, 0, 0);
+ get_last_error(ec, true);
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ ec = boost::asio::error::connection_reset;
+ else if (ec.value() == ERROR_PORT_UNREACHABLE)
+ ec = boost::asio::error::connection_refused;
+ if (result != 0)
+ return socket_error_retval;
+ ec.assign(0, ec.category());
+ return bytes_transferred;
+#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+ msghdr msg = msghdr();
+ msg.msg_iov = bufs;
+ msg.msg_iovlen = static_cast<int>(count);
+
+ union {
+ struct cmsghdr cmh;
+ char control[CMSG_SPACE(sizeof(struct ucred))];
+ } control_un;
+
+ // Set 'control_un' to describe ancillary data that we want to receive
+ control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred));
+ control_un.cmh.cmsg_level = SOL_SOCKET;
+ control_un.cmh.cmsg_type = SCM_CREDENTIALS;
+
+ // Set 'msg' fields to describe 'control_un'
+ msg.msg_control = control_un.control;
+ msg.msg_controllen = sizeof(control_un.control);
+
+ signed_size_type result = ::recvmsg(s, &msg, flags);
+ get_last_error(ec, true);
+ if (result >= 0) {
+ ec.assign(0, ec.category());
+
+ // Find UID / GID
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS
+ || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
+ continue;
+
+ ucredp = (struct ucred *) CMSG_DATA(cmsg);
+ if (ucredp) {
+ uid = ucredp->uid;
+ gid = ucredp->gid;
+ }
+ }
+ }
+ return result;
+#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+}
+
+signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
+ int flags, socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec,
+ std::uint32_t& uid, std::uint32_t& gid)
+{
+ uid = 0xFFFFFFFF;
+ gid = 0xFFFFFFFF;
+ struct ucred *ucredp;
+ clear_last_error();
+#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+ // Receive some data.
+ DWORD recv_buf_count = static_cast<DWORD>(count);
+ DWORD bytes_transferred = 0;
+ DWORD recv_flags = flags;
+ int tmp_addrlen = (int)*addrlen;
+ int result = ::WSARecvFrom(s, bufs, recv_buf_count,
+ &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0);
+ get_last_error(ec, true);
+ *addrlen = (std::size_t)tmp_addrlen;
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ ec = boost::asio::error::connection_reset;
+ else if (ec.value() == ERROR_PORT_UNREACHABLE)
+ ec = boost::asio::error::connection_refused;
+ if (result != 0)
+ return socket_error_retval;
+ ec.assign(0, ec.category());
+ return bytes_transferred;
+#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+ msghdr msg = msghdr();
+ init_msghdr_msg_name(msg.msg_name, addr);
+ msg.msg_namelen = static_cast<int>(*addrlen);
+ msg.msg_iov = bufs;
+ msg.msg_iovlen = static_cast<int>(count);
+
+ union {
+ struct cmsghdr cmh;
+ char control[CMSG_SPACE(sizeof(struct ucred))];
+ } control_un;
+
+ // Set 'control_un' to describe ancillary data that we want to receive
+ control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred));
+ control_un.cmh.cmsg_level = SOL_SOCKET;
+ control_un.cmh.cmsg_type = SCM_CREDENTIALS;
+
+ // Set 'msg' fields to describe 'control_un'
+ msg.msg_control = control_un.control;
+ msg.msg_controllen = sizeof(control_un.control);
+
+ signed_size_type result = ::recvmsg(s, &msg, flags);
+ get_last_error(ec, true);
+ *addrlen = msg.msg_namelen;
+ if (result >= 0) {
+ ec.assign(0, ec.category());
+
+ // Find UID / GID
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS
+ || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
+ continue;
+
+ ucredp = (struct ucred *) CMSG_DATA(cmsg);
+ if (ucredp) {
+ uid = ucredp->uid;
+ gid = ucredp->gid;
+ }
+ }
+ }
+ return result;
+#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+}
+
+size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
+ size_t count, int flags, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec,
+ std::uint32_t& uid, std::uint32_t& gid)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // Read some data.
+ for (;;)
+ {
+ // Try to complete the operation without blocking.
+ signed_size_type bytes = socket_ops::recvfrom(
+ s, bufs, count, flags, addr, addrlen, ec, uid, gid);
+
+ // Check if operation succeeded.
+ if (bytes >= 0)
+ return bytes;
+
+ // Operation failed.
+ if ((state & user_set_non_blocking)
+ || (ec != boost::asio::error::would_block
+ && ec != boost::asio::error::try_again))
+ return 0;
+
+ // Wait for socket to become ready.
+ if (socket_ops::poll_read(s, 0, -1, ec) < 0)
+ return 0;
+ }
+}
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+void complete_iocp_recvfrom(
+ const weak_cancel_token_type& cancel_token,
+ boost::system::error_code& ec,
+ std::uint32_t& uid, std::uint32_t& gid)
+{
+ uid = 0xFFFFFFFF;
+ gid = 0xFFFFFFFF;
+ // Map non-portable errors to their portable counterparts.
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ {
+ if (cancel_token.expired())
+ ec = boost::asio::error::operation_aborted;
+ else
+ ec = boost::asio::error::connection_reset;
+ }
+ else if (ec.value() == ERROR_PORT_UNREACHABLE)
+ {
+ ec = boost::asio::error::connection_refused;
+ }
+}
+
+#else // defined(BOOST_ASIO_HAS_IOCP)
+
+bool non_blocking_recv(socket_type s,
+ buf* bufs, size_t count, int flags, bool is_stream,
+ boost::system::error_code& ec, size_t& bytes_transferred,
+ std::uint32_t& uid, std::uint32_t& gid)
+{
+ for (;;)
+ {
+ // Read some data.
+ signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid);
+
+ // Check for end of stream.
+ if (is_stream && bytes == 0)
+ {
+ ec = boost::asio::error::eof;
+ return true;
+ }
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ // Operation is complete.
+ if (bytes >= 0)
+ {
+ ec = boost::system::error_code();
+ bytes_transferred = bytes;
+ }
+ else
+ bytes_transferred = 0;
+
+ return true;
+ }
+}
+
+bool non_blocking_recvfrom(socket_type s,
+ buf* bufs, size_t count, int flags,
+ socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec, size_t& bytes_transferred,
+ std::uint32_t& uid, std::uint32_t& gid)
+{
+ for (;;)
+ {
+ // Read some data.
+ signed_size_type bytes = socket_ops::recvfrom(
+ s, bufs, count, flags, addr, addrlen, ec, uid, gid);
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ // Operation is complete.
+ if (bytes >= 0)
+ {
+ ec = boost::system::error_code();
+ bytes_transferred = bytes;
+ }
+ else
+ bytes_transferred = 0;
+
+ return true;
+ }
+}
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+} // namespace socket_ops
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp
new file mode 100644
index 0000000..1167d57
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp
@@ -0,0 +1,162 @@
+//
+// detail/reactive_socket_recv_op_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/handler_work.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactor_op_ext.hpp>
+#include <boost/asio/detail/socket_ops_ext.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence>
+class reactive_socket_recv_op_base_ext : public reactor_op_ext
+{
+public:
+ reactive_socket_recv_op_base_ext(const boost::system::error_code& success_ec,
+ socket_type socket, socket_ops::state_type state,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, func_type complete_func)
+ : reactor_op_ext(success_ec, &reactive_socket_recv_op_base_ext::do_perform, complete_func),
+ socket_(socket),
+ state_(state),
+ buffers_(buffers),
+ flags_(flags)
+ {
+ }
+
+ static status do_perform(reactor_op* base)
+ {
+ reactive_socket_recv_op_base_ext* o(
+ static_cast<reactive_socket_recv_op_base_ext*>(base));
+
+ typedef buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs_type;
+
+ status result;
+ if (bufs_type::is_single_buffer)
+ {
+ result = socket_ops::non_blocking_recv1(o->socket_,
+ bufs_type::first(o->buffers_).data(),
+ bufs_type::first(o->buffers_).size(), o->flags_,
+ (o->state_ & socket_ops::stream_oriented) != 0,
+ o->ec_, o->bytes_transferred_) ? done : not_done;
+ }
+ else
+ {
+ bufs_type bufs(o->buffers_);
+ result = socket_ops::non_blocking_recv(o->socket_,
+ bufs.buffers(), bufs.count(), o->flags_,
+ (o->state_ & socket_ops::stream_oriented) != 0,
+ o->ec_, o->bytes_transferred_) ? done : not_done;
+ }
+
+ if (result == done)
+ if ((o->state_ & socket_ops::stream_oriented) != 0)
+ if (o->bytes_transferred_ == 0)
+ result = done_and_exhausted;
+
+ BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv",
+ o->ec_, o->bytes_transferred_));
+
+ return result;
+ }
+
+private:
+ socket_type socket_;
+ socket_ops::state_type state_;
+ MutableBufferSequence buffers_;
+ socket_base::message_flags flags_;
+};
+
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
+class reactive_socket_recv_op_ext :
+ public reactive_socket_recv_op_base_ext<MutableBufferSequence>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext);
+
+ reactive_socket_recv_op_ext(const boost::system::error_code& success_ec,
+ socket_type socket, socket_ops::state_type state,
+ const MutableBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ : reactive_socket_recv_op_base_ext<MutableBufferSequence>(success_ec,
+ socket, state, buffers, flags,
+ &reactive_socket_recv_op_ext::do_complete),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ work_(handler_, io_ex)
+ {
+ }
+
+ static void do_complete(void* owner, operation* base,
+ const boost::system::error_code& /*ec*/,
+ std::size_t /*bytes_transferred*/)
+ {
+ // Take ownership of the handler object.
+ reactive_socket_recv_op_ext* o(static_cast<reactive_socket_recv_op_ext*>(base));
+ ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
+
+ BOOST_ASIO_HANDLER_COMPLETION((*o));
+
+ // Take ownership of the operation's outstanding work.
+ handler_work<Handler, IoExecutor> w(
+ BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
+ o->work_));
+
+ // Make a copy of the handler so that the memory can be deallocated before
+ // the upcall is made. Even if we're not about to make an upcall, a
+ // sub-object of the handler may be the true owner of the memory associated
+ // with the handler. Consequently, a local copy of the handler is required
+ // to ensure that any owning sub-object remains valid until after we have
+ // deallocated the memory here.
+ detail::binder3<Handler, boost::system::error_code, std::size_t, boost::asio::ip::address>
+ handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_);
+ p.h = boost::asio::detail::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ fenced_block b(fenced_block::half);
+ BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_));
+ w.complete(handler, handler.handler_);
+ BOOST_ASIO_HANDLER_INVOCATION_END;
+ }
+ }
+
+private:
+ Handler handler_;
+ handler_work<Handler, IoExecutor> work_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp
new file mode 100644
index 0000000..bedbd29
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp
@@ -0,0 +1,162 @@
+//
+// detail/reactive_socket_recv_op_ext_local.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/handler_work.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactor_op_ext_local.hpp>
+#include <boost/asio/detail/socket_ops_ext_local.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence>
+class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local
+{
+public:
+ reactive_socket_recv_op_base_ext_local(const boost::system::error_code& success_ec,
+ socket_type socket, socket_ops::state_type state,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, func_type complete_func)
+ : reactor_op_ext_local(success_ec, &reactive_socket_recv_op_base_ext_local::do_perform, complete_func),
+ socket_(socket),
+ state_(state),
+ buffers_(buffers),
+ flags_(flags)
+ {
+ }
+
+ static status do_perform(reactor_op* base)
+ {
+ reactive_socket_recv_op_base_ext_local* o(
+ static_cast<reactive_socket_recv_op_base_ext_local*>(base));
+
+ typedef buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs_type;
+
+ status result;
+ if (bufs_type::is_single_buffer)
+ {
+ result = socket_ops::non_blocking_recv1(o->socket_,
+ bufs_type::first(o->buffers_).data(),
+ bufs_type::first(o->buffers_).size(), o->flags_,
+ (o->state_ & socket_ops::stream_oriented) != 0,
+ o->ec_, o->bytes_transferred_) ? done : not_done;
+ }
+ else
+ {
+ bufs_type bufs(o->buffers_);
+ result = socket_ops::non_blocking_recv(o->socket_,
+ bufs.buffers(), bufs.count(), o->flags_,
+ (o->state_ & socket_ops::stream_oriented) != 0,
+ o->ec_, o->bytes_transferred_) ? done : not_done;
+ }
+
+ if (result == done)
+ if ((o->state_ & socket_ops::stream_oriented) != 0)
+ if (o->bytes_transferred_ == 0)
+ result = done_and_exhausted;
+
+ BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv",
+ o->ec_, o->bytes_transferred_));
+
+ return result;
+ }
+
+private:
+ socket_type socket_;
+ socket_ops::state_type state_;
+ MutableBufferSequence buffers_;
+ socket_base::message_flags flags_;
+};
+
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
+class reactive_socket_recv_op_ext_local :
+ public reactive_socket_recv_op_base_ext_local<MutableBufferSequence>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local);
+
+ reactive_socket_recv_op_ext_local(const boost::system::error_code& success_ec,
+ socket_type socket, socket_ops::state_type state,
+ const MutableBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ : reactive_socket_recv_op_base_ext_local<MutableBufferSequence>(success_ec,
+ socket, state, buffers, flags,
+ &reactive_socket_recv_op_ext_local::do_complete),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ work_(handler_, io_ex)
+ {
+ }
+
+ static void do_complete(void* owner, operation* base,
+ const boost::system::error_code& /*ec*/,
+ std::size_t /*bytes_transferred*/)
+ {
+ // Take ownership of the handler object.
+ reactive_socket_recv_op_ext_local* o(static_cast<reactive_socket_recv_op_ext_local*>(base));
+ ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
+
+ BOOST_ASIO_HANDLER_COMPLETION((*o));
+
+ // Take ownership of the operation's outstanding work.
+ handler_work<Handler, IoExecutor> w(
+ BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
+ o->work_));
+
+ // Make a copy of the handler so that the memory can be deallocated before
+ // the upcall is made. Even if we're not about to make an upcall, a
+ // sub-object of the handler may be the true owner of the memory associated
+ // with the handler. Consequently, a local copy of the handler is required
+ // to ensure that any owning sub-object remains valid until after we have
+ // deallocated the memory here.
+ detail::binder4<Handler, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
+ handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_);
+ p.h = boost::asio::detail::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ fenced_block b(fenced_block::half);
+ BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3, handler.arg4));
+ w.complete(handler, handler.handler_);
+ BOOST_ASIO_HANDLER_INVOCATION_END;
+ }
+ }
+
+private:
+ Handler handler_;
+ handler_work<Handler, IoExecutor> work_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp
new file mode 100644
index 0000000..875fe14
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp
@@ -0,0 +1,153 @@
+//
+// detail/reactive_socket_recvfrom_op_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/handler_work.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactor_op_ext.hpp>
+#include <boost/asio/detail/socket_ops_ext.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence, typename Endpoint>
+class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext
+{
+public:
+ reactive_socket_recvfrom_op_base_ext(const boost::system::error_code& success_ec,
+ socket_type socket, int protocol_type,
+ const MutableBufferSequence& buffers, Endpoint& endpoint,
+ socket_base::message_flags flags, func_type complete_func)
+ : reactor_op_ext(success_ec, &reactive_socket_recvfrom_op_base_ext::do_perform, complete_func),
+ socket_(socket),
+ protocol_type_(protocol_type),
+ buffers_(buffers),
+ sender_endpoint_(endpoint),
+ flags_(flags)
+ {
+ }
+
+ static status do_perform(reactor_op* base)
+ {
+ reactive_socket_recvfrom_op_base_ext* o(
+ static_cast<reactive_socket_recvfrom_op_base_ext*>(base));
+
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(o->buffers_);
+
+ std::size_t addr_len = o->sender_endpoint_.capacity();
+ status result = socket_ops::non_blocking_recvfrom(o->socket_,
+ bufs.buffers(), bufs.count(), o->flags_,
+ o->sender_endpoint_.data(), &addr_len,
+ o->ec_, o->bytes_transferred_, o->da_) ? done : not_done;
+
+ if (result && !o->ec_)
+ o->sender_endpoint_.resize(addr_len);
+
+ BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom",
+ o->ec_, o->bytes_transferred_));
+
+ return result;
+ }
+
+private:
+ socket_type socket_;
+ int protocol_type_;
+ MutableBufferSequence buffers_;
+ Endpoint& sender_endpoint_;
+ socket_base::message_flags flags_;
+};
+
+template <typename MutableBufferSequence, typename Endpoint,
+ typename Handler, typename IoExecutor>
+class reactive_socket_recvfrom_op_ext :
+ public reactive_socket_recvfrom_op_base_ext<MutableBufferSequence, Endpoint>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext);
+
+ reactive_socket_recvfrom_op_ext(const boost::system::error_code& success_ec,
+ socket_type socket, int protocol_type,
+ const MutableBufferSequence& buffers, Endpoint& endpoint,
+ socket_base::message_flags flags, Handler& handler,
+ const IoExecutor& io_ex)
+ : reactive_socket_recvfrom_op_base_ext<MutableBufferSequence, Endpoint>(
+ success_ec, socket, protocol_type, buffers, endpoint, flags,
+ &reactive_socket_recvfrom_op_ext::do_complete),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ work_(handler_, io_ex)
+ {
+ }
+
+ static void do_complete(void* owner, operation* base,
+ const boost::system::error_code& /*ec*/,
+ std::size_t /*bytes_transferred*/)
+ {
+ // Take ownership of the handler object.
+ reactive_socket_recvfrom_op_ext* o(
+ static_cast<reactive_socket_recvfrom_op_ext*>(base));
+ ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
+
+ BOOST_ASIO_HANDLER_COMPLETION((*o));
+
+ // Take ownership of the operation's outstanding work.
+ handler_work<Handler, IoExecutor> w(
+ BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
+ o->work_));
+
+ // Make a copy of the handler so that the memory can be deallocated before
+ // the upcall is made. Even if we're not about to make an upcall, a
+ // sub-object of the handler may be the true owner of the memory associated
+ // with the handler. Consequently, a local copy of the handler is required
+ // to ensure that any owning sub-object remains valid until after we have
+ // deallocated the memory here.
+ detail::binder3<Handler, boost::system::error_code, std::size_t, boost::asio::ip::address>
+ handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_);
+ p.h = boost::asio::detail::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ fenced_block b(fenced_block::half);
+ BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_));
+ w.complete(handler, handler.handler_);
+ BOOST_ASIO_HANDLER_INVOCATION_END;
+ }
+ }
+
+private:
+ Handler handler_;
+ handler_work<Handler, IoExecutor> work_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp
new file mode 100644
index 0000000..f9fef2b
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp
@@ -0,0 +1,148 @@
+//
+// detail/reactive_socket_recvfrom_op_ext_local.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactor_op_ext_local.hpp>
+#include <boost/asio/detail/socket_ops_ext_local.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence, typename Endpoint>
+class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local
+{
+public:
+ reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type,
+ const MutableBufferSequence& buffers, Endpoint& endpoint,
+ socket_base::message_flags flags, func_type complete_func)
+ : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func),
+ socket_(socket),
+ protocol_type_(protocol_type),
+ buffers_(buffers),
+ sender_endpoint_(endpoint),
+ flags_(flags)
+ {
+ }
+
+ static status do_perform(reactor_op* base)
+ {
+ reactive_socket_recvfrom_op_base_ext_local* o(
+ static_cast<reactive_socket_recvfrom_op_base_ext_local*>(base));
+
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(o->buffers_);
+
+ std::size_t addr_len = o->sender_endpoint_.capacity();
+ status result = socket_ops::non_blocking_recvfrom(o->socket_,
+ bufs.buffers(), bufs.count(), o->flags_,
+ o->sender_endpoint_.data(), &addr_len,
+ o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done;
+
+ if (result && !o->ec_)
+ o->sender_endpoint_.resize(addr_len);
+
+ BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom",
+ o->ec_, o->bytes_transferred_));
+
+ return result;
+ }
+
+private:
+ socket_type socket_;
+ int protocol_type_;
+ MutableBufferSequence buffers_;
+ Endpoint& sender_endpoint_;
+ socket_base::message_flags flags_;
+};
+
+template <typename MutableBufferSequence, typename Endpoint,
+ typename Handler, typename IoExecutor>
+class reactive_socket_recvfrom_op_ext_local :
+ public reactive_socket_recvfrom_op_base_ext_local<MutableBufferSequence, Endpoint>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local);
+
+ reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type,
+ const MutableBufferSequence& buffers, Endpoint& endpoint,
+ socket_base::message_flags flags, Handler& handler,
+ const IoExecutor& io_ex)
+ : reactive_socket_recvfrom_op_base_ext_local<MutableBufferSequence, Endpoint>(
+ socket, protocol_type, buffers, endpoint, flags,
+ &reactive_socket_recvfrom_op_ext_local::do_complete),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ work_(handler_, io_ex)
+ {
+ }
+
+ static void do_complete(void* owner, operation* base,
+ const boost::system::error_code& /*ec*/,
+ std::size_t /*bytes_transferred*/)
+ {
+ // Take ownership of the handler object.
+ reactive_socket_recvfrom_op_ext_local* o(
+ static_cast<reactive_socket_recvfrom_op_ext_local*>(base));
+ ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
+
+ BOOST_ASIO_HANDLER_COMPLETION((*o));
+
+ // Take ownership of the operation's outstanding work.
+ handler_work<Handler, IoExecutor> w(
+ BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
+ o->work_));
+
+ // Make a copy of the handler so that the memory can be deallocated before
+ // the upcall is made. Even if we're not about to make an upcall, a
+ // sub-object of the handler may be the true owner of the memory associated
+ // with the handler. Consequently, a local copy of the handler is required
+ // to ensure that any owning sub-object remains valid until after we have
+ // deallocated the memory here.
+ detail::binder4<Handler, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
+ handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_);
+ p.h = boost::asio::detail::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ fenced_block b(fenced_block::half);
+ BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_));
+ w.complete(handler, handler.handler_);
+ BOOST_ASIO_HANDLER_INVOCATION_END;
+ }
+ }
+
+private:
+ Handler handler_;
+ handler_work<Handler, IoExecutor> work_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp
new file mode 100644
index 0000000..bd315dc
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp
@@ -0,0 +1,144 @@
+//
+// detail/reactive_socket_recvmsg_op_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/handler_work.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactor_op_ext.hpp>
+#include <boost/asio/detail/socket_ops_ext.hpp>
+#include <boost/asio/socket_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence>
+class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext
+{
+public:
+ reactive_socket_recvmsg_op_base_ext(const boost::system::error_code& success_ec,
+ socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, func_type complete_func)
+ : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func),
+ socket_(socket),
+ buffers_(buffers),
+ in_flags_(in_flags),
+ out_flags_(out_flags)
+ {
+ }
+
+ static status do_perform(reactor_op* base)
+ {
+ reactive_socket_recvmsg_op_base_ext* o(
+ static_cast<reactive_socket_recvmsg_op_base_ext*>(base));
+
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(o->buffers_);
+
+ status result = socket_ops::non_blocking_recvmsg(o->socket_,
+ bufs.buffers(), bufs.count(),
+ o->in_flags_, o->out_flags_,
+ o->ec_, o->bytes_transferred_) ? done : not_done;
+
+ BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg",
+ o->ec_, o->bytes_transferred_));
+
+ return result;
+ }
+
+private:
+ socket_type socket_;
+ MutableBufferSequence buffers_;
+ socket_base::message_flags in_flags_;
+ socket_base::message_flags& out_flags_;
+};
+
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
+class reactive_socket_recvmsg_op_ext :
+ public reactive_socket_recvmsg_op_base_ext<MutableBufferSequence>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext);
+
+ reactive_socket_recvmsg_op_ext(const boost::system::error_code& success_ec,
+ socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
+ : reactive_socket_recvmsg_op_base_ext<MutableBufferSequence>(socket, buffers,
+ in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ work_(handler_, io_ex)
+ {
+ }
+
+ static void do_complete(void* owner, operation* base,
+ const boost::system::error_code& /*ec*/,
+ std::size_t /*bytes_transferred*/)
+ {
+ // Take ownership of the handler object.
+ reactive_socket_recvmsg_op_ext* o(
+ static_cast<reactive_socket_recvmsg_op_ext*>(base));
+ ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
+
+ BOOST_ASIO_HANDLER_COMPLETION((*o));
+
+ // Take ownership of the operation's outstanding work.
+ handler_work<Handler, IoExecutor> w(
+ BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
+ o->work_));
+
+ // Make a copy of the handler so that the memory can be deallocated before
+ // the upcall is made. Even if we're not about to make an upcall, a
+ // sub-object of the handler may be the true owner of the memory associated
+ // with the handler. Consequently, a local copy of the handler is required
+ // to ensure that any owning sub-object remains valid until after we have
+ // deallocated the memory here.
+ detail::binder3<Handler, boost::system::error_code, std::size_t, boost::asio::ip::address>
+ handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_);
+ p.h = boost::asio::detail::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ fenced_block b(fenced_block::half);
+ BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_));
+ w.complete(handler, handler.handler_);
+ BOOST_ASIO_HANDLER_INVOCATION_END;
+ }
+ }
+
+private:
+ Handler handler_;
+ handler_work<Handler, IoExecutor> work_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp
new file mode 100644
index 0000000..8148690
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp
@@ -0,0 +1,145 @@
+//
+// detail/reactive_socket_recvmsg_op_ext_local.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/handler_work.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactor_op_ext_local.hpp>
+#include <boost/asio/detail/socket_ops_ext_local.hpp>
+#include <boost/asio/socket_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence>
+class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local
+{
+public:
+ reactive_socket_recvmsg_op_base_ext_local(const boost::system::error_code& success_ec,
+ socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, func_type complete_func)
+ : reactor_op_ext_local(success_ec, &reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func),
+ socket_(socket),
+ buffers_(buffers),
+ in_flags_(in_flags),
+ out_flags_(out_flags)
+ {
+ }
+
+ static status do_perform(reactor_op* base)
+ {
+ reactive_socket_recvmsg_op_base_ext_local* o(
+ static_cast<reactive_socket_recvmsg_op_base_ext_local*>(base));
+
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(o->buffers_);
+
+ status result = socket_ops::non_blocking_recvmsg(o->socket_,
+ bufs.buffers(), bufs.count(),
+ o->in_flags_, o->out_flags_,
+ o->ec_, o->bytes_transferred_) ? done : not_done;
+
+ BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg",
+ o->ec_, o->bytes_transferred_));
+
+ return result;
+ }
+
+private:
+ socket_type socket_;
+ MutableBufferSequence buffers_;
+ socket_base::message_flags in_flags_;
+ socket_base::message_flags& out_flags_;
+};
+
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
+class reactive_socket_recvmsg_op_ext_local :
+ public reactive_socket_recvmsg_op_base_ext_local<MutableBufferSequence>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local);
+
+ reactive_socket_recvmsg_op_ext_local(const boost::system::error_code& success_ec,
+ socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
+ : reactive_socket_recvmsg_op_base_ext_local<MutableBufferSequence>(success_ec,
+ socket, buffers, in_flags, out_flags,
+ &reactive_socket_recvmsg_op_ext_local::do_complete),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ work_(handler_, io_ex)
+ {
+ }
+
+ static void do_complete(void* owner, operation* base,
+ const boost::system::error_code& /*ec*/,
+ std::size_t /*bytes_transferred*/)
+ {
+ // Take ownership of the handler object.
+ reactive_socket_recvmsg_op_ext_local* o(
+ static_cast<reactive_socket_recvmsg_op_ext_local*>(base));
+ ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
+
+ BOOST_ASIO_HANDLER_COMPLETION((*o));
+
+ // Take ownership of the operation's outstanding work.
+ handler_work<Handler, IoExecutor> w(
+ BOOST_ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
+ o->work_));
+
+ // Make a copy of the handler so that the memory can be deallocated before
+ // the upcall is made. Even if we're not about to make an upcall, a
+ // sub-object of the handler may be the true owner of the memory associated
+ // with the handler. Consequently, a local copy of the handler is required
+ // to ensure that any owning sub-object remains valid until after we have
+ // deallocated the memory here.
+ detail::binder4<Handler, boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t>
+ handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_);
+ p.h = boost::asio::detail::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ fenced_block b(fenced_block::half);
+ BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_));
+ w.complete(handler, handler.handler_);
+ BOOST_ASIO_HANDLER_INVOCATION_END;
+ }
+ }
+
+private:
+ Handler handler_;
+ handler_work<Handler, IoExecutor> work_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp
new file mode 100644
index 0000000..2e68a87
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp
@@ -0,0 +1,524 @@
+//
+// detail/reactive_socket_service_base.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP) \
+ && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/socket_base.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactive_null_buffers_op.hpp>
+#include <boost/asio/detail/reactive_socket_recv_op_ext.hpp>
+#include <boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp>
+#include <boost/asio/detail/reactive_socket_send_op.hpp>
+#include <boost/asio/detail/reactive_wait_op.hpp>
+#include <boost/asio/detail/reactor.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
+#include <boost/asio/detail/socket_holder.hpp>
+#include <boost/asio/detail/socket_ops_ext.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class reactive_socket_service_base_ext
+{
+public:
+ // The native type of a socket.
+ typedef socket_type native_handle_type;
+
+ // The implementation type of the socket.
+ struct base_implementation_type
+ {
+ // The native socket representation.
+ socket_type socket_;
+
+ // The current state of the socket.
+ socket_ops::state_type state_;
+
+ // Per-descriptor data used by the reactor.
+ reactor::per_descriptor_data reactor_data_;
+ };
+
+ // Constructor.
+ BOOST_ASIO_DECL reactive_socket_service_base_ext(execution_context& context);
+
+ // Destroy all user-defined handler objects owned by the service.
+ BOOST_ASIO_DECL void base_shutdown();
+
+ // Construct a new socket implementation.
+ BOOST_ASIO_DECL void construct(base_implementation_type& impl);
+
+ // Move-construct a new socket implementation.
+ BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl,
+ base_implementation_type& other_impl);
+
+ // Move-assign from another socket implementation.
+ BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl,
+ reactive_socket_service_base_ext& other_service,
+ base_implementation_type& other_impl);
+
+ // Destroy a socket implementation.
+ BOOST_ASIO_DECL void destroy(base_implementation_type& impl);
+
+ // Determine whether the socket is open.
+ bool is_open(const base_implementation_type& impl) const
+ {
+ return impl.socket_ != invalid_socket;
+ }
+
+ // Destroy a socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code close(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Release ownership of the socket.
+ BOOST_ASIO_DECL socket_type release(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Get the native socket representation.
+ native_handle_type native_handle(base_implementation_type& impl)
+ {
+ return impl.socket_;
+ }
+
+ // Cancel all operations associated with the socket.
+ BOOST_ASIO_DECL boost::system::error_code cancel(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Determine whether the socket is at the out-of-band data mark.
+ bool at_mark(const base_implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ return socket_ops::sockatmark(impl.socket_, ec);
+ }
+
+ // Determine the number of bytes available for reading.
+ std::size_t available(const base_implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ return socket_ops::available(impl.socket_, ec);
+ }
+
+ // Place the socket into the state where it will listen for new connections.
+ boost::system::error_code listen(base_implementation_type& impl,
+ int backlog, boost::system::error_code& ec)
+ {
+ socket_ops::listen(impl.socket_, backlog, ec);
+ return ec;
+ }
+
+ // Perform an IO control command on the socket.
+ template <typename IO_Control_Command>
+ boost::system::error_code io_control(base_implementation_type& impl,
+ IO_Control_Command& command, boost::system::error_code& ec)
+ {
+ socket_ops::ioctl(impl.socket_, impl.state_, command.name(),
+ static_cast<ioctl_arg_type*>(command.data()), ec);
+ return ec;
+ }
+
+ // Gets the non-blocking mode of the socket.
+ bool non_blocking(const base_implementation_type& impl) const
+ {
+ return (impl.state_ & socket_ops::user_set_non_blocking) != 0;
+ }
+
+ // Sets the non-blocking mode of the socket.
+ boost::system::error_code non_blocking(base_implementation_type& impl,
+ bool mode, boost::system::error_code& ec)
+ {
+ socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec);
+ return ec;
+ }
+
+ // Gets the non-blocking mode of the native socket implementation.
+ bool native_non_blocking(const base_implementation_type& impl) const
+ {
+ return (impl.state_ & socket_ops::internal_non_blocking) != 0;
+ }
+
+ // Sets the non-blocking mode of the native socket implementation.
+ boost::system::error_code native_non_blocking(base_implementation_type& impl,
+ bool mode, boost::system::error_code& ec)
+ {
+ socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec);
+ return ec;
+ }
+
+ // Wait for the socket to become ready to read, ready to write, or to have
+ // pending error conditions.
+ boost::system::error_code wait(base_implementation_type& impl,
+ socket_base::wait_type w, boost::system::error_code& ec)
+ {
+ switch (w)
+ {
+ case socket_base::wait_read:
+ socket_ops::poll_read(impl.socket_, impl.state_, -1, ec);
+ break;
+ case socket_base::wait_write:
+ socket_ops::poll_write(impl.socket_, impl.state_, -1, ec);
+ break;
+ case socket_base::wait_error:
+ socket_ops::poll_error(impl.socket_, impl.state_, -1, ec);
+ break;
+ default:
+ ec = boost::asio::error::invalid_argument;
+ break;
+ }
+
+ return ec;
+ }
+
+ // Asynchronously wait for the socket to become ready to read, ready to
+ // write, or to have pending error conditions.
+ template <typename Handler, typename IoExecutor>
+ void async_wait(base_implementation_type& impl,
+ socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_wait_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_wait"));
+
+ int op_type;
+ switch (w)
+ {
+ case socket_base::wait_read:
+ op_type = reactor::read_op;
+ break;
+ case socket_base::wait_write:
+ op_type = reactor::write_op;
+ break;
+ case socket_base::wait_error:
+ op_type = reactor::except_op;
+ break;
+ default:
+ p.p->ec_ = boost::asio::error::invalid_argument;
+ reactor_.post_immediate_completion(p.p, is_continuation);
+ p.v = p.p = 0;
+ return;
+ }
+
+ start_op(impl, op_type, p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Send the given data to the peer.
+ template <typename ConstBufferSequence>
+ size_t send(base_implementation_type& impl,
+ const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_send(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
+ }
+
+ // Wait until data can be sent without blocking.
+ size_t send(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_write(impl.socket_, impl.state_, -1, ec);
+
+ return 0;
+ }
+
+ // Start an asynchronous send. The data being sent must be valid for the
+ // lifetime of the asynchronous operation.
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
+ void async_send(base_implementation_type& impl,
+ const ConstBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_send_op<
+ ConstBufferSequence, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_,
+ buffers, flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_send"));
+
+ start_op(impl, reactor::write_op, p.p, is_continuation, true,
+ ((impl.state_ & socket_ops::stream_oriented)
+ && buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence>::all_empty(buffers)));
+ p.v = p.p = 0;
+ }
+
+ // Start an asynchronous wait until data can be sent without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_send(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_send(null_buffers)"));
+
+ start_op(impl, reactor::write_op, p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Receive some data from the peer. Returns the number of bytes received.
+ template <typename MutableBufferSequence>
+ size_t receive(base_implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_recv(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
+ }
+
+ // Wait until data can be received without blocking.
+ size_t receive(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_read(impl.socket_, impl.state_, -1, ec);
+
+ return 0;
+ }
+
+ // Start an asynchronous receive. The buffer for the data being received
+ // must be valid for the lifetime of the asynchronous operation.
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
+ void async_receive(base_implementation_type& impl,
+ const MutableBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_recv_op_ext<
+ MutableBufferSequence, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_,
+ buffers, flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive"));
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation,
+ (flags & socket_base::message_out_of_band) == 0,
+ ((impl.state_ & socket_ops::stream_oriented)
+ && buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence>::all_empty(buffers)));
+ p.v = p.p = 0;
+ }
+
+ // Wait until data can be received without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_receive(base_implementation_type& impl,
+ const null_buffers&, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive(null_buffers)"));
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Receive some data with associated flags. Returns the number of bytes
+ // received.
+ template <typename MutableBufferSequence>
+ size_t receive_with_flags(base_implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_recvmsg(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), in_flags, out_flags, ec);
+ }
+
+ // Wait until data can be received without blocking.
+ size_t receive_with_flags(base_implementation_type& impl,
+ const null_buffers&, socket_base::message_flags,
+ socket_base::message_flags& out_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_read(impl.socket_, impl.state_, -1, ec);
+
+ // Clear out_flags, since we cannot give it any other sensible value when
+ // performing a null_buffers operation.
+ out_flags = 0;
+
+ return 0;
+ }
+
+ // Start an asynchronous receive. The buffer for the data being received
+ // must be valid for the lifetime of the asynchronous operation.
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
+ void async_receive_with_flags(base_implementation_type& impl,
+ const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_recvmsg_op_ext<
+ MutableBufferSequence, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, buffers,
+ in_flags, out_flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive_with_flags"));
+
+ start_op(impl,
+ (in_flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation,
+ (in_flags & socket_base::message_out_of_band) == 0, false);
+ p.v = p.p = 0;
+ }
+
+ // Wait until data can be received without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_receive_with_flags(base_implementation_type& impl,
+ const null_buffers&, socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive_with_flags(null_buffers)"));
+
+ // Clear out_flags, since we cannot give it any other sensible value when
+ // performing a null_buffers operation.
+ out_flags = 0;
+
+ start_op(impl,
+ (in_flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+protected:
+ // Open a new socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code do_open(
+ base_implementation_type& impl, int af,
+ int type, int protocol, boost::system::error_code& ec);
+
+ // Assign a native socket to a socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code do_assign(
+ base_implementation_type& impl, int type,
+ const native_handle_type& native_socket, boost::system::error_code& ec);
+
+ // Start the asynchronous read or write operation.
+ BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type,
+ reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop);
+
+ // Start the asynchronous accept operation.
+ BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl,
+ reactor_op* op, bool is_continuation, bool peer_is_open);
+
+ // Start the asynchronous connect operation.
+ BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl,
+ reactor_op* op, bool is_continuation,
+ const socket_addr_type* addr, size_t addrlen);
+
+ // The selector that performs event demultiplexing for the service.
+ reactor& reactor_;
+
+ // Cached success value to avoid accessing category singleton.
+ const boost::system::error_code success_ec_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/reactive_socket_service_base_ext.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+ // && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp
new file mode 100644
index 0000000..a71fce5
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp
@@ -0,0 +1,524 @@
+//
+// detail/reactive_socket_service_base_ext_local.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP) \
+ && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/socket_base.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactive_null_buffers_op.hpp>
+#include <boost/asio/detail/reactive_socket_recv_op_ext_local.hpp>
+#include <boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp>
+#include <boost/asio/detail/reactive_socket_send_op.hpp>
+#include <boost/asio/detail/reactive_wait_op.hpp>
+#include <boost/asio/detail/reactor.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
+#include <boost/asio/detail/socket_holder.hpp>
+#include <boost/asio/detail/socket_ops_ext_local.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class reactive_socket_service_base_ext_local
+{
+public:
+ // The native type of a socket.
+ typedef socket_type native_handle_type;
+
+ // The implementation type of the socket.
+ struct base_implementation_type
+ {
+ // The native socket representation.
+ socket_type socket_;
+
+ // The current state of the socket.
+ socket_ops::state_type state_;
+
+ // Per-descriptor data used by the reactor.
+ reactor::per_descriptor_data reactor_data_;
+ };
+
+ // Constructor.
+ BOOST_ASIO_DECL reactive_socket_service_base_ext_local(execution_context& context);
+
+ // Destroy all user-defined handler objects owned by the service.
+ BOOST_ASIO_DECL void base_shutdown();
+
+ // Construct a new socket implementation.
+ BOOST_ASIO_DECL void construct(base_implementation_type& impl);
+
+ // Move-construct a new socket implementation.
+ BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl,
+ base_implementation_type& other_impl);
+
+ // Move-assign from another socket implementation.
+ BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl,
+ reactive_socket_service_base_ext_local& other_service,
+ base_implementation_type& other_impl);
+
+ // Destroy a socket implementation.
+ BOOST_ASIO_DECL void destroy(base_implementation_type& impl);
+
+ // Determine whether the socket is open.
+ bool is_open(const base_implementation_type& impl) const
+ {
+ return impl.socket_ != invalid_socket;
+ }
+
+ // Destroy a socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code close(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Release ownership of the socket.
+ BOOST_ASIO_DECL socket_type release(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Get the native socket representation.
+ native_handle_type native_handle(base_implementation_type& impl)
+ {
+ return impl.socket_;
+ }
+
+ // Cancel all operations associated with the socket.
+ BOOST_ASIO_DECL boost::system::error_code cancel(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Determine whether the socket is at the out-of-band data mark.
+ bool at_mark(const base_implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ return socket_ops::sockatmark(impl.socket_, ec);
+ }
+
+ // Determine the number of bytes available for reading.
+ std::size_t available(const base_implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ return socket_ops::available(impl.socket_, ec);
+ }
+
+ // Place the socket into the state where it will listen for new connections.
+ boost::system::error_code listen(base_implementation_type& impl,
+ int backlog, boost::system::error_code& ec)
+ {
+ socket_ops::listen(impl.socket_, backlog, ec);
+ return ec;
+ }
+
+ // Perform an IO control command on the socket.
+ template <typename IO_Control_Command>
+ boost::system::error_code io_control(base_implementation_type& impl,
+ IO_Control_Command& command, boost::system::error_code& ec)
+ {
+ socket_ops::ioctl(impl.socket_, impl.state_, command.name(),
+ static_cast<ioctl_arg_type*>(command.data()), ec);
+ return ec;
+ }
+
+ // Gets the non-blocking mode of the socket.
+ bool non_blocking(const base_implementation_type& impl) const
+ {
+ return (impl.state_ & socket_ops::user_set_non_blocking) != 0;
+ }
+
+ // Sets the non-blocking mode of the socket.
+ boost::system::error_code non_blocking(base_implementation_type& impl,
+ bool mode, boost::system::error_code& ec)
+ {
+ socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec);
+ return ec;
+ }
+
+ // Gets the non-blocking mode of the native socket implementation.
+ bool native_non_blocking(const base_implementation_type& impl) const
+ {
+ return (impl.state_ & socket_ops::internal_non_blocking) != 0;
+ }
+
+ // Sets the non-blocking mode of the native socket implementation.
+ boost::system::error_code native_non_blocking(base_implementation_type& impl,
+ bool mode, boost::system::error_code& ec)
+ {
+ socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec);
+ return ec;
+ }
+
+ // Wait for the socket to become ready to read, ready to write, or to have
+ // pending error conditions.
+ boost::system::error_code wait(base_implementation_type& impl,
+ socket_base::wait_type w, boost::system::error_code& ec)
+ {
+ switch (w)
+ {
+ case socket_base::wait_read:
+ socket_ops::poll_read(impl.socket_, impl.state_, -1, ec);
+ break;
+ case socket_base::wait_write:
+ socket_ops::poll_write(impl.socket_, impl.state_, -1, ec);
+ break;
+ case socket_base::wait_error:
+ socket_ops::poll_error(impl.socket_, impl.state_, -1, ec);
+ break;
+ default:
+ ec = boost::asio::error::invalid_argument;
+ break;
+ }
+
+ return ec;
+ }
+
+ // Asynchronously wait for the socket to become ready to read, ready to
+ // write, or to have pending error conditions.
+ template <typename Handler, typename IoExecutor>
+ void async_wait(base_implementation_type& impl,
+ socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_wait_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_wait"));
+
+ int op_type;
+ switch (w)
+ {
+ case socket_base::wait_read:
+ op_type = reactor::read_op;
+ break;
+ case socket_base::wait_write:
+ op_type = reactor::write_op;
+ break;
+ case socket_base::wait_error:
+ op_type = reactor::except_op;
+ break;
+ default:
+ p.p->ec_ = boost::asio::error::invalid_argument;
+ reactor_.post_immediate_completion(p.p, is_continuation);
+ p.v = p.p = 0;
+ return;
+ }
+
+ start_op(impl, op_type, p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Send the given data to the peer.
+ template <typename ConstBufferSequence>
+ size_t send(base_implementation_type& impl,
+ const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_send(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
+ }
+
+ // Wait until data can be sent without blocking.
+ size_t send(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_write(impl.socket_, impl.state_, -1, ec);
+
+ return 0;
+ }
+
+ // Start an asynchronous send. The data being sent must be valid for the
+ // lifetime of the asynchronous operation.
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
+ void async_send(base_implementation_type& impl,
+ const ConstBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_send_op<
+ ConstBufferSequence, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_,
+ buffers, flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_send"));
+
+ start_op(impl, reactor::write_op, p.p, is_continuation, true,
+ ((impl.state_ & socket_ops::stream_oriented)
+ && buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence>::all_empty(buffers)));
+ p.v = p.p = 0;
+ }
+
+ // Start an asynchronous wait until data can be sent without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_send(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_send(null_buffers)"));
+
+ start_op(impl, reactor::write_op, p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Receive some data from the peer. Returns the number of bytes received.
+ template <typename MutableBufferSequence>
+ size_t receive(base_implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_recv(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
+ }
+
+ // Wait until data can be received without blocking.
+ size_t receive(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_read(impl.socket_, impl.state_, -1, ec);
+
+ return 0;
+ }
+
+ // Start an asynchronous receive. The buffer for the data being received
+ // must be valid for the lifetime of the asynchronous operation.
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
+ void async_receive(base_implementation_type& impl,
+ const MutableBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_recv_op_ext_local<
+ MutableBufferSequence, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_,
+ buffers, flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive"));
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation,
+ (flags & socket_base::message_out_of_band) == 0,
+ ((impl.state_ & socket_ops::stream_oriented)
+ && buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence>::all_empty(buffers)));
+ p.v = p.p = 0;
+ }
+
+ // Wait until data can be received without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_receive(base_implementation_type& impl,
+ const null_buffers&, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive(null_buffers)"));
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Receive some data with associated flags. Returns the number of bytes
+ // received.
+ template <typename MutableBufferSequence>
+ size_t receive_with_flags(base_implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_recvmsg(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), in_flags, out_flags, ec);
+ }
+
+ // Wait until data can be received without blocking.
+ size_t receive_with_flags(base_implementation_type& impl,
+ const null_buffers&, socket_base::message_flags,
+ socket_base::message_flags& out_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_read(impl.socket_, impl.state_, -1, ec);
+
+ // Clear out_flags, since we cannot give it any other sensible value when
+ // performing a null_buffers operation.
+ out_flags = 0;
+
+ return 0;
+ }
+
+ // Start an asynchronous receive. The buffer for the data being received
+ // must be valid for the lifetime of the asynchronous operation.
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
+ void async_receive_with_flags(base_implementation_type& impl,
+ const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_recvmsg_op_ext_local<
+ MutableBufferSequence, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, buffers,
+ in_flags, out_flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive_with_flags"));
+
+ start_op(impl,
+ (in_flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation,
+ (in_flags & socket_base::message_out_of_band) == 0, false);
+ p.v = p.p = 0;
+ }
+
+ // Wait until data can be received without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_receive_with_flags(base_implementation_type& impl,
+ const null_buffers&, socket_base::message_flags in_flags,
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive_with_flags(null_buffers)"));
+
+ // Clear out_flags, since we cannot give it any other sensible value when
+ // performing a null_buffers operation.
+ out_flags = 0;
+
+ start_op(impl,
+ (in_flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+protected:
+ // Open a new socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code do_open(
+ base_implementation_type& impl, int af,
+ int type, int protocol, boost::system::error_code& ec);
+
+ // Assign a native socket to a socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code do_assign(
+ base_implementation_type& impl, int type,
+ const native_handle_type& native_socket, boost::system::error_code& ec);
+
+ // Start the asynchronous read or write operation.
+ BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type,
+ reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop);
+
+ // Start the asynchronous accept operation.
+ BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl,
+ reactor_op* op, bool is_continuation, bool peer_is_open);
+
+ // Start the asynchronous connect operation.
+ BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl,
+ reactor_op* op, bool is_continuation,
+ const socket_addr_type* addr, size_t addrlen);
+
+ // The selector that performs event demultiplexing for the service.
+ reactor& reactor_;
+
+ // Cached success value to avoid accessing category singleton.
+ const boost::system::error_code success_ec_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+ // && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp
new file mode 100644
index 0000000..7254ccd
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp
@@ -0,0 +1,508 @@
+//
+// detail/reactive_socket_service_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/socket_base.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/reactive_null_buffers_op.hpp>
+#include <boost/asio/detail/reactive_socket_accept_op.hpp>
+#include <boost/asio/detail/reactive_socket_connect_op.hpp>
+#include <boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp>
+#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
+#include <boost/asio/detail/reactive_socket_service_base_ext.hpp>
+#include <boost/asio/detail/reactor.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
+#include <boost/asio/detail/socket_holder.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Protocol>
+class reactive_socket_service_ext :
+ public execution_context_service_base<reactive_socket_service_ext<Protocol> >,
+ public reactive_socket_service_base_ext
+{
+public:
+ // The protocol type.
+ typedef Protocol protocol_type;
+
+ // The endpoint type.
+ typedef typename Protocol::endpoint endpoint_type;
+
+ // The native type of a socket.
+ typedef socket_type native_handle_type;
+
+ // The implementation type of the socket.
+ struct implementation_type :
+ reactive_socket_service_base_ext::base_implementation_type
+ {
+ // Default constructor.
+ implementation_type()
+ : protocol_(endpoint_type().protocol())
+ {
+ }
+
+ // The protocol associated with the socket.
+ protocol_type protocol_;
+ };
+
+ // Constructor.
+ reactive_socket_service_ext(execution_context& context)
+ : execution_context_service_base<
+ reactive_socket_service_ext<Protocol> >(context),
+ reactive_socket_service_base_ext(context)
+ {
+ }
+
+ // Destroy all user-defined handler objects owned by the service.
+ void shutdown()
+ {
+ this->base_shutdown();
+ }
+
+ // Move-construct a new socket implementation.
+ void move_construct(implementation_type& impl,
+ implementation_type& other_impl)
+ {
+ this->base_move_construct(impl, other_impl);
+
+ impl.protocol_ = other_impl.protocol_;
+ other_impl.protocol_ = endpoint_type().protocol();
+ }
+
+ // Move-assign from another socket implementation.
+ void move_assign(implementation_type& impl,
+ reactive_socket_service_base_ext& other_service,
+ implementation_type& other_impl)
+ {
+ this->base_move_assign(impl, other_service, other_impl);
+
+ impl.protocol_ = other_impl.protocol_;
+ other_impl.protocol_ = endpoint_type().protocol();
+ }
+
+ // Move-construct a new socket implementation from another protocol type.
+ template <typename Protocol1>
+ void converting_move_construct(implementation_type& impl,
+ reactive_socket_service_ext<Protocol1>&,
+ typename reactive_socket_service_ext<
+ Protocol1>::implementation_type& other_impl)
+ {
+ this->base_move_construct(impl, other_impl);
+
+ impl.protocol_ = protocol_type(other_impl.protocol_);
+ other_impl.protocol_ = typename Protocol1::endpoint().protocol();
+ }
+
+ // Open a new socket implementation.
+ boost::system::error_code open(implementation_type& impl,
+ const protocol_type& protocol, boost::system::error_code& ec)
+ {
+ if (!do_open(impl, protocol.family(),
+ protocol.type(), protocol.protocol(), ec))
+ impl.protocol_ = protocol;
+ return ec;
+ }
+
+ // Assign a native socket to a socket implementation.
+ boost::system::error_code assign(implementation_type& impl,
+ const protocol_type& protocol, const native_handle_type& native_socket,
+ boost::system::error_code& ec)
+ {
+ if (!do_assign(impl, protocol.type(), native_socket, ec))
+ impl.protocol_ = protocol;
+ return ec;
+ }
+
+ // Get the native socket representation.
+ native_handle_type native_handle(implementation_type& impl)
+ {
+ return impl.socket_;
+ }
+
+ // Bind the socket to the specified local endpoint.
+ boost::system::error_code bind(implementation_type& impl,
+ const endpoint_type& endpoint, boost::system::error_code& ec)
+ {
+ socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec);
+ return ec;
+ }
+
+ // Set a socket option.
+ template <typename Option>
+ boost::system::error_code set_option(implementation_type& impl,
+ const Option& option, boost::system::error_code& ec)
+ {
+ socket_ops::setsockopt(impl.socket_, impl.state_,
+ option.level(impl.protocol_), option.name(impl.protocol_),
+ option.data(impl.protocol_), option.size(impl.protocol_), ec);
+ return ec;
+ }
+
+ // Set a socket option.
+ template <typename Option>
+ boost::system::error_code get_option(const implementation_type& impl,
+ Option& option, boost::system::error_code& ec) const
+ {
+ std::size_t size = option.size(impl.protocol_);
+ socket_ops::getsockopt(impl.socket_, impl.state_,
+ option.level(impl.protocol_), option.name(impl.protocol_),
+ option.data(impl.protocol_), &size, ec);
+ if (!ec)
+ option.resize(impl.protocol_, size);
+ return ec;
+ }
+
+ // Get the local endpoint.
+ endpoint_type local_endpoint(const implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ endpoint_type endpoint;
+ std::size_t addr_len = endpoint.capacity();
+ if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
+ return endpoint_type();
+ endpoint.resize(addr_len);
+ return endpoint;
+ }
+
+ // Get the remote endpoint.
+ endpoint_type remote_endpoint(const implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ endpoint_type endpoint;
+ std::size_t addr_len = endpoint.capacity();
+ if (socket_ops::getpeername(impl.socket_,
+ endpoint.data(), &addr_len, false, ec))
+ return endpoint_type();
+ endpoint.resize(addr_len);
+ return endpoint;
+ }
+
+ // Disable sends or receives on the socket.
+ boost::system::error_code shutdown(base_implementation_type& impl,
+ socket_base::shutdown_type what, boost::system::error_code& ec)
+ {
+ socket_ops::shutdown(impl.socket_, what, ec);
+ return ec;
+ }
+
+ // Send a datagram to the specified endpoint. Returns the number of bytes
+ // sent.
+ template <typename ConstBufferSequence>
+ size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers,
+ const endpoint_type& destination, socket_base::message_flags flags,
+ boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_sendto(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags,
+ destination.data(), destination.size(), ec);
+ }
+
+ // Wait until data can be sent without blocking.
+ size_t send_to(implementation_type& impl, const null_buffers&,
+ const endpoint_type&, socket_base::message_flags,
+ boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_write(impl.socket_, impl.state_, -1, ec);
+
+ return 0;
+ }
+
+ // Start an asynchronous send. The data being sent must be valid for the
+ // lifetime of the asynchronous operation.
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
+ void async_send_to(implementation_type& impl,
+ const ConstBufferSequence& buffers,
+ const endpoint_type& destination, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_sendto_op<ConstBufferSequence,
+ endpoint_type, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, buffers,
+ destination, flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_send_to"));
+
+ start_op(impl, reactor::write_op, p.p, is_continuation, true, false);
+ p.v = p.p = 0;
+ }
+
+ // Start an asynchronous wait until data can be sent without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_send_to(implementation_type& impl, const null_buffers&,
+ const endpoint_type&, socket_base::message_flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_send_to(null_buffers)"));
+
+ start_op(impl, reactor::write_op, p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Receive a datagram with the endpoint of the sender. Returns the number of
+ // bytes received.
+ template <typename MutableBufferSequence>
+ size_t receive_from(implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ endpoint_type& sender_endpoint, socket_base::message_flags flags,
+ boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(buffers);
+
+ std::size_t addr_len = sender_endpoint.capacity();
+ std::size_t bytes_recvd = socket_ops::sync_recvfrom(
+ impl.socket_, impl.state_, bufs.buffers(), bufs.count(),
+ flags, sender_endpoint.data(), &addr_len, ec);
+
+ if (!ec)
+ sender_endpoint.resize(addr_len);
+
+ return bytes_recvd;
+ }
+
+ // Wait until data can be received without blocking.
+ size_t receive_from(implementation_type& impl, const null_buffers&,
+ endpoint_type& sender_endpoint, socket_base::message_flags,
+ boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_read(impl.socket_, impl.state_, -1, ec);
+
+ // Reset endpoint since it can be given no sensible value at this time.
+ sender_endpoint = endpoint_type();
+
+ return 0;
+ }
+
+ // Start an asynchronous receive. The buffer for the data being received and
+ // the sender_endpoint object must both be valid for the lifetime of the
+ // asynchronous operation.
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
+ void async_receive_from(implementation_type& impl,
+ const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
+ socket_base::message_flags flags, Handler& handler,
+ const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_recvfrom_op_ext<MutableBufferSequence,
+ endpoint_type, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ int protocol = impl.protocol_.type();
+ p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers,
+ sender_endpoint, flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive_from"));
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation, true, false);
+ p.v = p.p = 0;
+ }
+
+ // Wait until data can be received without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_receive_from(implementation_type& impl, const null_buffers&,
+ endpoint_type& sender_endpoint, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive_from(null_buffers)"));
+
+ // Reset endpoint since it can be given no sensible value at this time.
+ sender_endpoint = endpoint_type();
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Accept a new connection.
+ template <typename Socket>
+ boost::system::error_code accept(implementation_type& impl,
+ Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec)
+ {
+ // We cannot accept a socket that is already open.
+ if (peer.is_open())
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0;
+ socket_holder new_socket(socket_ops::sync_accept(impl.socket_,
+ impl.state_, peer_endpoint ? peer_endpoint->data() : 0,
+ peer_endpoint ? &addr_len : 0, ec));
+
+ // On success, assign new connection to peer socket object.
+ if (new_socket.get() != invalid_socket)
+ {
+ if (peer_endpoint)
+ peer_endpoint->resize(addr_len);
+ peer.assign(impl.protocol_, new_socket.get(), ec);
+ if (!ec)
+ new_socket.release();
+ }
+
+ return ec;
+ }
+
+ // Start an asynchronous accept. The peer and peer_endpoint objects must be
+ // valid until the accept's handler is invoked.
+ template <typename Socket, typename Handler, typename IoExecutor>
+ void async_accept(implementation_type& impl, Socket& peer,
+ endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_accept_op<Socket, Protocol, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer,
+ impl.protocol_, peer_endpoint, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_accept"));
+
+ start_accept_op(impl, p.p, is_continuation, peer.is_open());
+ p.v = p.p = 0;
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ // Start an asynchronous accept. The peer_endpoint object must be valid until
+ // the accept's handler is invoked.
+ template <typename PeerIoExecutor, typename Handler, typename IoExecutor>
+ void async_move_accept(implementation_type& impl,
+ const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_move_accept_op<Protocol,
+ PeerIoExecutor, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_,
+ impl.protocol_, peer_endpoint, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_accept"));
+
+ start_accept_op(impl, p.p, is_continuation, false);
+ p.v = p.p = 0;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ // Connect the socket to the specified endpoint.
+ boost::system::error_code connect(implementation_type& impl,
+ const endpoint_type& peer_endpoint, boost::system::error_code& ec)
+ {
+ socket_ops::sync_connect(impl.socket_,
+ peer_endpoint.data(), peer_endpoint.size(), ec);
+ return ec;
+ }
+
+ // Start an asynchronous connect.
+ template <typename Handler, typename IoExecutor>
+ void async_connect(implementation_type& impl,
+ const endpoint_type& peer_endpoint,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_connect_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_connect"));
+
+ start_connect_op(impl, p.p, is_continuation,
+ peer_endpoint.data(), peer_endpoint.size());
+ p.v = p.p = 0;
+ }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp
new file mode 100644
index 0000000..8ac3265
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp
@@ -0,0 +1,508 @@
+//
+// detail/reactive_socket_service_ext_local.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/socket_base.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/reactive_null_buffers_op.hpp>
+#include <boost/asio/detail/reactive_socket_accept_op.hpp>
+#include <boost/asio/detail/reactive_socket_connect_op.hpp>
+#include <boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp>
+#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
+#include <boost/asio/detail/reactive_socket_service_base_ext_local.hpp>
+#include <boost/asio/detail/reactor.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
+#include <boost/asio/detail/socket_holder.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Protocol>
+class reactive_socket_service_ext_local :
+ public execution_context_service_base<reactive_socket_service_ext_local<Protocol> >,
+ public reactive_socket_service_base_ext_local
+{
+public:
+ // The protocol type.
+ typedef Protocol protocol_type;
+
+ // The endpoint type.
+ typedef typename Protocol::endpoint endpoint_type;
+
+ // The native type of a socket.
+ typedef socket_type native_handle_type;
+
+ // The implementation type of the socket.
+ struct implementation_type :
+ reactive_socket_service_base_ext_local::base_implementation_type
+ {
+ // Default constructor.
+ implementation_type()
+ : protocol_(endpoint_type().protocol())
+ {
+ }
+
+ // The protocol associated with the socket.
+ protocol_type protocol_;
+ };
+
+ // Constructor.
+ reactive_socket_service_ext_local(execution_context& context)
+ : execution_context_service_base<
+ reactive_socket_service_ext_local<Protocol> >(context),
+ reactive_socket_service_base_ext_local(context)
+ {
+ }
+
+ // Destroy all user-defined handler objects owned by the service.
+ void shutdown()
+ {
+ this->base_shutdown();
+ }
+
+ // Move-construct a new socket implementation.
+ void move_construct(implementation_type& impl,
+ implementation_type& other_impl)
+ {
+ this->base_move_construct(impl, other_impl);
+
+ impl.protocol_ = other_impl.protocol_;
+ other_impl.protocol_ = endpoint_type().protocol();
+ }
+
+ // Move-assign from another socket implementation.
+ void move_assign(implementation_type& impl,
+ reactive_socket_service_base_ext_local& other_service,
+ implementation_type& other_impl)
+ {
+ this->base_move_assign(impl, other_service, other_impl);
+
+ impl.protocol_ = other_impl.protocol_;
+ other_impl.protocol_ = endpoint_type().protocol();
+ }
+
+ // Move-construct a new socket implementation from another protocol type.
+ template <typename Protocol1>
+ void converting_move_construct(implementation_type& impl,
+ reactive_socket_service_ext_local<Protocol1>&,
+ typename reactive_socket_service_ext_local<
+ Protocol1>::implementation_type& other_impl)
+ {
+ this->base_move_construct(impl, other_impl);
+
+ impl.protocol_ = protocol_type(other_impl.protocol_);
+ other_impl.protocol_ = typename Protocol1::endpoint().protocol();
+ }
+
+ // Open a new socket implementation.
+ boost::system::error_code open(implementation_type& impl,
+ const protocol_type& protocol, boost::system::error_code& ec)
+ {
+ if (!do_open(impl, protocol.family(),
+ protocol.type(), protocol.protocol(), ec))
+ impl.protocol_ = protocol;
+ return ec;
+ }
+
+ // Assign a native socket to a socket implementation.
+ boost::system::error_code assign(implementation_type& impl,
+ const protocol_type& protocol, const native_handle_type& native_socket,
+ boost::system::error_code& ec)
+ {
+ if (!do_assign(impl, protocol.type(), native_socket, ec))
+ impl.protocol_ = protocol;
+ return ec;
+ }
+
+ // Get the native socket representation.
+ native_handle_type native_handle(implementation_type& impl)
+ {
+ return impl.socket_;
+ }
+
+ // Bind the socket to the specified local endpoint.
+ boost::system::error_code bind(implementation_type& impl,
+ const endpoint_type& endpoint, boost::system::error_code& ec)
+ {
+ socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec);
+ return ec;
+ }
+
+ // Set a socket option.
+ template <typename Option>
+ boost::system::error_code set_option(implementation_type& impl,
+ const Option& option, boost::system::error_code& ec)
+ {
+ socket_ops::setsockopt(impl.socket_, impl.state_,
+ option.level(impl.protocol_), option.name(impl.protocol_),
+ option.data(impl.protocol_), option.size(impl.protocol_), ec);
+ return ec;
+ }
+
+ // Set a socket option.
+ template <typename Option>
+ boost::system::error_code get_option(const implementation_type& impl,
+ Option& option, boost::system::error_code& ec) const
+ {
+ std::size_t size = option.size(impl.protocol_);
+ socket_ops::getsockopt(impl.socket_, impl.state_,
+ option.level(impl.protocol_), option.name(impl.protocol_),
+ option.data(impl.protocol_), &size, ec);
+ if (!ec)
+ option.resize(impl.protocol_, size);
+ return ec;
+ }
+
+ // Get the local endpoint.
+ endpoint_type local_endpoint(const implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ endpoint_type endpoint;
+ std::size_t addr_len = endpoint.capacity();
+ if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
+ return endpoint_type();
+ endpoint.resize(addr_len);
+ return endpoint;
+ }
+
+ // Get the remote endpoint.
+ endpoint_type remote_endpoint(const implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ endpoint_type endpoint;
+ std::size_t addr_len = endpoint.capacity();
+ if (socket_ops::getpeername(impl.socket_,
+ endpoint.data(), &addr_len, false, ec))
+ return endpoint_type();
+ endpoint.resize(addr_len);
+ return endpoint;
+ }
+
+ // Disable sends or receives on the socket.
+ boost::system::error_code shutdown(base_implementation_type& impl,
+ socket_base::shutdown_type what, boost::system::error_code& ec)
+ {
+ socket_ops::shutdown(impl.socket_, what, ec);
+ return ec;
+ }
+
+ // Send a datagram to the specified endpoint. Returns the number of bytes
+ // sent.
+ template <typename ConstBufferSequence>
+ size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers,
+ const endpoint_type& destination, socket_base::message_flags flags,
+ boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_sendto(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags,
+ destination.data(), destination.size(), ec);
+ }
+
+ // Wait until data can be sent without blocking.
+ size_t send_to(implementation_type& impl, const null_buffers&,
+ const endpoint_type&, socket_base::message_flags,
+ boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_write(impl.socket_, impl.state_, -1, ec);
+
+ return 0;
+ }
+
+ // Start an asynchronous send. The data being sent must be valid for the
+ // lifetime of the asynchronous operation.
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
+ void async_send_to(implementation_type& impl,
+ const ConstBufferSequence& buffers,
+ const endpoint_type& destination, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_sendto_op<ConstBufferSequence,
+ endpoint_type, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, buffers,
+ destination, flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_send_to"));
+
+ start_op(impl, reactor::write_op, p.p, is_continuation, true, false);
+ p.v = p.p = 0;
+ }
+
+ // Start an asynchronous wait until data can be sent without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_send_to(implementation_type& impl, const null_buffers&,
+ const endpoint_type&, socket_base::message_flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_send_to(null_buffers)"));
+
+ start_op(impl, reactor::write_op, p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Receive a datagram with the endpoint of the sender. Returns the number of
+ // bytes received.
+ template <typename MutableBufferSequence>
+ size_t receive_from(implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ endpoint_type& sender_endpoint, socket_base::message_flags flags,
+ boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(buffers);
+
+ std::size_t addr_len = sender_endpoint.capacity();
+ std::size_t bytes_recvd = socket_ops::sync_recvfrom(
+ impl.socket_, impl.state_, bufs.buffers(), bufs.count(),
+ flags, sender_endpoint.data(), &addr_len, ec);
+
+ if (!ec)
+ sender_endpoint.resize(addr_len);
+
+ return bytes_recvd;
+ }
+
+ // Wait until data can be received without blocking.
+ size_t receive_from(implementation_type& impl, const null_buffers&,
+ endpoint_type& sender_endpoint, socket_base::message_flags,
+ boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_read(impl.socket_, impl.state_, -1, ec);
+
+ // Reset endpoint since it can be given no sensible value at this time.
+ sender_endpoint = endpoint_type();
+
+ return 0;
+ }
+
+ // Start an asynchronous receive. The buffer for the data being received and
+ // the sender_endpoint object must both be valid for the lifetime of the
+ // asynchronous operation.
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
+ void async_receive_from(implementation_type& impl,
+ const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
+ socket_base::message_flags flags, Handler& handler,
+ const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_recvfrom_op_ext_local<MutableBufferSequence,
+ endpoint_type, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ int protocol = impl.protocol_.type();
+ p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers,
+ sender_endpoint, flags, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive_from"));
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation, true, false);
+ p.v = p.p = 0;
+ }
+
+ // Wait until data can be received without blocking.
+ template <typename Handler, typename IoExecutor>
+ void async_receive_from(implementation_type& impl, const null_buffers&,
+ endpoint_type& sender_endpoint, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_receive_from(null_buffers)"));
+
+ // Reset endpoint since it can be given no sensible value at this time.
+ sender_endpoint = endpoint_type();
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, is_continuation, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Accept a new connection.
+ template <typename Socket>
+ boost::system::error_code accept(implementation_type& impl,
+ Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec)
+ {
+ // We cannot accept a socket that is already open.
+ if (peer.is_open())
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0;
+ socket_holder new_socket(socket_ops::sync_accept(impl.socket_,
+ impl.state_, peer_endpoint ? peer_endpoint->data() : 0,
+ peer_endpoint ? &addr_len : 0, ec));
+
+ // On success, assign new connection to peer socket object.
+ if (new_socket.get() != invalid_socket)
+ {
+ if (peer_endpoint)
+ peer_endpoint->resize(addr_len);
+ peer.assign(impl.protocol_, new_socket.get(), ec);
+ if (!ec)
+ new_socket.release();
+ }
+
+ return ec;
+ }
+
+ // Start an asynchronous accept. The peer and peer_endpoint objects must be
+ // valid until the accept's handler is invoked.
+ template <typename Socket, typename Handler, typename IoExecutor>
+ void async_accept(implementation_type& impl, Socket& peer,
+ endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_accept_op<Socket, Protocol, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer,
+ impl.protocol_, peer_endpoint, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_accept"));
+
+ start_accept_op(impl, p.p, is_continuation, peer.is_open());
+ p.v = p.p = 0;
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ // Start an asynchronous accept. The peer_endpoint object must be valid until
+ // the accept's handler is invoked.
+ template <typename PeerIoExecutor, typename Handler, typename IoExecutor>
+ void async_move_accept(implementation_type& impl,
+ const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_move_accept_op<Protocol,
+ PeerIoExecutor, Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_,
+ impl.protocol_, peer_endpoint, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_accept"));
+
+ start_accept_op(impl, p.p, is_continuation, false);
+ p.v = p.p = 0;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ // Connect the socket to the specified endpoint.
+ boost::system::error_code connect(implementation_type& impl,
+ const endpoint_type& peer_endpoint, boost::system::error_code& ec)
+ {
+ socket_ops::sync_connect(impl.socket_,
+ peer_endpoint.data(), peer_endpoint.size(), ec);
+ return ec;
+ }
+
+ // Start an asynchronous connect.
+ template <typename Handler, typename IoExecutor>
+ void async_connect(implementation_type& impl,
+ const endpoint_type& peer_endpoint,
+ Handler& handler, const IoExecutor& io_ex)
+ {
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler);
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_connect_op<Handler, IoExecutor> op;
+ typename op::ptr p = { boost::asio::detail::addressof(handler),
+ op::ptr::allocate(handler), 0 };
+ p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex);
+
+ BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
+ &impl, impl.socket_, "async_connect"));
+
+ start_connect_op(impl, p.p, is_continuation,
+ peer_endpoint.data(), peer_endpoint.size());
+ p.v = p.p = 0;
+ }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp
new file mode 100644
index 0000000..697cd9f
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp
@@ -0,0 +1,43 @@
+//
+// detail/reactor_op_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP
+#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/reactor_op.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class reactor_op_ext
+ : public reactor_op
+{
+public:
+ // The destination address
+ boost::asio::ip::address da_;
+
+ reactor_op_ext(const boost::system::error_code& success_ec,
+ perform_func_type perform_func, func_type complete_func)
+ : reactor_op(success_ec, perform_func, complete_func)
+ {
+ }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp
new file mode 100644
index 0000000..3d9ae5f
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp
@@ -0,0 +1,44 @@
+//
+// detail/reactor_op_ext_local.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP
+#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/reactor_op.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class reactor_op_ext_local
+ : public reactor_op
+{
+public:
+ // Credentials
+ std::uint32_t uid_;
+ std::uint32_t gid_;
+
+ reactor_op_ext_local(const boost::system::error_code& success_ec,
+ perform_func_type perform_func, func_type complete_func)
+ : reactor_op(success_ec, perform_func, complete_func)
+ {
+ }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp
new file mode 100644
index 0000000..9285fed
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp
@@ -0,0 +1,62 @@
+//
+// detail/socket_ops_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP
+#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/socket_ops.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+namespace socket_ops {
+
+BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs,
+ size_t count, int flags, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec,
+ boost::asio::ip::address& da);
+
+BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state,
+ buf* bufs, size_t count, int flags, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da);
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+BOOST_ASIO_DECL void complete_iocp_recvfrom(
+ const weak_cancel_token_type& cancel_token,
+ boost::system::error_code& ec,
+ boost::asio::ip::address& da);
+
+#else // defined(BOOST_ASIO_HAS_IOCP)
+
+BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s,
+ buf* bufs, size_t count, int flags,
+ socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec, size_t& bytes_transferred,
+ boost::asio::ip::address& da);
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+} // namespace socket_ops
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/socket_ops_ext.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP
diff --git a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp
new file mode 100644
index 0000000..a937bb6
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp
@@ -0,0 +1,95 @@
+//
+// detail/socket_ops_ext_local.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP
+#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#include <boost/system/error_code.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+namespace socket_ops {
+
+BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs,
+ size_t count, int flags, boost::system::error_code& ec,
+ std::uint32_t& uid, std::uint32_t& gid);
+
+BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs,
+ size_t count, int flags, bool all_empty, boost::system::error_code& ec,
+ std::uint32_t& uid, std::uint32_t& gid);
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+BOOST_ASIO_DECL void complete_iocp_recv(state_type state,
+ const weak_cancel_token_type& cancel_token, bool all_empty,
+ boost::system::error_code& ec, size_t bytes_transferred,
+ std::uint32_t& uid, std::uint32_t& gid);
+
+#else // defined(BOOST_ASIO_HAS_IOCP)
+
+BOOST_ASIO_DECL bool non_blocking_recv(socket_type s,
+ buf* bufs, size_t count, int flags, bool is_stream,
+ boost::system::error_code& ec, size_t& bytes_transferred,
+ std::uint32_t& uid, std::uint32_t& gid);
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs,
+ size_t count, int flags, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec,
+ std::uint32_t& uid, std::uint32_t& gid);
+
+BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state,
+ buf* bufs, size_t count, int flags, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec,
+ std::uint32_t& uid, std::uint32_t& gid);
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+BOOST_ASIO_DECL void complete_iocp_recvfrom(
+ const weak_cancel_token_type& cancel_token,
+ boost::system::error_code& ec,
+ std::uint32_t& uid, std::uint32_t& gid);
+
+#else // defined(BOOST_ASIO_HAS_IOCP)
+
+BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s,
+ buf* bufs, size_t count, int flags,
+ socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec, size_t& bytes_transferred,
+ std::uint32_t& uid, std::uint32_t& gid);
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+
+} // namespace socket_ops
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/socket_ops_ext_local.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP
diff --git a/implementation/helper/1.76/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.76/boost/asio/ip/udp_ext.hpp
new file mode 100644
index 0000000..6ce2ac4
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/ip/udp_ext.hpp
@@ -0,0 +1,115 @@
+//
+// ip/udp_ext.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_IP_UDP_EXT_HPP
+#define BOOST_ASIO_IP_UDP_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/basic_datagram_socket_ext.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/ip/basic_endpoint.hpp>
+#include <boost/asio/ip/basic_resolver.hpp>
+#include <boost/asio/ip/basic_resolver_iterator.hpp>
+#include <boost/asio/ip/basic_resolver_query.hpp>
+#include <boost/asio/ip/udp.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+
+/// Encapsulates the flags needed for UDP.
+/**
+ * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Safe.
+ *
+ * @par Concepts:
+ * Protocol, InternetProtocol.
+ */
+class udp_ext
+{
+public:
+ /// The type of a UDP endpoint.
+ typedef basic_endpoint<udp> endpoint;
+
+ /// Construct to represent the IPv4 UDP protocol.
+ static udp_ext v4()
+ {
+ return udp_ext(BOOST_ASIO_OS_DEF(AF_INET));
+ }
+
+ /// Construct to represent the IPv6 UDP protocol.
+ static udp_ext v6()
+ {
+ return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6));
+ }
+
+ /// Obtain an identifier for the type of the protocol.
+ int type() const
+ {
+ return BOOST_ASIO_OS_DEF(SOCK_DGRAM);
+ }
+
+ /// Obtain an identifier for the protocol.
+ int protocol() const
+ {
+ return BOOST_ASIO_OS_DEF(IPPROTO_UDP);
+ }
+
+ /// Obtain an identifier for the protocol family.
+ int family() const
+ {
+ return family_;
+ }
+
+ /// The UDP socket type.
+ typedef basic_datagram_socket_ext<udp> socket;
+
+ /// The UDP resolver type.
+ typedef basic_resolver<udp> resolver;
+
+ /// Compare two protocols for equality.
+ friend bool operator==(const udp_ext& p1, const udp_ext& p2)
+ {
+ return p1.family_ == p2.family_;
+ }
+
+ /// Compare two protocols for inequality.
+ friend bool operator!=(const udp_ext& p1, const udp_ext& p2)
+ {
+ return p1.family_ != p2.family_;
+ }
+
+private:
+ // Construct with a specific family.
+ explicit udp_ext(int protocol_family)
+ : family_(protocol_family)
+ {
+ }
+
+ int family_;
+};
+
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IP_UDP_EXT_HPP
diff --git a/implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp
new file mode 100644
index 0000000..7c57c62
--- /dev/null
+++ b/implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp
@@ -0,0 +1,93 @@
+//
+// local/stream_protocol_ext.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP
+#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
+ || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/basic_socket_acceptor_ext.hpp>
+#include <boost/asio/basic_socket_iostream.hpp>
+#include <boost/asio/basic_stream_socket_ext.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/local/basic_endpoint.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace local {
+
+/// Encapsulates the flags needed for stream-oriented UNIX sockets.
+/**
+ * The boost::asio::local::stream_protocol class contains flags necessary for
+ * stream-oriented UNIX domain sockets.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Safe.
+ *
+ * @par Concepts:
+ * Protocol.
+ */
+class stream_protocol_ext
+{
+public:
+ /// Obtain an identifier for the type of the protocol.
+ int type() const
+ {
+ return SOCK_STREAM;
+ }
+
+ /// Obtain an identifier for the protocol.
+ int protocol() const
+ {
+ return 0;
+ }
+
+ /// Obtain an identifier for the protocol family.
+ int family() const
+ {
+ return AF_UNIX;
+ }
+
+ /// The type of a UNIX domain endpoint.
+ typedef basic_endpoint<stream_protocol_ext> endpoint;
+
+ /// The UNIX domain socket type.
+ typedef basic_stream_socket_ext<stream_protocol_ext> socket;
+
+ /// The UNIX domain acceptor type.
+ typedef basic_socket_acceptor_ext<stream_protocol_ext> acceptor;
+
+#if !defined(BOOST_ASIO_NO_IOSTREAM)
+ /// The UNIX domain iostream type.
+ typedef basic_socket_iostream<stream_protocol_ext> iostream;
+#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
+};
+
+} // namespace local
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+ // || defined(GENERATING_DOCUMENTATION)
+
+#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP