diff options
-rw-r--r-- | meta-ivi/recipes-core-ivi/vsomeip/vsomeip/0001-Support-boost-v1.66.patch | 6085 | ||||
-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" |