aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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"