aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOscar Andreasson <oscar.andreasson@pelagicore.com>2018-07-31 09:32:51 +0200
committerOscar Andreasson <oan@frozentux.net>2018-08-08 12:59:43 +0200
commit13ac1d5ad3f350931cc1cb563936bd1295f6715d (patch)
treed4bd10fe71add8b007cc0221ddfa60512d73010c
parentdc30c564c28cd1d765c81e27ecd80fb03b76f4b7 (diff)
downloadmeta-ivi-13ac1d5ad3f350931cc1cb563936bd1295f6715d.tar.gz
meta-ivi-13ac1d5ad3f350931cc1cb563936bd1295f6715d.tar.bz2
meta-ivi-13ac1d5ad3f350931cc1cb563936bd1295f6715d.zip
vsomeip: bump version and patch for sumo
Add patch for compilation with boost 1.66. The current version of vsomeip does not support boost 1.66 which is part of the yocto sumo release. This patch fixes vsomeip with regards to this until vsomeip 3.0 is released. Signed-off-by: Oscar Andreasson <oscar.andreasson@pelagicore.com>
-rw-r--r--meta-ivi/recipes-core-ivi/vsomeip/vsomeip/0001-Support-boost-v1.66.patch6085
-rw-r--r--meta-ivi/recipes-core-ivi/vsomeip/vsomeip_2.10.21.bb (renamed from meta-ivi/recipes-core-ivi/vsomeip/vsomeip_2.10.10.bb)3
2 files changed, 6087 insertions, 1 deletions
diff --git a/meta-ivi/recipes-core-ivi/vsomeip/vsomeip/0001-Support-boost-v1.66.patch b/meta-ivi/recipes-core-ivi/vsomeip/vsomeip/0001-Support-boost-v1.66.patch
new file mode 100644
index 0000000..cfae72c
--- /dev/null
+++ b/meta-ivi/recipes-core-ivi/vsomeip/vsomeip/0001-Support-boost-v1.66.patch
@@ -0,0 +1,6085 @@
+From f13c0788a691c0f9714e4ff35b430881a9e34841 Mon Sep 17 00:00:00 2001
+From: Lutz Bichler <Lutz.Bichler@bmw.de>
+Date: Tue, 31 Jul 2018 12:10:39 +0200
+Subject: [PATCH] Support boost v1.66
+
+---
+ CMakeLists.txt | 8 +-
+ .../configuration/include/internal.hpp | 195 ++
+ .../endpoints/include/netlink_connector.hpp | 5 +-
+ .../src/local_client_endpoint_impl.cpp | 2 +-
+ .../src/local_server_endpoint_impl.cpp | 8 +-
+ .../src/udp_server_endpoint_impl.cpp | 4 +-
+ .../boost/asio/basic_datagram_socket_ext.hpp | 0
+ .../asio/datagram_socket_service_ext.hpp | 0
+ .../detail/handler_type_requirements_ext.hpp | 0
+ .../impl/reactive_socket_service_base_ext.ipp | 0
+ .../boost/asio/detail/impl/socket_ops_ext.ipp | 0
+ .../detail/reactive_socket_recv_op_ext.hpp | 0
+ .../reactive_socket_recvfrom_op_ext.hpp | 0
+ .../detail/reactive_socket_recvmsg_op_ext.hpp | 0
+ .../reactive_socket_service_base_ext.hpp | 0
+ .../detail/reactive_socket_service_ext.hpp | 0
+ .../boost/asio/detail/reactor_op_ext.hpp | 0
+ .../boost/asio/detail/socket_ops_ext.hpp | 0
+ .../{ => 1.55}/boost/asio/ip/udp_ext.hpp | 0
+ .../boost/asio/basic_datagram_socket_ext.hpp | 1045 ++++++++++
+ .../1.66/boost/asio/basic_socket_ext.hpp | 1760 +++++++++++++++++
+ .../detail/handler_type_requirements_ext.hpp | 565 ++++++
+ .../impl/reactive_socket_service_base_ext.ipp | 302 +++
+ .../boost/asio/detail/impl/socket_ops_ext.ipp | 210 ++
+ .../detail/reactive_socket_recv_op_ext.hpp | 138 ++
+ .../reactive_socket_recvfrom_op_ext.hpp | 141 ++
+ .../detail/reactive_socket_recvmsg_op_ext.hpp | 135 ++
+ .../reactive_socket_service_base_ext.hpp | 517 +++++
+ .../detail/reactive_socket_service_ext.hpp | 531 +++++
+ .../1.66/boost/asio/detail/reactor_op_ext.hpp | 42 +
+ .../1.66/boost/asio/detail/socket_ops_ext.hpp | 62 +
+ .../helper/1.66/boost/asio/ip/udp_ext.hpp | 115 ++
+ 32 files changed, 5775 insertions(+), 10 deletions(-)
+ create mode 100644 implementation/configuration/include/internal.hpp
+ rename implementation/helper/{ => 1.55}/boost/asio/basic_datagram_socket_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/datagram_socket_service_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/handler_type_requirements_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/impl/socket_ops_ext.ipp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/reactive_socket_recv_op_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/reactive_socket_service_base_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/reactive_socket_service_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/reactor_op_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/detail/socket_ops_ext.hpp (100%)
+ rename implementation/helper/{ => 1.55}/boost/asio/ip/udp_ext.hpp (100%)
+ create mode 100644 implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/basic_socket_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp
+ create mode 100644 implementation/helper/1.66/boost/asio/ip/udp_ext.hpp
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 2c4b3f5..f314152 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -106,6 +106,12 @@ else()
+ MESSAGE( STATUS "Boost was not found!")
+ endif()
+
++if(${Boost_VERSION} GREATER 106599)
++set(VSOMEIP_BOOST_HELPER implementation/helper/1.66)
++else()
++set(VSOMEIP_BOOST_HELPER implementation/helper/1.55)
++endif()
++
+ # DLT
+ find_package(PkgConfig)
+ pkg_check_modules(DLT "automotive-dlt >= 2.11")
+@@ -123,7 +129,7 @@ endif(NOT SystemD_FOUND)
+
+ include_directories(
+ include
+- implementation/helper
++ ${VSOMEIP_BOOST_HELPER}
+ ${DLT_INCLUDE_DIRS}
+ )
+
+diff --git a/implementation/configuration/include/internal.hpp b/implementation/configuration/include/internal.hpp
+new file mode 100644
+index 0000000..7f7d036
+--- /dev/null
++++ b/implementation/configuration/include/internal.hpp
+@@ -0,0 +1,195 @@
++// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
++// This Source Code Form is subject to the terms of the Mozilla Public
++// License, v. 2.0. If a copy of the MPL was not distributed with this
++// file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++#ifndef VSOMEIP_INTERNAL_HPP
++#define VSOMEIP_INTERNAL_HPP
++
++#include <cstdint>
++#include <limits>
++#include <vsomeip/primitive_types.hpp>
++
++#define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME"
++#define VSOMEIP_ENV_CONFIGURATION "VSOMEIP_CONFIGURATION"
++#define VSOMEIP_ENV_CONFIGURATION_MODULE "VSOMEIP_CONFIGURATION_MODULE"
++#define VSOMEIP_ENV_MANDATORY_CONFIGURATION_FILES "VSOMEIP_MANDATORY_CONFIGURATION_FILES"
++#define VSOMEIP_ENV_LOAD_PLUGINS "VSOMEIP_LOAD_PLUGINS"
++#define VSOMEIP_ENV_CLIENTSIDELOGGING "VSOMEIP_CLIENTSIDELOGGING"
++#define VSOMEIP_ENV_DEBUG_CONFIGURATION "VSOMEIP_DEBUG_CONFIGURATION"
++
++#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/etc/vsomeip.json"
++#define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json"
++#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json"
++
++#define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/etc/vsomeip"
++#define VSOMEIP_DEBUG_CONFIGURATION_FOLDER "/var/opt/public/sin/vsomeip/"
++#define VSOMEIP_LOCAL_CONFIGURATION_FOLDER "./vsomeip"
++
++#define VSOMEIP_BASE_PATH "/tmp/"
++
++#ifdef WIN32
++#define VSOMEIP_CFG_LIBRARY "vsomeip-cfg.dll"
++#else
++#define VSOMEIP_CFG_LIBRARY "libvsomeip-cfg.so.2"
++#endif
++
++#ifdef WIN32
++#define VSOMEIP_SD_LIBRARY "vsomeip-sd.dll"
++#else
++#define VSOMEIP_SD_LIBRARY "libvsomeip-sd.so.2"
++#endif
++
++#define VSOMEIP_ROUTING "vsomeipd"
++#define VSOMEIP_ROUTING_CLIENT 0
++#define VSOMEIP_ROUTING_INFO_SIZE_INIT 256
++
++#ifdef _WIN32
++#define VSOMEIP_INTERNAL_BASE_PORT 51234
++#define __func__ __FUNCTION__
++#endif
++
++#define VSOMEIP_UNICAST_ADDRESS "127.0.0.1"
++
++#define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100
++#define VSOMEIP_MAX_CONNECT_TIMEOUT 1600
++#define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000
++
++#define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 5000
++#define VSOMEIP_DEFAULT_MAX_MISSING_PONGS 3
++
++#define VSOMEIP_IO_THREAD_COUNT 2
++
++#define VSOMEIP_MAX_DISPATCHERS 10
++#define VSOMEIP_MAX_DISPATCH_TIME 100
++
++#define VSOMEIP_MAX_DESERIALIZER 5
++
++#define VSOMEIP_REQUEST_DEBOUNCE_TIME 10
++
++#define VSOMEIP_COMMAND_HEADER_SIZE 7
++
++#define VSOMEIP_COMMAND_TYPE_POS 0
++#define VSOMEIP_COMMAND_CLIENT_POS 1
++#define VSOMEIP_COMMAND_SIZE_POS_MIN 3
++#define VSOMEIP_COMMAND_SIZE_POS_MAX 6
++#define VSOMEIP_COMMAND_PAYLOAD_POS 7
++
++#define VSOMEIP_REGISTER_APPLICATION 0x00
++#define VSOMEIP_DEREGISTER_APPLICATION 0x01
++#define VSOMEIP_APPLICATION_LOST 0x02
++#define VSOMEIP_ROUTING_INFO 0x03
++#define VSOMEIP_REGISTERED_ACK 0x04
++
++#define VSOMEIP_PING 0x0E
++#define VSOMEIP_PONG 0x0F
++
++#define VSOMEIP_OFFER_SERVICE 0x10
++#define VSOMEIP_STOP_OFFER_SERVICE 0x11
++#define VSOMEIP_SUBSCRIBE 0x12
++#define VSOMEIP_UNSUBSCRIBE 0x13
++#define VSOMEIP_REQUEST_SERVICE 0x14
++#define VSOMEIP_RELEASE_SERVICE 0x15
++#define VSOMEIP_SUBSCRIBE_NACK 0x16
++#define VSOMEIP_SUBSCRIBE_ACK 0x17
++
++#define VSOMEIP_SEND 0x18
++#define VSOMEIP_NOTIFY 0x19
++#define VSOMEIP_NOTIFY_ONE 0x1A
++
++#define VSOMEIP_REGISTER_EVENT 0x1B
++#define VSOMEIP_UNREGISTER_EVENT 0x1C
++#define VSOMEIP_ID_RESPONSE 0x1D
++#define VSOMEIP_ID_REQUEST 0x1E
++#define VSOMEIP_OFFERED_SERVICES_REQUEST 0x1F
++#define VSOMEIP_OFFERED_SERVICES_RESPONSE 0x20
++#define VSOMEIP_UNSUBSCRIBE_ACK 0x21
++
++#define VSOMEIP_SEND_COMMAND_SIZE 14
++#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN 7
++#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MAX 8
++#define VSOMEIP_SEND_COMMAND_FLUSH_POS 9
++#define VSOMEIP_SEND_COMMAND_RELIABLE_POS 10
++#define VSOMEIP_SEND_COMMAND_VALID_CRC_POS 11
++#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN 12
++#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MAX 13
++#define VSOMEIP_SEND_COMMAND_PAYLOAD_POS 14
++
++#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 16
++#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 17
++#define VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE 11
++#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 16
++#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 19
++#define VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE 19
++#define VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE 19
++#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 17
++#define VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE 15
++#define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 15
++#define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 14
++#define VSOMEIP_ID_RESPONSE_COMMAND_SIZE 12
++#define VSOMEIP_ID_REQUEST_COMMAND_SIZE 13
++#define VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE 8
++
++#ifndef _WIN32
++#include <pthread.h>
++#endif
++
++#define VSOMEIP_DATA_ID 0x677D
++#define VSOMEIP_DIAGNOSIS_ADDRESS 0x00
++
++#define VSOMEIP_DEFAULT_SHM_PERMISSION 0666
++#define VSOMEIP_DEFAULT_UMASK_LOCAL_ENDPOINTS 0000
++
++#define VSOMEIP_ROUTING_READY_MESSAGE "SOME/IP routing ready."
++
++namespace vsomeip {
++
++typedef enum {
++ RIE_ADD_CLIENT = 0x0,
++ RIE_ADD_SERVICE_INSTANCE = 0x1,
++ RIE_DEL_SERVICE_INSTANCE = 0x2,
++ RIE_DEL_CLIENT = 0x3,
++} routing_info_entry_e;
++
++struct service_data_t {
++ service_t service_;
++ instance_t instance_;
++ major_version_t major_;
++ minor_version_t minor_;
++ bool use_exclusive_proxy_; // only used for requests!
++
++ bool operator<(const service_data_t &_other) const {
++ return (service_ < _other.service_
++ || (service_ == _other.service_
++ && instance_ < _other.instance_));
++ }
++};
++
++typedef enum {
++ SUBSCRIPTION_ACKNOWLEDGED,
++ SUBSCRIPTION_NOT_ACKNOWLEDGED,
++ IS_SUBSCRIBING
++} subscription_state_e;
++
++struct configuration_data_t {
++#ifndef _WIN32
++ volatile char initialized_;
++ pthread_mutex_t mutex_;
++ pid_t pid_;
++#endif
++ unsigned short client_base_;
++ unsigned short max_clients_;
++ int max_used_client_ids_index_;
++ unsigned short max_assigned_client_id_without_diagnosis_;
++ unsigned short routing_manager_host_;
++ // array of used client ids here, pointer to it is kept in utility class
++};
++
++const std::uint32_t MESSAGE_SIZE_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)();
++
++const std::uint32_t QUEUE_SIZE_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)();
++
++
++} // namespace vsomeip
++
++#endif // VSOMEIP_INTERNAL_HPP
+diff --git a/implementation/endpoints/include/netlink_connector.hpp b/implementation/endpoints/include/netlink_connector.hpp
+index f71ba88..3527d5d 100644
+--- a/implementation/endpoints/include/netlink_connector.hpp
++++ b/implementation/endpoints/include/netlink_connector.hpp
+@@ -15,8 +15,9 @@
+ #include <map>
+ #include <mutex>
+
+-#include <boost/asio/ip/address.hpp>
++#include <boost/asio/io_service.hpp>
+ #include <boost/asio/basic_raw_socket.hpp>
++#include <boost/asio/ip/address.hpp>
+
+ #include "../../endpoints/include/buffer.hpp"
+
+@@ -67,7 +68,7 @@ public:
+ /// Get the underlying endpoint in the native type.
+ data_type* data()
+ {
+- return &sockaddr;
++ return reinterpret_cast<struct sockaddr*>(&sockaddr);
+ }
+
+ /// Get the underlying endpoint in the native type.
+diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp
+index 29d861f..06ef995 100644
+--- a/implementation/endpoints/src/local_client_endpoint_impl.cpp
++++ b/implementation/endpoints/src/local_client_endpoint_impl.cpp
+@@ -125,7 +125,7 @@ void local_client_endpoint_impl::connect() {
+ auto its_host = host_.lock();
+ if (its_host) {
+ if (its_host->get_configuration()->is_security_enabled()) {
+- credentials::send_credentials(socket_->native(),
++ credentials::send_credentials(socket_->native_handle(),
+ its_host->get_client());
+ }
+ }
+diff --git a/implementation/endpoints/src/local_server_endpoint_impl.cpp b/implementation/endpoints/src/local_server_endpoint_impl.cpp
+index 6ae9c6c..5522afb 100644
+--- a/implementation/endpoints/src/local_server_endpoint_impl.cpp
++++ b/implementation/endpoints/src/local_server_endpoint_impl.cpp
+@@ -49,7 +49,7 @@ local_server_endpoint_impl::local_server_endpoint_impl(
+
+ #ifndef _WIN32
+ if (_host->get_configuration()->is_security_enabled()) {
+- credentials::activate_credentials(acceptor_.native());
++ credentials::activate_credentials(acceptor_.native_handle());
+ }
+ #endif
+ }
+@@ -73,7 +73,7 @@ local_server_endpoint_impl::local_server_endpoint_impl(
+
+ #ifndef _WIN32
+ if (_host->get_configuration()->is_security_enabled()) {
+- credentials::activate_credentials(acceptor_.native());
++ credentials::activate_credentials(acceptor_.native_handle());
+ }
+ #endif
+ }
+@@ -208,7 +208,7 @@ void local_server_endpoint_impl::accept_cbk(
+ uid_t uid(0);
+ gid_t gid(0);
+ client_t client = credentials::receive_credentials(
+- new_connection_socket.native(), uid, gid);
++ new_connection_socket.native_handle(), uid, gid);
+ if (!its_host->check_credentials(client, uid, gid)) {
+ VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client()
+ << " received client credentials from client 0x" << client
+@@ -220,7 +220,7 @@ void local_server_endpoint_impl::accept_cbk(
+ return;
+ }
+ _connection->set_bound_client(client);
+- credentials::deactivate_credentials(new_connection_socket.native());
++ credentials::deactivate_credentials(new_connection_socket.native_handle());
+ }
+ }
+ #endif
+diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
+index 6da5b32..b64eb32 100644
+--- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp
++++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
+@@ -62,11 +62,11 @@ udp_server_endpoint_impl::udp_server_endpoint_impl(
+
+ #ifdef _WIN32
+ const char* optval("0001");
+- ::setsockopt(socket_.native(), IPPROTO_IP, IP_PKTINFO,
++ ::setsockopt(socket_.native_handle(), IPPROTO_IP, IP_PKTINFO,
+ optval, sizeof(optval));
+ #else
+ int optval(1);
+- ::setsockopt(socket_.native(), IPPROTO_IP, IP_PKTINFO,
++ ::setsockopt(socket_.native_handle(), IPPROTO_IP, IP_PKTINFO,
+ &optval, sizeof(optval));
+ #endif
+ }
+diff --git a/implementation/helper/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/basic_datagram_socket_ext.hpp
+rename to implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp
+diff --git a/implementation/helper/boost/asio/datagram_socket_service_ext.hpp b/implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/datagram_socket_service_ext.hpp
+rename to implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp
+diff --git a/implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp
+rename to implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp
+diff --git a/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp
+rename to implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp
+diff --git a/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp
+rename to implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp
+diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp
+rename to implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext.hpp
+diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp
+rename to implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp
+diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp
+rename to implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp
+diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp
+rename to implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext.hpp
+diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp
+rename to implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp
+diff --git a/implementation/helper/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/reactor_op_ext.hpp
+rename to implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp
+diff --git a/implementation/helper/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/detail/socket_ops_ext.hpp
+rename to implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp
+diff --git a/implementation/helper/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.55/boost/asio/ip/udp_ext.hpp
+similarity index 100%
+rename from implementation/helper/boost/asio/ip/udp_ext.hpp
+rename to implementation/helper/1.55/boost/asio/ip/udp_ext.hpp
+diff --git a/implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp
+new file mode 100644
+index 0000000..bc893a2
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp
+@@ -0,0 +1,1045 @@
++//
++// basic_datagram_socket_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_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 <iostream>
++
++#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/throw_error.hpp>
++#include <boost/asio/detail/type_traits.hpp>
++#include <boost/asio/error.hpp>
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++#include <boost/asio/detail/datagram_socket_service_ext.hpp>
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++
++#include <boost/asio/detail/push_options.hpp>
++
++namespace boost {
++namespace asio {
++
++/// 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
++ BOOST_ASIO_SVC_TPARAM_DEF1(= datagram_socket_service_ext<Protocol>)>
++class basic_datagram_socket_ext
++ : public basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>
++{
++public:
++ /// The native representation of a socket.
++#if defined(GENERATING_DOCUMENTATION)
++ typedef implementation_defined native_handle_type;
++#else
++ typedef typename basic_socket_ext<
++ Protocol BOOST_ASIO_SVC_TARG>::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 io_context The io_service object that the datagram socket will use
++ * to dispatch handlers for any asynchronous operations performed on the
++ * socket.
++ */
++ explicit basic_datagram_socket_ext(boost::asio::io_context& io_context)
++ : basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>(io_context)
++ {
++ }
++
++ /// Construct and open a basic_datagram_socket.
++ /**
++ * This constructor creates and opens a datagram socket.
++ *
++ * @param io_context The io_context object that the datagram socket will use
++ * 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(boost::asio::io_context& io_context,
++ const protocol_type& protocol)
++ : basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>(io_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 io_context The io_context object that the datagram socket will use
++ * 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(boost::asio::io_context& io_context,
++ const endpoint_type& endpoint)
++ : basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>(io_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 io_context The io_context object that the datagram socket will use
++ * 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(boost::asio::io_context& io_context,
++ const protocol_type& protocol, const native_handle_type& native_socket)
++ : basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>(
++ io_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(io_context&) constructor.
++ */
++ basic_datagram_socket_ext(basic_datagram_socket_ext&& other)
++ : basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>(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(io_context&) constructor.
++ */
++ basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other)
++ {
++ basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>::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(io_context&) constructor.
++ */
++ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
++ basic_datagram_socket_ext(
++ basic_datagram_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
++ typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
++ : basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>(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(io_context&) constructor.
++ */
++ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
++ typename enable_if<is_convertible<Protocol1, Protocol>::value,
++ basic_datagram_socket_ext>::type& operator=(
++ basic_datagram_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
++ {
++ basic_socket_ext<Protocol BOOST_ASIO_SVC_TARG>::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->get_service().send(
++ this->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->get_service().send(
++ this->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->get_service().send(
++ this->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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::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)
++ {
++ // 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;
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_send(this->get_implementation(),
++ buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<WriteHandler,
++ void (boost::system::error_code, std::size_t)> init(handler);
++
++ this->get_service().async_send(this->get_implementation(),
++ buffers, 0, init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++
++ /// 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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::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)
++ {
++ // 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;
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_send(this->get_implementation(),
++ buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<WriteHandler,
++ void (boost::system::error_code, std::size_t)> init(handler);
++
++ this->get_service().async_send(this->get_implementation(),
++ buffers, flags, init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++
++ /// 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->get_service().send_to(
++ this->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->get_service().send_to(
++ this->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->get_service().send_to(this->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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::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)
++ {
++ // 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;
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_send_to(
++ this->get_implementation(), buffers, destination, 0,
++ BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<WriteHandler,
++ void (boost::system::error_code, std::size_t)> init(handler);
++
++ this->get_service().async_send_to(
++ this->get_implementation(), buffers, destination, 0,
++ init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++
++ /// 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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::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)
++ {
++ // 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;
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_send_to(
++ this->get_implementation(), buffers, destination, flags,
++ BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<WriteHandler,
++ void (boost::system::error_code, std::size_t)> init(handler);
++
++ this->get_service().async_send_to(
++ this->get_implementation(), buffers, destination, flags,
++ init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++
++ /// 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->get_service().receive(
++ this->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->get_service().receive(
++ this->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->get_service().receive(
++ this->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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::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)
++ {
++ // 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;
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_receive(this->get_implementation(),
++ buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<ReadHandler,
++ void (boost::system::error_code, std::size_t, boost::asio::ip::address)> init(handler);
++
++ this->get_service().async_receive(this->get_implementation(),
++ buffers, 0, init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++
++ /// 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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::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)
++ {
++ // 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;
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_receive(this->get_implementation(),
++ buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<ReadHandler,
++ void (boost::system::error_code, std::size_t, boost::asio::ip::address)> init(handler);
++
++ this->get_service().async_receive(this->get_implementation(),
++ buffers, flags, init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++
++ /// 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->get_service().receive_from(
++ this->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->get_service().receive_from(
++ this->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->get_service().receive_from(this->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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::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)
++ {
++ // 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;
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_receive_from(
++ this->get_implementation(), buffers, sender_endpoint, 0,
++ BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<ReadHandler,
++ void (boost::system::error_code, std::size_t, boost::asio::ip::address)> init(handler);
++
++ this->get_service().async_receive_from(
++ this->get_implementation(), buffers, sender_endpoint, 0,
++ init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++
++ /// 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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::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)
++ {
++ // 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;
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_receive_from(
++ this->get_implementation(), buffers, sender_endpoint, flags,
++ BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<ReadHandler,
++ void (boost::system::error_code, std::size_t, boost::asio::ip::address)> init(handler);
++
++ this->get_service().async_receive_from(
++ this->get_implementation(), buffers, sender_endpoint, flags,
++ init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++};
++
++} // namespace asio
++} // namespace boost
++
++#include <boost/asio/detail/pop_options.hpp>
++
++#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP
+diff --git a/implementation/helper/1.66/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.66/boost/asio/basic_socket_ext.hpp
+new file mode 100644
+index 0000000..cdf4029
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/basic_socket_ext.hpp
+@@ -0,0 +1,1760 @@
++//
++// basic_socket_ext.hpp
++// ~~~~~~~~~~~~~~~~
++//
++// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
++// Copyright (C) 2018 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/basic_io_object.hpp>
++#include <boost/asio/detail/handler_type_requirements.hpp>
++#include <boost/asio/detail/throw_error.hpp>
++#include <boost/asio/detail/type_traits.hpp>
++#include <boost/asio/error.hpp>
++#include <boost/asio/post.hpp>
++#include <boost/asio/socket_base.hpp>
++
++#if defined(BOOST_ASIO_HAS_MOVE)
++# include <utility>
++#endif // defined(BOOST_ASIO_HAS_MOVE)
++
++#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
++# include <boost/asio/detail/winrt_ssocket_service.hpp>
++# define BOOST_ASIO_SVC_T detail::winrt_ssocket_service<Protocol>
++# elif defined(BOOST_ASIO_HAS_IOCP)
++# include <boost/asio/detail/win_iocp_socket_service.hpp>
++# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
++# else
++# include <boost/asio/detail/reactive_socket_service_ext.hpp>
++# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext<Protocol>
++# endif
++#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++
++#include <boost/asio/detail/push_options.hpp>
++
++namespace boost {
++namespace asio {
++
++/// 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 BOOST_ASIO_SVC_TPARAM>
++class basic_socket_ext
++ : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
++ public socket_base
++{
++public:
++ /// The type of the executor associated with the object.
++ typedef io_context::executor_type executor_type;
++
++ /// The native representation of a socket.
++#if defined(GENERATING_DOCUMENTATION)
++ typedef implementation_defined native_handle_type;
++#else
++ typedef typename BOOST_ASIO_SVC_T::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 BOOST_ASIO_SVC_TARG> 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 io_context The io_context object that the socket will use to
++ * dispatch handlers for any asynchronous operations performed on the socket.
++ */
++ explicit basic_socket_ext(boost::asio::io_context& io_context)
++ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
++ {
++ }
++
++ /// Construct and open a basic_socket.
++ /**
++ * This constructor creates and opens a socket.
++ *
++ * @param io_context The io_context object that the socket will use 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(boost::asio::io_context& io_context,
++ const protocol_type& protocol)
++ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
++ {
++ boost::system::error_code ec;
++ this->get_service().open(this->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 io_context The io_context object that the socket will use 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(boost::asio::io_context& io_context,
++ const endpoint_type& endpoint)
++ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
++ {
++ boost::system::error_code ec;
++ const protocol_type protocol = endpoint.protocol();
++ this->get_service().open(this->get_implementation(), protocol, ec);
++ boost::asio::detail::throw_error(ec, "open");
++ this->get_service().bind(this->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 io_context The io_context object that the socket will use 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(boost::asio::io_context& io_context,
++ const protocol_type& protocol, const native_handle_type& native_socket)
++ : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
++ {
++ boost::system::error_code ec;
++ this->get_service().assign(this->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(io_context&) constructor.
++ */
++ basic_socket_ext(basic_socket_ext&& other)
++ : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
++ {
++ }
++
++ /// 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(io_context&) constructor.
++ */
++ basic_socket_ext& operator=(basic_socket_ext&& other)
++ {
++ basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
++ return *this;
++ }
++
++ // All sockets have access to each other's implementations.
++ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
++ friend class basic_socket;
++
++ /// 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(io_context&) constructor.
++ */
++ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
++ basic_socket_ext(basic_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
++ typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
++ : basic_io_object<BOOST_ASIO_SVC_T>(
++ other.get_service(), other.get_implementation())
++ {
++ }
++
++ /// 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(io_context&) constructor.
++ */
++ template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
++ typename enable_if<is_convertible<Protocol1, Protocol>::value,
++ basic_socket_ext>::type& operator=(
++ basic_socket_ext<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
++ {
++ basic_socket_ext tmp(std::move(other));
++ basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(tmp));
++ return *this;
++ }
++#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ // These functions are provided by basic_io_object<>.
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++#if !defined(BOOST_ASIO_NO_DEPRECATED)
++ /// (Deprecated: Use get_executor().) Get the io_context associated with the
++ /// object.
++ /**
++ * This function may be used to obtain the io_context object that the I/O
++ * object uses to dispatch handlers for asynchronous operations.
++ *
++ * @return A reference to the io_context object that the I/O object will use
++ * to dispatch handlers. Ownership is not transferred to the caller.
++ */
++ boost::asio::io_context& get_io_context()
++ {
++ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
++ }
++
++ /// (Deprecated: Use get_executor().) Get the io_context associated with the
++ /// object.
++ /**
++ * This function may be used to obtain the io_context object that the I/O
++ * object uses to dispatch handlers for asynchronous operations.
++ *
++ * @return A reference to the io_context object that the I/O object will use
++ * to dispatch handlers. Ownership is not transferred to the caller.
++ */
++ boost::asio::io_context& get_io_service()
++ {
++ return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
++ }
++#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
++
++ /// Get the executor associated with the object.
++ executor_type get_executor() BOOST_ASIO_NOEXCEPT
++ {
++ return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
++ }
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++
++#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(io_context);
++ * socket.open(boost::asio::ip::tcp::v4());
++ * @endcode
++ */
++ void open(const protocol_type& protocol = protocol_type())
++ {
++ boost::system::error_code ec;
++ this->get_service().open(this->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(io_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)
++ {
++ this->get_service().open(this->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;
++ this->get_service().assign(this->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)
++ {
++ this->get_service().assign(this->get_implementation(),
++ protocol, native_socket, ec);
++ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
++ }
++
++ /// Determine whether the socket is open.
++ bool is_open() const
++ {
++ return this->get_service().is_open(this->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;
++ this->get_service().close(this->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(io_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)
++ {
++ this->get_service().close(this->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 = this->get_service().release(
++ this->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 this->get_service().release(this->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 this->get_service().native_handle(this->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;
++ this->get_service().cancel(this->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)
++ {
++ this->get_service().cancel(this->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 = this->get_service().at_mark(this->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 this->get_service().at_mark(this->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 = this->get_service().available(
++ this->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 this->get_service().available(this->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(io_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;
++ this->get_service().bind(this->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(io_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)
++ {
++ this->get_service().bind(this->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(io_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())
++ {
++ this->get_service().open(this->get_implementation(),
++ peer_endpoint.protocol(), ec);
++ boost::asio::detail::throw_error(ec, "connect");
++ }
++ this->get_service().connect(this->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(io_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())
++ {
++ this->get_service().open(this->get_implementation(),
++ peer_endpoint.protocol(), ec);
++ if (ec)
++ {
++ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
++ }
++ }
++
++ this->get_service().connect(this->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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::post().
++ *
++ * @par Example
++ * @code
++ * void connect_handler(const boost::system::error_code& error)
++ * {
++ * if (!error)
++ * {
++ * // Connect succeeded.
++ * }
++ * }
++ *
++ * ...
++ *
++ * boost::asio::ip::tcp::socket socket(io_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)
++ {
++ // 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 (!is_open())
++ {
++ boost::system::error_code ec;
++ const protocol_type protocol = peer_endpoint.protocol();
++ this->get_service().open(this->get_implementation(), protocol, ec);
++ if (ec)
++ {
++ async_completion<ConnectHandler,
++ void (boost::system::error_code)> init(handler);
++
++ boost::asio::post(this->get_executor(),
++ boost::asio::detail::bind_handler(
++ BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(
++ ConnectHandler, void (boost::system::error_code)))(
++ init.completion_handler), ec));
++
++ return init.result.get();
++ }
++ }
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_connect(this->get_implementation(),
++ peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<ConnectHandler,
++ void (boost::system::error_code)> init(handler);
++
++ this->get_service().async_connect(
++ this->get_implementation(), peer_endpoint, init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++
++ /// 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(io_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;
++ this->get_service().set_option(this->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(io_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)
++ {
++ this->get_service().set_option(this->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(io_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;
++ this->get_service().get_option(this->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(io_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
++ {
++ this->get_service().get_option(this->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(io_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;
++ this->get_service().io_control(this->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(io_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)
++ {
++ this->get_service().io_control(this->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 this->get_service().non_blocking(this->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;
++ this->get_service().non_blocking(this->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)
++ {
++ this->get_service().non_blocking(this->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 this->get_service().native_non_blocking(this->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;
++ this->get_service().native_non_blocking(
++ this->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)
++ {
++ this->get_service().native_non_blocking(
++ this->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(io_context);
++ * ...
++ * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
++ * @endcode
++ */
++ endpoint_type local_endpoint() const
++ {
++ boost::system::error_code ec;
++ endpoint_type ep = this->get_service().local_endpoint(
++ this->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(io_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 this->get_service().local_endpoint(this->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(io_context);
++ * ...
++ * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
++ * @endcode
++ */
++ endpoint_type remote_endpoint() const
++ {
++ boost::system::error_code ec;
++ endpoint_type ep = this->get_service().remote_endpoint(
++ this->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(io_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 this->get_service().remote_endpoint(this->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(io_context);
++ * ...
++ * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
++ * @endcode
++ */
++ void shutdown(shutdown_type what)
++ {
++ boost::system::error_code ec;
++ this->get_service().shutdown(this->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(io_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)
++ {
++ this->get_service().shutdown(this->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(io_context);
++ * ...
++ * socket.wait(boost::asio::ip::tcp::socket::wait_read);
++ * @endcode
++ */
++ void wait(wait_type w)
++ {
++ boost::system::error_code ec;
++ this->get_service().wait(this->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(io_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)
++ {
++ this->get_service().wait(this->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. Invocation
++ * of the handler will be performed in a manner equivalent to using
++ * boost::asio::io_context::post().
++ *
++ * @par Example
++ * @code
++ * void wait_handler(const boost::system::error_code& error)
++ * {
++ * if (!error)
++ * {
++ * // Wait succeeded.
++ * }
++ * }
++ *
++ * ...
++ *
++ * boost::asio::ip::tcp::socket socket(io_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)
++ {
++ // 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;
++
++#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ return this->get_service().async_wait(this->get_implementation(),
++ w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
++#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ async_completion<WaitHandler,
++ void (boost::system::error_code)> init(handler);
++
++ this->get_service().async_wait(this->get_implementation(),
++ w, init.completion_handler);
++
++ return init.result.get();
++#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++ }
++
++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()
++ {
++ }
++
++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;
++};
++
++} // namespace asio
++} // namespace boost
++
++#include <boost/asio/detail/pop_options.hpp>
++
++#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++# undef BOOST_ASIO_SVC_T
++#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
++
++#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP
+diff --git a/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp
+new file mode 100644
+index 0000000..bc09b18
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp
+@@ -0,0 +1,565 @@
++//
++// detail/handler_type_requirements_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_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>
++
++#include <boost/asio/detail/push_options.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_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_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_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) \
++ 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
++
++#include <boost/asio/detail/pop_options.hpp>
++
++#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP
+diff --git a/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp
+new file mode 100644
+index 0000000..8cd2b1b
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp
+@@ -0,0 +1,302 @@
++//
++// detail/reactive_socket_service_base_ext.ipp
++// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++//
++// 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_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(
++ boost::asio::io_context& io_context)
++ : io_context_(io_context), reactor_(use_service<reactor>(io_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.66/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp
+new file mode 100644
+index 0000000..504cac1
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp
+@@ -0,0 +1,210 @@
++//
++// detail/impl/socket_ops_ext.ipp
++// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++//
++// 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_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)
++{
++ clear_last_error();
++#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
++ GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
++ LPFN_WSARECVMSG WSARecvMsg;
++ DWORD NumberOfBytes;
++
++ error_wrapper(WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
++ &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
++ &WSARecvMsg, sizeof WSARecvMsg,
++ &NumberOfBytes, NULL, NULL), ec);
++ 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;
++ signed_size_type result = error_wrapper(WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL), ec);
++
++ 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)
++ continue;
++
++ 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 {
++ 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 = error_wrapper(::recvmsg(s, &msg, flags), ec);
++ *addrlen = msg.msg_namelen;
++ if (result >= 0) {
++ ec = boost::system::error_code();
++
++ // 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)
++ continue;
++
++ struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg);
++ if (pi)
++ {
++ da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr));
++ }
++ }
++ }
++ 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.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp
+new file mode 100644
+index 0000000..080e8dd
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp
+@@ -0,0 +1,138 @@
++//
++// detail/reactive_socket_recv_op_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_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/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(socket_type socket,
++ socket_ops::state_type state, const MutableBufferSequence& buffers,
++ socket_base::message_flags flags, func_type complete_func)
++ : reactor_op_ext(&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));
++
++ buffer_sequence_adapter<boost::asio::mutable_buffer,
++ MutableBufferSequence> bufs(o->buffers_);
++
++ status 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>
++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(socket_type socket,
++ socket_ops::state_type state, const MutableBufferSequence& buffers,
++ socket_base::message_flags flags, Handler& handler)
++ : reactive_socket_recv_op_base_ext<MutableBufferSequence>(socket, state,
++ buffers, flags, &reactive_socket_recv_op_ext::do_complete),
++ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
++ {
++ handler_work<Handler>::start(handler_);
++ }
++
++ 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 };
++ handler_work<Handler> w(o->handler_);
++
++ BOOST_ASIO_HANDLER_COMPLETION((*o));
++
++ // 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_;
++};
++
++} // 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.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp
+new file mode 100644
+index 0000000..e726b60
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp
+@@ -0,0 +1,141 @@
++//
++// detail/reactive_socket_recvfrom_op_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_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/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(socket_type socket, int protocol_type,
++ const MutableBufferSequence& buffers, Endpoint& endpoint,
++ socket_base::message_flags flags, func_type complete_func)
++ : reactor_op_ext(&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>
++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(socket_type socket, int protocol_type,
++ const MutableBufferSequence& buffers, Endpoint& endpoint,
++ socket_base::message_flags flags, Handler& handler)
++ : reactive_socket_recvfrom_op_base_ext<MutableBufferSequence, Endpoint>(
++ socket, protocol_type, buffers, endpoint, flags,
++ &reactive_socket_recvfrom_op_ext::do_complete),
++ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
++ {
++ handler_work<Handler>::start(handler_);
++ }
++
++ 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 };
++ handler_work<Handler> w(o->handler_);
++
++ BOOST_ASIO_HANDLER_COMPLETION((*o));
++
++ // 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_;
++};
++
++} // 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.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp
+new file mode 100644
+index 0000000..f88ea58
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp
+@@ -0,0 +1,135 @@
++//
++// detail/reactive_socket_recvmsg_op_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_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/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(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>
++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(socket_type socket,
++ const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
++ socket_base::message_flags& out_flags, Handler& handler)
++ : 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))
++ {
++ handler_work<Handler>::start(handler_);
++ }
++
++ 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 };
++ handler_work<Handler> w(o->handler_);
++
++ BOOST_ASIO_HANDLER_COMPLETION((*o));
++
++ // 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_;
++};
++
++} // 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.66/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp
+new file mode 100644
+index 0000000..ea99fbf
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp
+@@ -0,0 +1,517 @@
++//
++// detail/reactive_socket_service_base_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_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 <iostream>
++
++#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/io_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(
++ boost::asio::io_context& io_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>
++ void async_wait(base_implementation_type& impl,
++ socket_base::wait_type w, Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(handler);
++
++ 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>
++ void async_send(base_implementation_type& impl,
++ const ConstBufferSequence& buffers,
++ socket_base::message_flags flags, Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler);
++
++ 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>
++ void async_send(base_implementation_type& impl, const null_buffers&,
++ socket_base::message_flags, Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(handler);
++
++ 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>
++ void async_receive(base_implementation_type& impl,
++ const MutableBufferSequence& buffers,
++ socket_base::message_flags flags, Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler);
++
++ 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>
++ void async_receive(base_implementation_type& impl, const null_buffers&,
++ socket_base::message_flags flags, Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(handler);
++
++ 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>
++ 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)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler);
++
++ 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>
++ 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)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ boost_asio_handler_alloc_helpers::allocate(
++ sizeof(op), handler), 0 };
++ p.p = new (p.v) op(handler);
++
++ BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl,
++ "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 io_context that owns this socket service
++ io_context& io_context_;
++
++ // The selector that performs event demultiplexing for the service.
++ reactor& reactor_;
++};
++
++} // 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.66/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp
+new file mode 100644
+index 0000000..8f75eb1
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp
+@@ -0,0 +1,531 @@
++//
++// detail/reactive_socket_service_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_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 <iostream>
++
++#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/io_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 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(boost::asio::io_context& io_context)
++ : service_base<reactive_socket_service_ext<Protocol> >(io_context),
++ reactive_socket_service_base_ext(io_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<Protocol>&,
++ 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>
++ void async_send_to(implementation_type& impl,
++ const ConstBufferSequence& buffers,
++ const endpoint_type& destination, socket_base::message_flags flags,
++ Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler);
++
++ 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>
++ void async_send_to(implementation_type& impl, const null_buffers&,
++ const endpoint_type&, socket_base::message_flags, Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(handler);
++
++ 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>
++ void async_receive_from(implementation_type& impl,
++ const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
++ socket_base::message_flags flags, Handler& handler)
++ {
++ 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> 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(impl.socket_, protocol,
++ buffers, sender_endpoint, flags, handler);
++
++ 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>
++ void async_receive_from(implementation_type& impl,
++ const null_buffers&, endpoint_type& sender_endpoint,
++ socket_base::message_flags flags, Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(handler);
++
++ 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;
++ }
++
++#if defined(BOOST_ASIO_HAS_MOVE)
++ // Accept a new connection.
++ typename Protocol::socket accept(implementation_type& impl,
++ io_context* peer_io_context, endpoint_type* peer_endpoint,
++ boost::system::error_code& ec)
++ {
++ typename Protocol::socket peer(
++ peer_io_context ? *peer_io_context : io_context_);
++
++ 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 peer;
++ }
++ #endif // defined(BOOST_ASIO_HAS_MOVE)
++
++ // 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>
++ void async_accept(implementation_type& impl, Socket& peer,
++ endpoint_type* peer_endpoint, Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(impl.socket_, impl.state_, peer,
++ impl.protocol_, peer_endpoint, handler);
++
++ 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 Handler>
++ void async_accept(implementation_type& impl,
++ boost::asio::io_context* peer_io_context,
++ endpoint_type* peer_endpoint, Handler& handler)
++ {
++ 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, Handler> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(peer_io_context ? *peer_io_context : io_context_,
++ impl.socket_, impl.state_, impl.protocol_, peer_endpoint, handler);
++
++ 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>
++ void async_connect(implementation_type& impl,
++ const endpoint_type& peer_endpoint, Handler& handler)
++ {
++ 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> op;
++ typename op::ptr p = { boost::asio::detail::addressof(handler),
++ op::ptr::allocate(handler), 0 };
++ p.p = new (p.v) op(impl.socket_, handler);
++
++ 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.66/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp
+new file mode 100644
+index 0000000..55ac6a4
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp
+@@ -0,0 +1,42 @@
++//
++// detail/reactor_op_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_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(perform_func_type perform_func, func_type complete_func)
++ : reactor_op(perform_func, complete_func)
++ {
++ }
++};
++
++} // namespace detail
++} // namespace asio
++} // namespace boost
++
++#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP
+diff --git a/implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp
+new file mode 100644
+index 0000000..aa31a0f
+--- /dev/null
++++ b/implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp
+@@ -0,0 +1,62 @@
++//
++// detail/socket_ops_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_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.66/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.66/boost/asio/ip/udp_ext.hpp
+new file mode 100644
+index 0000000..e930f86
+--- /dev/null
++++ b/implementation/helper/1.66/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
+--
+2.18.0
+
diff --git a/meta-ivi/recipes-core-ivi/vsomeip/vsomeip_2.10.10.bb b/meta-ivi/recipes-core-ivi/vsomeip/vsomeip_2.10.21.bb
index 5bcb8d0..938bf6b 100644
--- a/meta-ivi/recipes-core-ivi/vsomeip/vsomeip_2.10.10.bb
+++ b/meta-ivi/recipes-core-ivi/vsomeip/vsomeip_2.10.21.bb
@@ -6,8 +6,9 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=815ca599c9df247a0c7f619bab123dad"
DEPENDS = "boost dlt-daemon"
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
-SRCREV = "4808f3130c97cea3f0168005b9df029282060539"
+SRCREV = "9fb9beecadf52083599302fa8ddee7efbec64a39"
SRC_URI = "git://github.com/GENIVI/${BPN}.git;protocol=https \
+ file://0001-Support-boost-v1.66.patch \
"
S = "${WORKDIR}/git"