You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by li...@apache.org on 2022/07/28 00:32:06 UTC

[rocketmq-clients] branch master updated: Support build with CMake (#77)

This is an automated email from the ASF dual-hosted git repository.

lizhanhui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git


The following commit(s) were added to refs/heads/master by this push:
     new 15e2844  Support build with CMake (#77)
15e2844 is described below

commit 15e284459d061b19cf44115f050b1997ca646d50
Author: Zhanhui Li <li...@gmail.com>
AuthorDate: Thu Jul 28 08:32:02 2022 +0800

    Support build with CMake (#77)
    
    * Include generated grpc files
    
    * WIP: support build and release with CMake
    
    * WIP: support build with cmake
    
    * WIP: support build with cmake
    
    * WIP: build stats with cmake
    
    * WIP
    
    * WIP: Support build with cmake
    
    * Support build with cmake
    
    * Ignore license header checker of third party libraries
    
    * Build project targets only
    
    * Exclude cpp/cmake from license checking
---
 .github/workflows/cpp_build.yml                    |    4 +-
 .licenserc.yaml                                    |    2 +
 cpp/CMakeLists.txt                                 |   33 +
 cpp/bazel/rocketmq_deps.bzl                        |   15 +-
 cpp/cmake/FindProtobufWithTargets.cmake            |  203 +
 cpp/cmake/FindgRPC.cmake                           |  357 ++
 cpp/cmake/OpenCensusHelpers.cmake                  |   90 +
 cpp/examples/CMakeLists.txt                        |    6 +
 cpp/proto/CMakeLists.txt                           |   19 +
 cpp/source/CMakeLists.txt                          |   31 +
 cpp/source/admin/CMakeLists.txt                    |   13 +
 cpp/source/base/CMakeLists.txt                     |   15 +
 cpp/source/base/MixAll.cpp                         |    3 +-
 cpp/source/base/UniqueIdGenerator.cpp              |    7 +-
 cpp/source/base/UtilAll.cpp                        |    3 +-
 cpp/source/base/include/InvocationContext.h        |    3 +-
 cpp/source/client/CMakeLists.txt                   |   18 +
 cpp/source/client/ClientManagerImpl.cpp            |    6 +-
 cpp/source/client/ReceiveMessageStreamReader.cpp   |    5 +-
 cpp/source/client/SessionImpl.cpp                  |    3 +-
 cpp/source/client/TelemetryBidiReactor.cpp         |    3 +-
 cpp/source/client/TopicAssignmentInfo.cpp          |    3 +-
 cpp/source/client/include/TopicAssignmentInfo.h    |    2 +-
 cpp/source/concurrent/CMakeLists.txt               |    9 +
 cpp/source/concurrent/CountdownLatch.cpp           |    4 +-
 cpp/source/log/CMakeLists.txt                      |   11 +
 cpp/source/remoting/BUILD.bazel                    |   32 -
 cpp/source/remoting/BrokerData.cpp                 |   43 -
 cpp/source/remoting/QueryRouteRequestHeader.cpp    |   29 -
 cpp/source/remoting/QueueData.cpp                  |   49 -
 cpp/source/remoting/RemotingCommand.cpp            |  113 -
 cpp/source/remoting/TopicRouteData.cpp             |   46 -
 cpp/source/remoting/include/BrokerData.h           |   38 -
 cpp/source/remoting/include/CommandCustomHeader.h  |   33 -
 cpp/source/remoting/include/LanguageCode.h         |   41 -
 .../remoting/include/QueryRouteRequestHeader.h     |   46 -
 cpp/source/remoting/include/QueueData.h            |   44 -
 cpp/source/remoting/include/RemotingCommand.h      |  106 -
 cpp/source/remoting/include/RemotingCommandType.h  |   31 -
 cpp/source/remoting/include/RequestCode.h          |   32 -
 cpp/source/remoting/include/ResponseCode.h         |   32 -
 cpp/source/remoting/include/TopicRouteData.h       |   44 -
 cpp/source/remoting/include/Version.h              |   31 -
 .../rocketmq/AsyncReceiveMessageCallback.cpp       |    3 +-
 cpp/source/rocketmq/CMakeLists.txt                 |   22 +
 cpp/source/rocketmq/ClientImpl.cpp                 |    3 +-
 cpp/source/rocketmq/ConsumeMessageServiceImpl.cpp  |    3 +-
 cpp/source/rocketmq/ConsumeTask.cpp                |    3 +-
 cpp/source/rocketmq/Producer.cpp                   |    3 +-
 cpp/source/rocketmq/StaticNameServerResolver.cpp   |    3 +-
 cpp/source/rocketmq/TopicPublishInfo.cpp           |    3 +-
 cpp/source/rocketmq/include/ProcessQueueImpl.h     |    3 -
 cpp/source/scheduler/CMakeLists.txt                |   10 +
 cpp/source/stats/CMakeLists.txt                    |   17 +
 cpp/source/stats/MetricBidiReactor.cpp             |    3 +-
 cpp/source/stats/StdoutHandler.cpp                 |    4 +-
 cpp/source/trace/CMakeLists.txt                    |   13 +
 cpp/third_party/CMakeLists.txt                     |    8 +
 cpp/third_party/asio/1.18.2/CMakeLists.txt         |    4 +
 cpp/third_party/asio/1.18.2/include/Makefile.am    |  566 ++
 cpp/third_party/asio/1.18.2/include/Makefile.in    | 1105 ++++
 cpp/third_party/asio/1.18.2/include/asio.hpp       |  182 +
 .../asio/1.18.2/include/asio/any_io_executor.hpp   |  300 +
 .../1.18.2/include/asio/associated_allocator.hpp   |  125 +
 .../1.18.2/include/asio/associated_executor.hpp    |  166 +
 .../asio/1.18.2/include/asio/async_result.hpp      |  582 ++
 .../asio/1.18.2/include/asio/awaitable.hpp         |  133 +
 .../1.18.2/include/asio/basic_datagram_socket.hpp  | 1223 ++++
 .../1.18.2/include/asio/basic_deadline_timer.hpp   |  693 +++
 .../asio/1.18.2/include/asio/basic_io_object.hpp   |  290 +
 .../asio/1.18.2/include/asio/basic_raw_socket.hpp  | 1214 ++++
 .../include/asio/basic_seq_packet_socket.hpp       |  768 +++
 .../asio/1.18.2/include/asio/basic_serial_port.hpp |  907 +++
 .../asio/1.18.2/include/asio/basic_signal_set.hpp  |  576 ++
 .../asio/1.18.2/include/asio/basic_socket.hpp      | 1895 ++++++
 .../1.18.2/include/asio/basic_socket_acceptor.hpp  | 2508 ++++++++
 .../1.18.2/include/asio/basic_socket_iostream.hpp  |  407 ++
 .../1.18.2/include/asio/basic_socket_streambuf.hpp |  687 +++
 .../1.18.2/include/asio/basic_stream_socket.hpp    | 1060 ++++
 .../asio/1.18.2/include/asio/basic_streambuf.hpp   |  452 ++
 .../1.18.2/include/asio/basic_streambuf_fwd.hpp    |   36 +
 .../1.18.2/include/asio/basic_waitable_timer.hpp   |  811 +++
 .../asio/1.18.2/include/asio/bind_executor.hpp     |  575 ++
 .../asio/1.18.2/include/asio/buffer.hpp            | 2496 ++++++++
 .../1.18.2/include/asio/buffered_read_stream.hpp   |  253 +
 .../include/asio/buffered_read_stream_fwd.hpp      |   25 +
 .../asio/1.18.2/include/asio/buffered_stream.hpp   |  279 +
 .../1.18.2/include/asio/buffered_stream_fwd.hpp    |   25 +
 .../1.18.2/include/asio/buffered_write_stream.hpp  |  245 +
 .../include/asio/buffered_write_stream_fwd.hpp     |   25 +
 .../asio/1.18.2/include/asio/buffers_iterator.hpp  |  521 ++
 .../asio/1.18.2/include/asio/co_spawn.hpp          |  471 ++
 .../1.18.2/include/asio/completion_condition.hpp   |  218 +
 .../asio/1.18.2/include/asio/compose.hpp           |  136 +
 .../asio/1.18.2/include/asio/connect.hpp           | 1076 ++++
 .../asio/1.18.2/include/asio/coroutine.hpp         |  328 ++
 .../asio/1.18.2/include/asio/deadline_timer.hpp    |   38 +
 cpp/third_party/asio/1.18.2/include/asio/defer.hpp |  130 +
 .../asio/1.18.2/include/asio/detached.hpp          |  112 +
 .../asio/1.18.2/include/asio/detail/array.hpp      |   38 +
 .../asio/1.18.2/include/asio/detail/array_fwd.hpp  |   34 +
 .../asio/1.18.2/include/asio/detail/assert.hpp     |   32 +
 .../1.18.2/include/asio/detail/atomic_count.hpp    |   64 +
 .../asio/detail/base_from_completion_cond.hpp      |   69 +
 .../1.18.2/include/asio/detail/bind_handler.hpp    |  938 +++
 .../include/asio/detail/blocking_executor_op.hpp   |  107 +
 .../include/asio/detail/buffer_resize_guard.hpp    |   66 +
 .../asio/detail/buffer_sequence_adapter.hpp        |  650 +++
 .../asio/detail/buffered_stream_storage.hpp        |  126 +
 .../include/asio/detail/bulk_executor_op.hpp       |   88 +
 .../asio/1.18.2/include/asio/detail/call_stack.hpp |  125 +
 .../asio/1.18.2/include/asio/detail/chrono.hpp     |   66 +
 .../include/asio/detail/chrono_time_traits.hpp     |  190 +
 .../include/asio/detail/completion_handler.hpp     |   88 +
 .../include/asio/detail/concurrency_hint.hpp       |   94 +
 .../asio/detail/conditionally_enabled_event.hpp    |  120 +
 .../asio/detail/conditionally_enabled_mutex.hpp    |  149 +
 .../asio/1.18.2/include/asio/detail/config.hpp     | 1865 ++++++
 .../include/asio/detail/consuming_buffers.hpp      |  414 ++
 .../asio/1.18.2/include/asio/detail/cstddef.hpp    |   31 +
 .../asio/1.18.2/include/asio/detail/cstdint.hpp    |   60 +
 .../1.18.2/include/asio/detail/date_time_fwd.hpp   |   34 +
 .../include/asio/detail/deadline_timer_service.hpp |  295 +
 .../1.18.2/include/asio/detail/dependent_type.hpp  |   36 +
 .../1.18.2/include/asio/detail/descriptor_ops.hpp  |  139 +
 .../include/asio/detail/descriptor_read_op.hpp     |  148 +
 .../include/asio/detail/descriptor_write_op.hpp    |  148 +
 .../include/asio/detail/dev_poll_reactor.hpp       |  218 +
 .../1.18.2/include/asio/detail/epoll_reactor.hpp   |  266 +
 .../asio/1.18.2/include/asio/detail/event.hpp      |   48 +
 .../asio/detail/eventfd_select_interrupter.hpp     |   83 +
 .../include/asio/detail/executor_function.hpp      |  204 +
 .../1.18.2/include/asio/detail/executor_op.hpp     |   84 +
 .../1.18.2/include/asio/detail/fd_set_adapter.hpp  |   39 +
 .../1.18.2/include/asio/detail/fenced_block.hpp    |   80 +
 .../asio/1.18.2/include/asio/detail/functional.hpp |   38 +
 .../asio/1.18.2/include/asio/detail/future.hpp     |   33 +
 .../include/asio/detail/gcc_arm_fenced_block.hpp   |   91 +
 .../include/asio/detail/gcc_hppa_fenced_block.hpp  |   68 +
 .../include/asio/detail/gcc_sync_fenced_block.hpp  |   65 +
 .../include/asio/detail/gcc_x86_fenced_block.hpp   |   99 +
 .../asio/1.18.2/include/asio/detail/global.hpp     |   52 +
 .../include/asio/detail/handler_alloc_helpers.hpp  |  284 +
 .../include/asio/detail/handler_cont_helpers.hpp   |   45 +
 .../include/asio/detail/handler_invoke_helpers.hpp |   80 +
 .../include/asio/detail/handler_tracking.hpp       |  264 +
 .../asio/detail/handler_type_requirements.hpp      |  556 ++
 .../1.18.2/include/asio/detail/handler_work.hpp    |  514 ++
 .../asio/1.18.2/include/asio/detail/hash_map.hpp   |  331 ++
 .../asio/detail/impl/buffer_sequence_adapter.ipp   |  118 +
 .../include/asio/detail/impl/descriptor_ops.ipp    |  608 ++
 .../include/asio/detail/impl/dev_poll_reactor.hpp  |   91 +
 .../include/asio/detail/impl/dev_poll_reactor.ipp  |  446 ++
 .../include/asio/detail/impl/epoll_reactor.hpp     |   89 +
 .../include/asio/detail/impl/epoll_reactor.ipp     |  787 +++
 .../detail/impl/eventfd_select_interrupter.ipp     |  171 +
 .../include/asio/detail/impl/handler_tracking.ipp  |  396 ++
 .../include/asio/detail/impl/kqueue_reactor.hpp    |   93 +
 .../include/asio/detail/impl/kqueue_reactor.ipp    |  570 ++
 .../1.18.2/include/asio/detail/impl/null_event.ipp |   74 +
 .../asio/detail/impl/pipe_select_interrupter.ipp   |  129 +
 .../include/asio/detail/impl/posix_event.ipp       |   63 +
 .../include/asio/detail/impl/posix_mutex.ipp       |   46 +
 .../include/asio/detail/impl/posix_thread.ipp      |   84 +
 .../include/asio/detail/impl/posix_tss_ptr.ipp     |   46 +
 .../detail/impl/reactive_descriptor_service.ipp    |  223 +
 .../detail/impl/reactive_serial_port_service.ipp   |  149 +
 .../detail/impl/reactive_socket_service_base.ipp   |  300 +
 .../asio/detail/impl/resolver_service_base.ipp     |  158 +
 .../1.18.2/include/asio/detail/impl/scheduler.ipp  |  659 +++
 .../include/asio/detail/impl/select_reactor.hpp    |  100 +
 .../include/asio/detail/impl/select_reactor.ipp    |  338 ++
 .../include/asio/detail/impl/service_registry.hpp  |   94 +
 .../include/asio/detail/impl/service_registry.ipp  |  197 +
 .../asio/detail/impl/signal_set_service.ipp        |  668 +++
 .../1.18.2/include/asio/detail/impl/socket_ops.ipp | 3964 +++++++++++++
 .../asio/detail/impl/socket_select_interrupter.ipp |  185 +
 .../asio/detail/impl/strand_executor_service.hpp   |  352 ++
 .../asio/detail/impl/strand_executor_service.ipp   |  158 +
 .../include/asio/detail/impl/strand_service.hpp    |   87 +
 .../include/asio/detail/impl/strand_service.ipp    |  202 +
 .../include/asio/detail/impl/thread_context.ipp    |   35 +
 .../include/asio/detail/impl/throw_error.ipp       |   60 +
 .../include/asio/detail/impl/timer_queue_ptime.ipp |   91 +
 .../include/asio/detail/impl/timer_queue_set.ipp   |  101 +
 .../1.18.2/include/asio/detail/impl/win_event.ipp  |   76 +
 .../asio/detail/impl/win_iocp_handle_service.ipp   |  525 ++
 .../asio/detail/impl/win_iocp_io_context.hpp       |  104 +
 .../asio/detail/impl/win_iocp_io_context.ipp       |  608 ++
 .../detail/impl/win_iocp_serial_port_service.ipp   |  192 +
 .../detail/impl/win_iocp_socket_service_base.ipp   |  801 +++
 .../1.18.2/include/asio/detail/impl/win_mutex.ipp  |   84 +
 .../asio/detail/impl/win_object_handle_service.ipp |  448 ++
 .../include/asio/detail/impl/win_static_mutex.ipp  |  136 +
 .../1.18.2/include/asio/detail/impl/win_thread.ipp |  150 +
 .../include/asio/detail/impl/win_tss_ptr.ipp       |   57 +
 .../detail/impl/winrt_ssocket_service_base.ipp     |  626 ++
 .../asio/detail/impl/winrt_timer_scheduler.hpp     |   92 +
 .../asio/detail/impl/winrt_timer_scheduler.ipp     |  121 +
 .../include/asio/detail/impl/winsock_init.ipp      |   82 +
 .../asio/1.18.2/include/asio/detail/io_control.hpp |   84 +
 .../1.18.2/include/asio/detail/io_object_impl.hpp  |  172 +
 .../include/asio/detail/is_buffer_sequence.hpp     |  312 +
 .../1.18.2/include/asio/detail/is_executor.hpp     |  126 +
 .../1.18.2/include/asio/detail/keyword_tss_ptr.hpp |   70 +
 .../1.18.2/include/asio/detail/kqueue_reactor.hpp  |  242 +
 .../asio/1.18.2/include/asio/detail/limits.hpp     |   26 +
 .../asio/detail/local_free_on_block_exit.hpp       |   59 +
 .../include/asio/detail/macos_fenced_block.hpp     |   62 +
 .../asio/1.18.2/include/asio/detail/memory.hpp     |   73 +
 .../asio/1.18.2/include/asio/detail/mutex.hpp      |   48 +
 .../include/asio/detail/non_const_lvalue.hpp       |   54 +
 .../1.18.2/include/asio/detail/noncopyable.hpp     |   43 +
 .../asio/1.18.2/include/asio/detail/null_event.hpp |  106 +
 .../include/asio/detail/null_fenced_block.hpp      |   47 +
 .../1.18.2/include/asio/detail/null_global.hpp     |   59 +
 .../asio/1.18.2/include/asio/detail/null_mutex.hpp |   64 +
 .../1.18.2/include/asio/detail/null_reactor.hpp    |   68 +
 .../include/asio/detail/null_signal_blocker.hpp    |   69 +
 .../include/asio/detail/null_socket_service.hpp    |  519 ++
 .../include/asio/detail/null_static_mutex.hpp      |   60 +
 .../1.18.2/include/asio/detail/null_thread.hpp     |   67 +
 .../1.18.2/include/asio/detail/null_tss_ptr.hpp    |   68 +
 .../1.18.2/include/asio/detail/object_pool.hpp     |  171 +
 .../include/asio/detail/old_win_sdk_compat.hpp     |  214 +
 .../asio/1.18.2/include/asio/detail/op_queue.hpp   |  162 +
 .../asio/1.18.2/include/asio/detail/operation.hpp  |   38 +
 .../asio/detail/pipe_select_interrupter.hpp        |   89 +
 .../1.18.2/include/asio/detail/pop_options.hpp     |  141 +
 .../1.18.2/include/asio/detail/posix_event.hpp     |  175 +
 .../include/asio/detail/posix_fd_set_adapter.hpp   |  118 +
 .../1.18.2/include/asio/detail/posix_global.hpp    |   80 +
 .../1.18.2/include/asio/detail/posix_mutex.hpp     |   76 +
 .../include/asio/detail/posix_signal_blocker.hpp   |   85 +
 .../include/asio/detail/posix_static_mutex.hpp     |   64 +
 .../1.18.2/include/asio/detail/posix_thread.hpp    |  109 +
 .../1.18.2/include/asio/detail/posix_tss_ptr.hpp   |   79 +
 .../1.18.2/include/asio/detail/push_options.hpp    |  191 +
 .../asio/detail/reactive_descriptor_service.hpp    |  416 ++
 .../asio/detail/reactive_null_buffers_op.hpp       |   98 +
 .../asio/detail/reactive_serial_port_service.hpp   |  237 +
 .../asio/detail/reactive_socket_accept_op.hpp      |  242 +
 .../asio/detail/reactive_socket_connect_op.hpp     |  123 +
 .../asio/detail/reactive_socket_recv_op.hpp        |  159 +
 .../asio/detail/reactive_socket_recvfrom_op.hpp    |  164 +
 .../asio/detail/reactive_socket_recvmsg_op.hpp     |  145 +
 .../asio/detail/reactive_socket_send_op.hpp        |  162 +
 .../asio/detail/reactive_socket_sendto_op.hpp      |  156 +
 .../asio/detail/reactive_socket_service.hpp        |  528 ++
 .../asio/detail/reactive_socket_service_base.hpp   |  541 ++
 .../include/asio/detail/reactive_wait_op.hpp       |   98 +
 .../asio/1.18.2/include/asio/detail/reactor.hpp    |   32 +
 .../1.18.2/include/asio/detail/reactor_fwd.hpp     |   40 +
 .../asio/1.18.2/include/asio/detail/reactor_op.hpp |   67 +
 .../include/asio/detail/reactor_op_queue.hpp       |  168 +
 .../include/asio/detail/recycling_allocator.hpp    |  104 +
 .../asio/1.18.2/include/asio/detail/regex_fwd.hpp  |   44 +
 .../include/asio/detail/resolve_endpoint_op.hpp    |  140 +
 .../asio/1.18.2/include/asio/detail/resolve_op.hpp |   45 +
 .../include/asio/detail/resolve_query_op.hpp       |  150 +
 .../include/asio/detail/resolver_service.hpp       |  145 +
 .../include/asio/detail/resolver_service_base.hpp  |  158 +
 .../asio/1.18.2/include/asio/detail/scheduler.hpp  |  229 +
 .../include/asio/detail/scheduler_operation.hpp    |   78 +
 .../include/asio/detail/scheduler_thread_info.hpp  |   40 +
 .../1.18.2/include/asio/detail/scoped_lock.hpp     |  101 +
 .../asio/1.18.2/include/asio/detail/scoped_ptr.hpp |   87 +
 .../include/asio/detail/select_interrupter.hpp     |   46 +
 .../1.18.2/include/asio/detail/select_reactor.hpp  |  238 +
 .../include/asio/detail/service_registry.hpp       |  164 +
 .../1.18.2/include/asio/detail/signal_blocker.hpp  |   44 +
 .../1.18.2/include/asio/detail/signal_handler.hpp  |   90 +
 .../1.18.2/include/asio/detail/signal_init.hpp     |   47 +
 .../asio/1.18.2/include/asio/detail/signal_op.hpp  |   49 +
 .../include/asio/detail/signal_set_service.hpp     |  229 +
 .../1.18.2/include/asio/detail/socket_holder.hpp   |   98 +
 .../asio/1.18.2/include/asio/detail/socket_ops.hpp |  383 ++
 .../1.18.2/include/asio/detail/socket_option.hpp   |  316 +
 .../asio/detail/socket_select_interrupter.hpp      |   91 +
 .../1.18.2/include/asio/detail/socket_types.hpp    |  417 ++
 .../include/asio/detail/solaris_fenced_block.hpp   |   62 +
 .../1.18.2/include/asio/detail/source_location.hpp |   45 +
 .../1.18.2/include/asio/detail/static_mutex.hpp    |   52 +
 .../asio/1.18.2/include/asio/detail/std_event.hpp  |  188 +
 .../include/asio/detail/std_fenced_block.hpp       |   62 +
 .../asio/1.18.2/include/asio/detail/std_global.hpp |   70 +
 .../asio/1.18.2/include/asio/detail/std_mutex.hpp  |   73 +
 .../include/asio/detail/std_static_mutex.hpp       |   81 +
 .../asio/1.18.2/include/asio/detail/std_thread.hpp |   71 +
 .../asio/detail/strand_executor_service.hpp        |  173 +
 .../1.18.2/include/asio/detail/strand_service.hpp  |  144 +
 .../1.18.2/include/asio/detail/string_view.hpp     |   47 +
 .../asio/1.18.2/include/asio/detail/thread.hpp     |   60 +
 .../1.18.2/include/asio/detail/thread_context.hpp  |   51 +
 .../1.18.2/include/asio/detail/thread_group.hpp    |   99 +
 .../include/asio/detail/thread_info_base.hpp       |  190 +
 .../1.18.2/include/asio/detail/throw_error.hpp     |   53 +
 .../1.18.2/include/asio/detail/throw_exception.hpp |   51 +
 .../1.18.2/include/asio/detail/timer_queue.hpp     |  360 ++
 .../include/asio/detail/timer_queue_base.hpp       |   68 +
 .../include/asio/detail/timer_queue_ptime.hpp      |   99 +
 .../1.18.2/include/asio/detail/timer_queue_set.hpp |   66 +
 .../1.18.2/include/asio/detail/timer_scheduler.hpp |   35 +
 .../include/asio/detail/timer_scheduler_fwd.hpp    |   40 +
 .../asio/1.18.2/include/asio/detail/tss_ptr.hpp    |   69 +
 .../1.18.2/include/asio/detail/type_traits.hpp     |  156 +
 .../include/asio/detail/variadic_templates.hpp     |  294 +
 .../1.18.2/include/asio/detail/wait_handler.hpp    |   90 +
 .../asio/1.18.2/include/asio/detail/wait_op.hpp    |   45 +
 .../asio/1.18.2/include/asio/detail/win_event.hpp  |  164 +
 .../include/asio/detail/win_fd_set_adapter.hpp     |  149 +
 .../include/asio/detail/win_fenced_block.hpp       |   90 +
 .../asio/1.18.2/include/asio/detail/win_global.hpp |   71 +
 .../asio/detail/win_iocp_handle_read_op.hpp        |  117 +
 .../asio/detail/win_iocp_handle_service.hpp        |  335 ++
 .../asio/detail/win_iocp_handle_write_op.hpp       |  110 +
 .../include/asio/detail/win_iocp_io_context.hpp    |  339 ++
 .../asio/detail/win_iocp_null_buffers_op.hpp       |  127 +
 .../include/asio/detail/win_iocp_operation.hpp     |   96 +
 .../include/asio/detail/win_iocp_overlapped_op.hpp |   96 +
 .../asio/detail/win_iocp_overlapped_ptr.hpp        |  171 +
 .../asio/detail/win_iocp_serial_port_service.hpp   |  232 +
 .../asio/detail/win_iocp_socket_accept_op.hpp      |  312 +
 .../asio/detail/win_iocp_socket_connect_op.hpp     |  135 +
 .../asio/detail/win_iocp_socket_recv_op.hpp        |  124 +
 .../asio/detail/win_iocp_socket_recvfrom_op.hpp    |  133 +
 .../asio/detail/win_iocp_socket_recvmsg_op.hpp     |  125 +
 .../asio/detail/win_iocp_socket_send_op.hpp        |  118 +
 .../asio/detail/win_iocp_socket_service.hpp        |  581 ++
 .../asio/detail/win_iocp_socket_service_base.hpp   |  600 ++
 .../include/asio/detail/win_iocp_thread_info.hpp   |   34 +
 .../include/asio/detail/win_iocp_wait_op.hpp       |  128 +
 .../asio/1.18.2/include/asio/detail/win_mutex.hpp  |   78 +
 .../asio/detail/win_object_handle_service.hpp      |  195 +
 .../include/asio/detail/win_static_mutex.hpp       |   74 +
 .../asio/1.18.2/include/asio/detail/win_thread.hpp |  147 +
 .../1.18.2/include/asio/detail/win_tss_ptr.hpp     |   79 +
 .../1.18.2/include/asio/detail/winapp_thread.hpp   |  124 +
 .../1.18.2/include/asio/detail/wince_thread.hpp    |  124 +
 .../include/asio/detail/winrt_async_manager.hpp    |  305 +
 .../1.18.2/include/asio/detail/winrt_async_op.hpp  |   65 +
 .../include/asio/detail/winrt_resolve_op.hpp       |  125 +
 .../include/asio/detail/winrt_resolver_service.hpp |  212 +
 .../asio/detail/winrt_socket_connect_op.hpp        |   98 +
 .../include/asio/detail/winrt_socket_recv_op.hpp   |  119 +
 .../include/asio/detail/winrt_socket_send_op.hpp   |  110 +
 .../include/asio/detail/winrt_ssocket_service.hpp  |  250 +
 .../asio/detail/winrt_ssocket_service_base.hpp     |  362 ++
 .../include/asio/detail/winrt_timer_scheduler.hpp  |  147 +
 .../1.18.2/include/asio/detail/winrt_utils.hpp     |  106 +
 .../1.18.2/include/asio/detail/winsock_init.hpp    |  128 +
 .../1.18.2/include/asio/detail/work_dispatcher.hpp |  148 +
 .../1.18.2/include/asio/detail/wrapped_handler.hpp |  327 ++
 .../asio/1.18.2/include/asio/dispatch.hpp          |  121 +
 cpp/third_party/asio/1.18.2/include/asio/error.hpp |  356 ++
 .../asio/1.18.2/include/asio/error_code.hpp        |  202 +
 .../asio/1.18.2/include/asio/execution.hpp         |   48 +
 .../1.18.2/include/asio/execution/allocator.hpp    |  337 ++
 .../1.18.2/include/asio/execution/any_executor.hpp | 2346 ++++++++
 .../1.18.2/include/asio/execution/bad_executor.hpp |   47 +
 .../1.18.2/include/asio/execution/blocking.hpp     | 1551 +++++
 .../include/asio/execution/blocking_adaptation.hpp | 1212 ++++
 .../1.18.2/include/asio/execution/bulk_execute.hpp |  395 ++
 .../include/asio/execution/bulk_guarantee.hpp      | 1215 ++++
 .../asio/1.18.2/include/asio/execution/connect.hpp |  489 ++
 .../asio/1.18.2/include/asio/execution/context.hpp |  233 +
 .../1.18.2/include/asio/execution/context_as.hpp   |  221 +
 .../include/asio/execution/detail/as_invocable.hpp |  152 +
 .../include/asio/execution/detail/as_operation.hpp |  105 +
 .../include/asio/execution/detail/as_receiver.hpp  |  128 +
 .../include/asio/execution/detail/bulk_sender.hpp  |  261 +
 .../asio/execution/detail/submit_receiver.hpp      |  233 +
 .../asio/execution/detail/void_receiver.hpp        |   90 +
 .../asio/1.18.2/include/asio/execution/execute.hpp |  283 +
 .../1.18.2/include/asio/execution/executor.hpp     |  252 +
 .../include/asio/execution/impl/bad_executor.ipp   |   40 +
 .../execution/impl/receiver_invocation_error.ipp   |   36 +
 .../include/asio/execution/invocable_archetype.hpp |   71 +
 .../asio/1.18.2/include/asio/execution/mapping.hpp | 1116 ++++
 .../1.18.2/include/asio/execution/occupancy.hpp    |  226 +
 .../include/asio/execution/operation_state.hpp     |   94 +
 .../include/asio/execution/outstanding_work.hpp    |  867 +++
 .../1.18.2/include/asio/execution/prefer_only.hpp  |  331 ++
 .../1.18.2/include/asio/execution/receiver.hpp     |  280 +
 .../asio/execution/receiver_invocation_error.hpp   |   48 +
 .../1.18.2/include/asio/execution/relationship.hpp |  865 +++
 .../1.18.2/include/asio/execution/schedule.hpp     |  287 +
 .../1.18.2/include/asio/execution/scheduler.hpp    |   86 +
 .../asio/1.18.2/include/asio/execution/sender.hpp  |  311 +
 .../1.18.2/include/asio/execution/set_done.hpp     |  250 +
 .../1.18.2/include/asio/execution/set_error.hpp    |  250 +
 .../1.18.2/include/asio/execution/set_value.hpp    |  483 ++
 .../asio/1.18.2/include/asio/execution/start.hpp   |  247 +
 .../asio/1.18.2/include/asio/execution/submit.hpp  |  450 ++
 .../asio/1.18.2/include/asio/execution_context.hpp |  412 ++
 .../asio/1.18.2/include/asio/executor.hpp          |  347 ++
 .../1.18.2/include/asio/executor_work_guard.hpp    |  302 +
 .../1.18.2/include/asio/experimental/as_single.hpp |  135 +
 .../include/asio/experimental/impl/as_single.hpp   |  243 +
 .../1.18.2/include/asio/generic/basic_endpoint.hpp |  193 +
 .../include/asio/generic/datagram_protocol.hpp     |  123 +
 .../include/asio/generic/detail/endpoint.hpp       |  133 +
 .../include/asio/generic/detail/impl/endpoint.ipp  |  110 +
 .../1.18.2/include/asio/generic/raw_protocol.hpp   |  121 +
 .../include/asio/generic/seq_packet_protocol.hpp   |  122 +
 .../include/asio/generic/stream_protocol.hpp       |  127 +
 .../1.18.2/include/asio/handler_alloc_hook.hpp     |  104 +
 .../include/asio/handler_continuation_hook.hpp     |   54 +
 .../1.18.2/include/asio/handler_invoke_hook.hpp    |  111 +
 .../1.18.2/include/asio/high_resolution_timer.hpp  |   44 +
 .../asio/1.18.2/include/asio/impl/awaitable.hpp    |  436 ++
 .../include/asio/impl/buffered_read_stream.hpp     |  529 ++
 .../include/asio/impl/buffered_write_stream.hpp    |  509 ++
 .../asio/1.18.2/include/asio/impl/co_spawn.hpp     |  298 +
 .../asio/1.18.2/include/asio/impl/compose.hpp      |  637 +++
 .../asio/1.18.2/include/asio/impl/connect.hpp      |  916 +++
 .../asio/1.18.2/include/asio/impl/defer.hpp        |  252 +
 .../asio/1.18.2/include/asio/impl/detached.hpp     |  130 +
 .../asio/1.18.2/include/asio/impl/dispatch.hpp     |  247 +
 .../asio/1.18.2/include/asio/impl/error.ipp        |  128 +
 .../asio/1.18.2/include/asio/impl/error_code.ipp   |  206 +
 .../1.18.2/include/asio/impl/execution_context.hpp |  109 +
 .../1.18.2/include/asio/impl/execution_context.ipp |   82 +
 .../asio/1.18.2/include/asio/impl/executor.hpp     |  300 +
 .../asio/1.18.2/include/asio/impl/executor.ipp     |   43 +
 .../include/asio/impl/handler_alloc_hook.ipp       |   61 +
 .../asio/1.18.2/include/asio/impl/io_context.hpp   |  444 ++
 .../asio/1.18.2/include/asio/impl/io_context.ipp   |  175 +
 .../include/asio/impl/multiple_exceptions.ipp      |   49 +
 .../asio/1.18.2/include/asio/impl/post.hpp         |  252 +
 .../asio/1.18.2/include/asio/impl/read.hpp         | 1214 ++++
 .../asio/1.18.2/include/asio/impl/read_at.hpp      |  744 +++
 .../asio/1.18.2/include/asio/impl/read_until.hpp   | 3371 +++++++++++
 .../1.18.2/include/asio/impl/redirect_error.hpp    |  391 ++
 .../1.18.2/include/asio/impl/serial_port_base.hpp  |   59 +
 .../1.18.2/include/asio/impl/serial_port_base.ipp  |  554 ++
 .../asio/1.18.2/include/asio/impl/spawn.hpp        |  527 ++
 .../asio/1.18.2/include/asio/impl/src.hpp          |   86 +
 .../1.18.2/include/asio/impl/system_context.hpp    |   34 +
 .../1.18.2/include/asio/impl/system_context.ipp    |   92 +
 .../1.18.2/include/asio/impl/system_executor.hpp   |  185 +
 .../asio/1.18.2/include/asio/impl/thread_pool.hpp  |  354 ++
 .../asio/1.18.2/include/asio/impl/thread_pool.ipp  |  141 +
 .../1.18.2/include/asio/impl/use_awaitable.hpp     |  279 +
 .../asio/1.18.2/include/asio/impl/use_future.hpp   | 1028 ++++
 .../asio/1.18.2/include/asio/impl/write.hpp        | 1116 ++++
 .../asio/1.18.2/include/asio/impl/write_at.hpp     |  666 +++
 .../asio/1.18.2/include/asio/io_context.hpp        | 1550 +++++
 .../asio/1.18.2/include/asio/io_context_strand.hpp |  376 ++
 .../asio/1.18.2/include/asio/io_service.hpp        |   33 +
 .../asio/1.18.2/include/asio/io_service_strand.hpp |   20 +
 .../asio/1.18.2/include/asio/ip/address.hpp        |  290 +
 .../asio/1.18.2/include/asio/ip/address_v4.hpp     |  355 ++
 .../1.18.2/include/asio/ip/address_v4_iterator.hpp |  162 +
 .../1.18.2/include/asio/ip/address_v4_range.hpp    |  134 +
 .../asio/1.18.2/include/asio/ip/address_v6.hpp     |  382 ++
 .../1.18.2/include/asio/ip/address_v6_iterator.hpp |  183 +
 .../1.18.2/include/asio/ip/address_v6_range.hpp    |  129 +
 .../1.18.2/include/asio/ip/bad_address_cast.hpp    |   53 +
 .../asio/1.18.2/include/asio/ip/basic_endpoint.hpp |  291 +
 .../asio/1.18.2/include/asio/ip/basic_resolver.hpp | 1076 ++++
 .../include/asio/ip/basic_resolver_entry.hpp       |  113 +
 .../include/asio/ip/basic_resolver_iterator.hpp    |  192 +
 .../include/asio/ip/basic_resolver_query.hpp       |  244 +
 .../include/asio/ip/basic_resolver_results.hpp     |  311 +
 .../1.18.2/include/asio/ip/detail/endpoint.hpp     |  141 +
 .../include/asio/ip/detail/impl/endpoint.ipp       |  199 +
 .../include/asio/ip/detail/socket_option.hpp       |  566 ++
 .../asio/1.18.2/include/asio/ip/host_name.hpp      |   42 +
 .../asio/1.18.2/include/asio/ip/icmp.hpp           |  115 +
 .../asio/1.18.2/include/asio/ip/impl/address.hpp   |   67 +
 .../asio/1.18.2/include/asio/ip/impl/address.ipp   |  239 +
 .../1.18.2/include/asio/ip/impl/address_v4.hpp     |   67 +
 .../1.18.2/include/asio/ip/impl/address_v4.ipp     |  210 +
 .../1.18.2/include/asio/ip/impl/address_v6.hpp     |   67 +
 .../1.18.2/include/asio/ip/impl/address_v6.ipp     |  350 ++
 .../1.18.2/include/asio/ip/impl/basic_endpoint.hpp |   43 +
 .../asio/1.18.2/include/asio/ip/impl/host_name.ipp |   54 +
 .../1.18.2/include/asio/ip/impl/network_v4.hpp     |   54 +
 .../1.18.2/include/asio/ip/impl/network_v4.ipp     |  216 +
 .../1.18.2/include/asio/ip/impl/network_v6.hpp     |   53 +
 .../1.18.2/include/asio/ip/impl/network_v6.ipp     |  185 +
 .../asio/1.18.2/include/asio/ip/multicast.hpp      |  191 +
 .../asio/1.18.2/include/asio/ip/network_v4.hpp     |  261 +
 .../asio/1.18.2/include/asio/ip/network_v6.hpp     |  235 +
 .../asio/1.18.2/include/asio/ip/resolver_base.hpp  |  129 +
 .../1.18.2/include/asio/ip/resolver_query_base.hpp |   43 +
 .../asio/1.18.2/include/asio/ip/tcp.hpp            |  155 +
 .../asio/1.18.2/include/asio/ip/udp.hpp            |  111 +
 .../asio/1.18.2/include/asio/ip/unicast.hpp        |   70 +
 .../asio/1.18.2/include/asio/ip/v6_only.hpp        |   69 +
 .../1.18.2/include/asio/is_applicable_property.hpp |   61 +
 .../asio/1.18.2/include/asio/is_executor.hpp       |   46 +
 .../asio/1.18.2/include/asio/is_read_buffered.hpp  |   59 +
 .../asio/1.18.2/include/asio/is_write_buffered.hpp |   59 +
 .../1.18.2/include/asio/local/basic_endpoint.hpp   |  247 +
 .../1.18.2/include/asio/local/connect_pair.hpp     |  101 +
 .../include/asio/local/datagram_protocol.hpp       |   80 +
 .../1.18.2/include/asio/local/detail/endpoint.hpp  |  139 +
 .../include/asio/local/detail/impl/endpoint.ipp    |  136 +
 .../1.18.2/include/asio/local/stream_protocol.hpp  |   90 +
 .../1.18.2/include/asio/multiple_exceptions.hpp    |   58 +
 .../asio/1.18.2/include/asio/packaged_task.hpp     |  126 +
 .../asio/1.18.2/include/asio/placeholders.hpp      |  151 +
 .../1.18.2/include/asio/posix/basic_descriptor.hpp |  698 +++
 .../include/asio/posix/basic_stream_descriptor.hpp |  481 ++
 .../asio/1.18.2/include/asio/posix/descriptor.hpp  |   37 +
 .../1.18.2/include/asio/posix/descriptor_base.hpp  |   90 +
 .../include/asio/posix/stream_descriptor.hpp       |   37 +
 cpp/third_party/asio/1.18.2/include/asio/post.hpp  |  126 +
 .../asio/1.18.2/include/asio/prefer.hpp            |  734 +++
 cpp/third_party/asio/1.18.2/include/asio/query.hpp |  324 ++
 cpp/third_party/asio/1.18.2/include/asio/read.hpp  | 1300 +++++
 .../asio/1.18.2/include/asio/read_at.hpp           |  694 +++
 .../asio/1.18.2/include/asio/read_until.hpp        | 2899 ++++++++++
 .../asio/1.18.2/include/asio/redirect_error.hpp    |   66 +
 .../asio/1.18.2/include/asio/require.hpp           |  571 ++
 .../asio/1.18.2/include/asio/require_concept.hpp   |  352 ++
 .../asio/1.18.2/include/asio/serial_port.hpp       |   36 +
 .../asio/1.18.2/include/asio/serial_port_base.hpp  |  167 +
 .../asio/1.18.2/include/asio/signal_set.hpp        |   28 +
 .../asio/1.18.2/include/asio/socket_base.hpp       |  559 ++
 cpp/third_party/asio/1.18.2/include/asio/spawn.hpp |  344 ++
 cpp/third_party/asio/1.18.2/include/asio/ssl.hpp   |   28 +
 .../asio/1.18.2/include/asio/ssl/context.hpp       |  761 +++
 .../asio/1.18.2/include/asio/ssl/context_base.hpp  |  209 +
 .../asio/ssl/detail/buffered_handshake_op.hpp      |  119 +
 .../asio/1.18.2/include/asio/ssl/detail/engine.hpp |  165 +
 .../include/asio/ssl/detail/handshake_op.hpp       |   67 +
 .../1.18.2/include/asio/ssl/detail/impl/engine.ipp |  349 ++
 .../include/asio/ssl/detail/impl/openssl_init.ipp  |  165 +
 .../asio/1.18.2/include/asio/ssl/detail/io.hpp     |  416 ++
 .../include/asio/ssl/detail/openssl_init.hpp       |  101 +
 .../include/asio/ssl/detail/openssl_types.hpp      |   34 +
 .../include/asio/ssl/detail/password_callback.hpp  |   66 +
 .../1.18.2/include/asio/ssl/detail/read_op.hpp     |   72 +
 .../1.18.2/include/asio/ssl/detail/shutdown_op.hpp |   69 +
 .../1.18.2/include/asio/ssl/detail/stream_core.hpp |  169 +
 .../include/asio/ssl/detail/verify_callback.hpp    |   62 +
 .../1.18.2/include/asio/ssl/detail/write_op.hpp    |   76 +
 .../asio/1.18.2/include/asio/ssl/error.hpp         |  125 +
 .../include/asio/ssl/host_name_verification.hpp    |   90 +
 .../asio/1.18.2/include/asio/ssl/impl/context.hpp  |   67 +
 .../asio/1.18.2/include/asio/ssl/impl/context.ipp  | 1238 ++++
 .../asio/1.18.2/include/asio/ssl/impl/error.ipp    |  102 +
 .../asio/ssl/impl/host_name_verification.ipp       |   73 +
 .../include/asio/ssl/impl/rfc2818_verification.ipp |  164 +
 .../asio/1.18.2/include/asio/ssl/impl/src.hpp      |   29 +
 .../include/asio/ssl/rfc2818_verification.hpp      |   98 +
 .../asio/1.18.2/include/asio/ssl/stream.hpp        |  900 +++
 .../asio/1.18.2/include/asio/ssl/stream_base.hpp   |   52 +
 .../1.18.2/include/asio/ssl/verify_context.hpp     |   67 +
 .../asio/1.18.2/include/asio/ssl/verify_mode.hpp   |   63 +
 .../1.18.2/include/asio/static_thread_pool.hpp     |   31 +
 .../asio/1.18.2/include/asio/steady_timer.hpp      |   42 +
 .../asio/1.18.2/include/asio/strand.hpp            |  569 ++
 .../asio/1.18.2/include/asio/streambuf.hpp         |   33 +
 .../asio/1.18.2/include/asio/system_context.hpp    |   90 +
 .../asio/1.18.2/include/asio/system_error.hpp      |  131 +
 .../asio/1.18.2/include/asio/system_executor.hpp   |  684 +++
 .../asio/1.18.2/include/asio/system_timer.hpp      |   42 +
 .../asio/1.18.2/include/asio/this_coro.hpp         |   45 +
 .../asio/1.18.2/include/asio/thread.hpp            |   92 +
 .../asio/1.18.2/include/asio/thread_pool.hpp       | 1131 ++++
 .../asio/1.18.2/include/asio/time_traits.hpp       |   86 +
 .../include/asio/traits/bulk_execute_free.hpp      |  114 +
 .../include/asio/traits/bulk_execute_member.hpp    |  114 +
 .../1.18.2/include/asio/traits/connect_free.hpp    |  112 +
 .../1.18.2/include/asio/traits/connect_member.hpp  |  112 +
 .../include/asio/traits/equality_comparable.hpp    |  104 +
 .../1.18.2/include/asio/traits/execute_free.hpp    |  108 +
 .../1.18.2/include/asio/traits/execute_member.hpp  |  108 +
 .../1.18.2/include/asio/traits/prefer_free.hpp     |  108 +
 .../1.18.2/include/asio/traits/prefer_member.hpp   |  108 +
 .../asio/1.18.2/include/asio/traits/query_free.hpp |  108 +
 .../1.18.2/include/asio/traits/query_member.hpp    |  108 +
 .../asio/traits/query_static_constexpr_member.hpp  |  108 +
 .../include/asio/traits/require_concept_free.hpp   |  108 +
 .../include/asio/traits/require_concept_member.hpp |  108 +
 .../1.18.2/include/asio/traits/require_free.hpp    |  108 +
 .../1.18.2/include/asio/traits/require_member.hpp  |  108 +
 .../1.18.2/include/asio/traits/schedule_free.hpp   |  108 +
 .../1.18.2/include/asio/traits/schedule_member.hpp |  108 +
 .../1.18.2/include/asio/traits/set_done_free.hpp   |  108 +
 .../1.18.2/include/asio/traits/set_done_member.hpp |  108 +
 .../1.18.2/include/asio/traits/set_error_free.hpp  |  112 +
 .../include/asio/traits/set_error_member.hpp       |  112 +
 .../1.18.2/include/asio/traits/set_value_free.hpp  |  234 +
 .../include/asio/traits/set_value_member.hpp       |  234 +
 .../asio/1.18.2/include/asio/traits/start_free.hpp |  108 +
 .../1.18.2/include/asio/traits/start_member.hpp    |  108 +
 .../1.18.2/include/asio/traits/static_query.hpp    |  108 +
 .../1.18.2/include/asio/traits/static_require.hpp  |  123 +
 .../include/asio/traits/static_require_concept.hpp |  124 +
 .../1.18.2/include/asio/traits/submit_free.hpp     |  112 +
 .../1.18.2/include/asio/traits/submit_member.hpp   |  112 +
 .../asio/1.18.2/include/asio/ts/buffer.hpp         |   24 +
 .../asio/1.18.2/include/asio/ts/executor.hpp       |   35 +
 .../asio/1.18.2/include/asio/ts/internet.hpp       |   40 +
 .../asio/1.18.2/include/asio/ts/io_context.hpp     |   20 +
 .../asio/1.18.2/include/asio/ts/net.hpp            |   26 +
 .../asio/1.18.2/include/asio/ts/netfwd.hpp         |  254 +
 .../asio/1.18.2/include/asio/ts/socket.hpp         |   27 +
 .../asio/1.18.2/include/asio/ts/timer.hpp          |   26 +
 .../asio/1.18.2/include/asio/unyield.hpp           |   21 +
 .../asio/1.18.2/include/asio/use_awaitable.hpp     |  169 +
 .../asio/1.18.2/include/asio/use_future.hpp        |  160 +
 .../asio/1.18.2/include/asio/uses_executor.hpp     |   71 +
 .../asio/1.18.2/include/asio/version.hpp           |   23 +
 .../asio/1.18.2/include/asio/wait_traits.hpp       |   56 +
 .../include/asio/windows/basic_object_handle.hpp   |  435 ++
 .../asio/windows/basic_overlapped_handle.hpp       |  361 ++
 .../asio/windows/basic_random_access_handle.hpp    |  490 ++
 .../include/asio/windows/basic_stream_handle.hpp   |  474 ++
 .../1.18.2/include/asio/windows/object_handle.hpp  |   38 +
 .../include/asio/windows/overlapped_handle.hpp     |   39 +
 .../1.18.2/include/asio/windows/overlapped_ptr.hpp |  145 +
 .../include/asio/windows/random_access_handle.hpp  |   37 +
 .../1.18.2/include/asio/windows/stream_handle.hpp  |   37 +
 cpp/third_party/asio/1.18.2/include/asio/write.hpp | 1258 ++++
 .../asio/1.18.2/include/asio/write_at.hpp          |  702 +++
 cpp/third_party/asio/1.18.2/include/asio/yield.hpp |   23 +
 cpp/third_party/filesystem/1.5.12/CMakeLists.txt   |    4 +
 .../filesystem/1.5.12/include/ghc/filesystem.hpp   | 6049 ++++++++++++++++++++
 .../filesystem/1.5.12/include/ghc/fs_fwd.hpp       |   38 +
 .../filesystem/1.5.12/include/ghc/fs_impl.hpp      |   35 +
 .../filesystem/1.5.12/include/ghc/fs_std.hpp       |   60 +
 .../filesystem/1.5.12/include/ghc/fs_std_fwd.hpp   |   63 +
 .../filesystem/1.5.12/include/ghc/fs_std_impl.hpp  |   46 +
 cpp/third_party/fmt/9.0.0/CMakeLists.txt           |    5 +
 cpp/third_party/fmt/9.0.0/include/fmt/args.h       |  234 +
 cpp/third_party/fmt/9.0.0/include/fmt/chrono.h     | 2080 +++++++
 cpp/third_party/fmt/9.0.0/include/fmt/color.h      |  651 +++
 cpp/third_party/fmt/9.0.0/include/fmt/compile.h    |  603 ++
 cpp/third_party/fmt/9.0.0/include/fmt/core.h       | 3280 +++++++++++
 cpp/third_party/fmt/9.0.0/include/fmt/format-inl.h | 1733 ++++++
 cpp/third_party/fmt/9.0.0/include/fmt/format.h     | 4192 ++++++++++++++
 cpp/third_party/fmt/9.0.0/include/fmt/os.h         |  478 ++
 cpp/third_party/fmt/9.0.0/include/fmt/ostream.h    |  213 +
 cpp/third_party/fmt/9.0.0/include/fmt/printf.h     |  640 +++
 cpp/third_party/fmt/9.0.0/include/fmt/ranges.h     |  631 ++
 cpp/third_party/fmt/9.0.0/include/fmt/std.h        |  176 +
 cpp/third_party/fmt/9.0.0/include/fmt/xchar.h      |  232 +
 .../opencensus/0.5.0-alpha/CMakeLists.txt          |    4 +
 cpp/third_party/opencensus/0.5.0-alpha/README.md   |    1 +
 .../opencensus/0.5.0-alpha/opencensus/BUILD        |   37 +
 .../0.5.0-alpha/opencensus/CMakeLists.txt          |   20 +
 .../opencensus/0.5.0-alpha/opencensus/common/BUILD |   28 +
 .../0.5.0-alpha/opencensus/common/CMakeLists.txt   |   15 +
 .../0.5.0-alpha/opencensus/common/internal/BUILD   |  163 +
 .../opencensus/common/internal/CMakeLists.txt      |   49 +
 .../opencensus/common/internal/grpc/BUILD          |   57 +
 .../opencensus/common/internal/grpc/status.cc      |   80 +
 .../opencensus/common/internal/grpc/status.h       |   31 +
 .../opencensus/common/internal/grpc/status_test.cc |   40 +
 .../common/internal/grpc/with_user_agent.cc        |   30 +
 .../common/internal/grpc/with_user_agent.h         |   30 +
 .../opencensus/common/internal/hostname.cc         |   69 +
 .../opencensus/common/internal/hostname.h          |   33 +
 .../opencensus/common/internal/hostname_test.cc    |   33 +
 .../opencensus/common/internal/random.cc           |   59 +
 .../opencensus/common/internal/random.h            |   77 +
 .../opencensus/common/internal/random_benchmark.cc |   49 +
 .../opencensus/common/internal/random_test.cc      |   37 +
 .../opencensus/common/internal/stats_object.h      |  557 ++
 .../common/internal/stats_object_test.cc           |  559 ++
 .../common/internal/string_vector_hash.h           |   36 +
 .../opencensus/common/internal/timestamp.cc        |   33 +
 .../opencensus/common/internal/timestamp.h         |   30 +
 .../common/internal/timestamp_benchmark.cc         |   34 +
 .../opencensus/common/internal/timestamp_test.cc   |   40 +
 .../opencensus/common/internal/varint.cc           |   59 +
 .../opencensus/common/internal/varint.h            |   36 +
 .../opencensus/common/internal/varint_test.cc      |   75 +
 .../0.5.0-alpha/opencensus/common/version.h        |   22 +
 .../0.5.0-alpha/opencensus/context/BUILD           |   86 +
 .../0.5.0-alpha/opencensus/context/CMakeLists.txt  |   37 +
 .../0.5.0-alpha/opencensus/context/README.md       |    7 +
 .../0.5.0-alpha/opencensus/context/context.h       |   83 +
 .../opencensus/context/internal/context.cc         |   74 +
 .../context/internal/context_benchmark.cc          |   54 +
 .../opencensus/context/internal/context_test.cc    |  115 +
 .../opencensus/context/internal/with_context.cc    |   64 +
 .../context/internal/with_context_test.cc          |   62 +
 .../0.5.0-alpha/opencensus/context/with_context.h  |   61 +
 .../opencensus/0.5.0-alpha/opencensus/copts.bzl    |   47 +
 .../opencensus/0.5.0-alpha/opencensus/curl.bzl     |  201 +
 .../0.5.0-alpha/opencensus/doc/benchmarks.md       |   59 +
 .../0.5.0-alpha/opencensus/doc/context.md          |  133 +
 .../0.5.0-alpha/opencensus/doc/conventions.md      |   89 +
 .../0.5.0-alpha/opencensus/doc/fuzzing.md          |   20 +
 .../opencensus/exporters/CMakeLists.txt            |   16 +
 .../opencensus/exporters/stats/CMakeLists.txt      |   15 +
 .../opencensus/exporters/stats/stdout/BUILD        |   45 +
 .../exporters/stats/stdout/CMakeLists.txt          |   27 +
 .../stats/stdout/internal/stdout_exporter.cc       |  134 +
 .../stats/stdout/internal/stdout_exporter_test.cc  |   66 +
 .../exporters/stats/stdout/stdout_exporter.h       |   35 +
 .../opencensus/exporters/trace/CMakeLists.txt      |   19 +
 .../opencensus/exporters/trace/ocagent/BUILD       |   56 +
 .../opencensus/exporters/trace/ocagent/README.md   |   75 +
 .../trace/ocagent/internal/ocagent_exporter.cc     |  359 ++
 .../ocagent/internal/ocagent_exporter_test.cc      |   72 +
 .../exporters/trace/ocagent/ocagent_exporter.h     |   60 +
 .../opencensus/exporters/trace/stackdriver/BUILD   |   44 +
 .../exporters/trace/stackdriver/README.md          |    3 +
 .../stackdriver/internal/stackdriver_exporter.cc   |  292 +
 .../trace/stackdriver/stackdriver_exporter.h       |   78 +
 .../opencensus/exporters/trace/stdout/BUILD        |   49 +
 .../exporters/trace/stdout/CMakeLists.txt          |   26 +
 .../trace/stdout/internal/stdout_exporter.cc       |   56 +
 .../trace/stdout/internal/stdout_exporter_test.cc  |   65 +
 .../exporters/trace/stdout/stdout_exporter.h       |   34 +
 .../opencensus/exporters/trace/zipkin/BUILD        |   56 +
 .../opencensus/exporters/trace/zipkin/README.md    |   52 +
 .../trace/zipkin/internal/zipkin_exporter.cc       |  393 ++
 .../trace/zipkin/internal/zipkin_exporter_test.cc  |   69 +
 .../exporters/trace/zipkin/zipkin_exporter.h       |   76 +
 .../opencensus/0.5.0-alpha/opencensus/stats/BUILD  |  264 +
 .../0.5.0-alpha/opencensus/stats/CMakeLists.txt    |  115 +
 .../0.5.0-alpha/opencensus/stats/README.md         |   19 +
 .../0.5.0-alpha/opencensus/stats/aggregation.h     |   90 +
 .../opencensus/stats/bucket_boundaries.h           |   88 +
 .../0.5.0-alpha/opencensus/stats/distribution.h    |   87 +
 .../0.5.0-alpha/opencensus/stats/examples/BUILD    |   52 +
 .../opencensus/stats/examples/exporter_example.cc  |  132 +
 .../stats/examples/view_and_recording_example.cc   |   98 +
 .../opencensus/stats/internal/aggregation.cc       |   41 +
 .../stats/internal/aggregation_window.cc           |   39 +
 .../opencensus/stats/internal/aggregation_window.h |   78 +
 .../opencensus/stats/internal/bucket_boundaries.cc |   81 +
 .../stats/internal/bucket_boundaries_test.cc       |   83 +
 .../opencensus/stats/internal/debug_string_test.cc |   91 +
 .../opencensus/stats/internal/delta_producer.cc    |  143 +
 .../opencensus/stats/internal/delta_producer.h     |  130 +
 .../opencensus/stats/internal/distribution.cc      |   51 +
 .../opencensus/stats/internal/distribution_test.cc |  177 +
 .../opencensus/stats/internal/measure.cc           |   60 +
 .../opencensus/stats/internal/measure_data.cc      |  111 +
 .../opencensus/stats/internal/measure_data.h       |   75 +
 .../opencensus/stats/internal/measure_data_test.cc |  143 +
 .../stats/internal/measure_descriptor.cc           |   29 +
 .../opencensus/stats/internal/measure_registry.cc  |   39 +
 .../stats/internal/measure_registry_impl.cc        |  162 +
 .../stats/internal/measure_registry_impl.h         |  119 +
 .../stats/internal/measure_registry_test.cc        |  166 +
 .../opencensus/stats/internal/recording.cc         |   38 +
 .../stats/internal/set_aggregation_window.cc       |   29 +
 .../stats/internal/set_aggregation_window.h        |   34 +
 .../opencensus/stats/internal/stats_exporter.cc    |  146 +
 .../stats/internal/stats_exporter_impl.h           |   71 +
 .../stats/internal/stats_exporter_test.cc          |  185 +
 .../opencensus/stats/internal/stats_manager.cc     |  208 +
 .../opencensus/stats/internal/stats_manager.h      |  139 +
 .../stats/internal/stats_manager_benchmark.cc      |  191 +
 .../stats/internal/stats_manager_test.cc           |  462 ++
 .../0.5.0-alpha/opencensus/stats/internal/view.cc  |   51 +
 .../opencensus/stats/internal/view_data.cc         |  101 +
 .../opencensus/stats/internal/view_data_impl.cc    |  364 ++
 .../opencensus/stats/internal/view_data_impl.h     |  177 +
 .../stats/internal/view_data_impl_test.cc          |  328 ++
 .../opencensus/stats/internal/view_data_test.cc    |  124 +
 .../opencensus/stats/internal/view_descriptor.cc   |  115 +
 .../0.5.0-alpha/opencensus/stats/measure.h         |  125 +
 .../opencensus/stats/measure_descriptor.h          |   73 +
 .../opencensus/stats/measure_registry.h            |   47 +
 .../0.5.0-alpha/opencensus/stats/recording.h       |   50 +
 .../0.5.0-alpha/opencensus/stats/stats.h           |   34 +
 .../0.5.0-alpha/opencensus/stats/stats_exporter.h  |   81 +
 .../0.5.0-alpha/opencensus/stats/tag_key.h         |   35 +
 .../0.5.0-alpha/opencensus/stats/tag_set.h         |   35 +
 .../opencensus/stats/testing/test_utils.cc         |   81 +
 .../opencensus/stats/testing/test_utils.h          |   66 +
 .../opencensus/0.5.0-alpha/opencensus/stats/view.h |   66 +
 .../0.5.0-alpha/opencensus/stats/view_data.h       |   97 +
 .../0.5.0-alpha/opencensus/stats/view_descriptor.h |  127 +
 .../opencensus/0.5.0-alpha/opencensus/tags/BUILD   |  199 +
 .../0.5.0-alpha/opencensus/tags/CMakeLists.txt     |   77 +
 .../0.5.0-alpha/opencensus/tags/README.md          |   13 +
 .../0.5.0-alpha/opencensus/tags/context_util.h     |   33 +
 .../opencensus/tags/internal/context_util.cc       |   41 +
 .../opencensus/tags/internal/context_util_test.cc  |   53 +
 .../opencensus/tags/internal/grpc_tags_bin.cc      |  129 +
 .../tags/internal/grpc_tags_bin_benchmark.cc       |   54 +
 .../tags/internal/grpc_tags_bin_corpus/kv          |  Bin 0 -> 9 bytes
 .../tags/internal/grpc_tags_bin_fuzzer.cc          |   23 +
 .../opencensus/tags/internal/grpc_tags_bin_test.cc |  169 +
 .../opencensus/tags/internal/tag_key.cc            |   80 +
 .../opencensus/tags/internal/tag_key_test.cc       |   58 +
 .../opencensus/tags/internal/tag_map.cc            |   84 +
 .../opencensus/tags/internal/tag_map_benchmark.cc  |   48 +
 .../opencensus/tags/internal/tag_map_test.cc       |  118 +
 .../opencensus/tags/internal/with_tag_map.cc       |   68 +
 .../tags/internal/with_tag_map_benchmark.cc        |   79 +
 .../opencensus/tags/internal/with_tag_map_test.cc  |  144 +
 .../opencensus/tags/propagation/grpc_tags_bin.h    |   42 +
 .../0.5.0-alpha/opencensus/tags/tag_key.h          |   65 +
 .../0.5.0-alpha/opencensus/tags/tag_map.h          |   72 +
 .../0.5.0-alpha/opencensus/tags/with_tag_map.h     |   62 +
 .../opencensus/0.5.0-alpha/opencensus/trace/BUILD  |  601 ++
 .../0.5.0-alpha/opencensus/trace/CMakeLists.txt    |  229 +
 .../0.5.0-alpha/opencensus/trace/README.md         |   59 +
 .../opencensus/trace/attribute_value_ref.h         |  105 +
 .../0.5.0-alpha/opencensus/trace/context_util.h    |   33 +
 .../0.5.0-alpha/opencensus/trace/examples/BUILD    |   39 +
 .../opencensus/trace/examples/span_example.cc      |   87 +
 .../opencensus/trace/exporter/annotation.h         |   58 +
 .../opencensus/trace/exporter/attribute_value.h    |   79 +
 .../0.5.0-alpha/opencensus/trace/exporter/link.h   |   74 +
 .../opencensus/trace/exporter/message_event.h      |   65 +
 .../opencensus/trace/exporter/span_data.h          |  163 +
 .../opencensus/trace/exporter/span_exporter.h      |   72 +
 .../0.5.0-alpha/opencensus/trace/exporter/status.h |   68 +
 .../opencensus/trace/internal/annotation.cc        |   48 +
 .../opencensus/trace/internal/annotation_test.cc   |   56 +
 .../opencensus/trace/internal/attribute_list.cc    |   56 +
 .../opencensus/trace/internal/attribute_list.h     |   63 +
 .../opencensus/trace/internal/attribute_value.cc   |  159 +
 .../trace/internal/attribute_value_ref.cc          |   74 +
 .../internal/attribute_value_ref_benchmark.cc      |   42 +
 .../trace/internal/attribute_value_ref_test.cc     |  125 +
 .../trace/internal/attribute_value_test.cc         |  115 +
 .../0.5.0-alpha/opencensus/trace/internal/b3.cc    |  113 +
 .../opencensus/trace/internal/b3_benchmark.cc      |   51 +
 .../trace/internal/b3_corpus/trace_id_64bit        |    1 +
 .../opencensus/trace/internal/b3_fuzzer.cc         |   33 +
 .../opencensus/trace/internal/b3_test.cc           |  118 +
 .../trace/internal/cloud_trace_context.cc          |  111 +
 .../internal/cloud_trace_context_benchmark.cc      |   65 +
 .../cloud_trace_context_corpus/span_id_overflow    |    1 +
 .../internal/cloud_trace_context_corpus/valid      |    1 +
 .../trace/internal/cloud_trace_context_fuzzer.cc   |   30 +
 .../trace/internal/cloud_trace_context_test.cc     |   96 +
 .../opencensus/trace/internal/context_util.cc      |   39 +
 .../opencensus/trace/internal/context_util_test.cc |   55 +
 .../opencensus/trace/internal/event_with_time.h    |   38 +
 .../opencensus/trace/internal/grpc_trace_bin.cc    |   88 +
 .../trace/internal/grpc_trace_bin_benchmark.cc     |   77 +
 .../trace/internal/grpc_trace_bin_corpus/valid     |  Bin 0 -> 29 bytes
 .../trace/internal/grpc_trace_bin_fuzzer.cc        |   32 +
 .../trace/internal/grpc_trace_bin_test.cc          |  136 +
 .../0.5.0-alpha/opencensus/trace/internal/link.cc  |   32 +
 .../opencensus/trace/internal/link_test.cc         |   45 +
 .../opencensus/trace/internal/local_span_store.cc  |   46 +
 .../opencensus/trace/internal/local_span_store.h   |  110 +
 .../trace/internal/local_span_store_impl.cc        |  162 +
 .../trace/internal/local_span_store_impl.h         |   85 +
 .../trace/internal/local_span_store_test.cc        |   53 +
 .../opencensus/trace/internal/message_event.cc     |   36 +
 .../trace/internal/running_span_store.cc           |   36 +
 .../opencensus/trace/internal/running_span_store.h |   72 +
 .../trace/internal/running_span_store_impl.cc      |  101 +
 .../trace/internal/running_span_store_impl.h       |   74 +
 .../trace/internal/running_span_store_test.cc      |  110 +
 .../opencensus/trace/internal/sampler.cc           |   69 +
 .../opencensus/trace/internal/sampler_benchmark.cc |   53 +
 .../opencensus/trace/internal/sampler_test.cc      |   75 +
 .../0.5.0-alpha/opencensus/trace/internal/span.cc  |  236 +
 .../opencensus/trace/internal/span_benchmark.cc    |   93 +
 .../opencensus/trace/internal/span_context.cc      |   40 +
 .../opencensus/trace/internal/span_context_test.cc |   65 +
 .../opencensus/trace/internal/span_data.cc         |  129 +
 .../opencensus/trace/internal/span_exporter.cc     |   49 +
 .../trace/internal/span_exporter_impl.cc           |  130 +
 .../opencensus/trace/internal/span_exporter_impl.h |  101 +
 .../trace/internal/span_exporter_test.cc           |   97 +
 .../opencensus/trace/internal/span_id.cc           |   50 +
 .../opencensus/trace/internal/span_id_benchmark.cc |   85 +
 .../opencensus/trace/internal/span_id_test.cc      |   49 +
 .../opencensus/trace/internal/span_impl.cc         |  188 +
 .../opencensus/trace/internal/span_impl.h          |  148 +
 .../opencensus/trace/internal/span_options_test.cc |   77 +
 .../opencensus/trace/internal/span_test.cc         |  370 ++
 .../opencensus/trace/internal/status.cc            |   83 +
 .../opencensus/trace/internal/status_test.cc       |   57 +
 .../opencensus/trace/internal/trace_config.cc      |   27 +
 .../opencensus/trace/internal/trace_config_impl.cc |   46 +
 .../opencensus/trace/internal/trace_config_impl.h  |   51 +
 .../opencensus/trace/internal/trace_config_test.cc |   67 +
 .../opencensus/trace/internal/trace_context.cc     |   97 +
 .../trace/internal/trace_context_benchmark.cc      |   47 +
 .../internal/trace_context_corpus/bad_options      |    1 +
 .../internal/trace_context_corpus/bad_span_id      |    1 +
 .../internal/trace_context_corpus/bad_trace_id     |    1 +
 .../trace/internal/trace_context_corpus/valid      |    1 +
 .../trace/internal/trace_context_fuzzer.cc         |   30 +
 .../trace/internal/trace_context_test.cc           |   86 +
 .../opencensus/trace/internal/trace_events.h       |  100 +
 .../opencensus/trace/internal/trace_id.cc          |   51 +
 .../opencensus/trace/internal/trace_options.cc     |   53 +
 .../trace/internal/trace_options_test.cc           |   54 +
 .../opencensus/trace/internal/trace_params_impl.h  |   69 +
 .../opencensus/trace/internal/with_span.cc         |   61 +
 .../trace/internal/with_span_benchmark.cc          |   66 +
 .../opencensus/trace/internal/with_span_test.cc    |  138 +
 .../0.5.0-alpha/opencensus/trace/propagation/b3.h  |   68 +
 .../trace/propagation/cloud_trace_context.h        |   53 +
 .../opencensus/trace/propagation/grpc_trace_bin.h  |   67 +
 .../opencensus/trace/propagation/trace_context.h   |   51 +
 .../0.5.0-alpha/opencensus/trace/sampler.h         |   99 +
 .../opencensus/0.5.0-alpha/opencensus/trace/span.h |  207 +
 .../0.5.0-alpha/opencensus/trace/span_context.h    |   78 +
 .../0.5.0-alpha/opencensus/trace/span_id.h         |   58 +
 .../0.5.0-alpha/opencensus/trace/status_code.h     |  183 +
 .../0.5.0-alpha/opencensus/trace/trace_config.h    |   35 +
 .../0.5.0-alpha/opencensus/trace/trace_id.h        |   58 +
 .../0.5.0-alpha/opencensus/trace/trace_options.h   |   64 +
 .../0.5.0-alpha/opencensus/trace/trace_params.h    |   41 +
 .../0.5.0-alpha/opencensus/trace/with_span.h       |   67 +
 cpp/third_party/opencensus/proto/CMakeLists.txt    |   21 +
 .../proto/opencensus/proto/agent/README.md         |   13 +
 .../opencensus/proto/agent/common/v1/BUILD.bazel   |   34 +
 .../opencensus/proto/agent/common/v1/common.proto  |   98 +
 .../opencensus/proto/agent/metrics/v1/BUILD.bazel  |   55 +
 .../proto/agent/metrics/v1/metrics_service.proto   |   56 +
 .../opencensus/proto/agent/trace/v1/BUILD.bazel    |   56 +
 .../proto/agent/trace/v1/trace_service.proto       |   85 +
 .../proto/agent/trace/v1/trace_service_http.yaml   |    9 +
 .../proto/opencensus/proto/metrics/v1/BUILD.bazel  |   48 +
 .../opencensus/proto/metrics/v1/metrics.proto      |  301 +
 .../proto/opencensus/proto/resource/v1/BUILD.bazel |   38 +
 .../opencensus/proto/resource/v1/resource.proto    |   33 +
 .../proto/opencensus/proto/stats/v1/BUILD.bazel    |   45 +
 .../proto/opencensus/proto/stats/v1/stats.proto    |  136 +
 .../proto/opencensus/proto/trace/v1/BUILD.bazel    |   83 +
 .../proto/opencensus/proto/trace/v1/trace.proto    |  417 ++
 .../opencensus/proto/trace/v1/trace_config.proto   |   79 +
 cpp/third_party/spdlog/1.10.0/CMakeLists.txt       |    4 +
 .../spdlog/1.10.0/include/spdlog/async.h           |   99 +
 .../1.10.0/include/spdlog/async_logger-inl.h       |   92 +
 .../spdlog/1.10.0/include/spdlog/async_logger.h    |   68 +
 .../spdlog/1.10.0/include/spdlog/cfg/argv.h        |   44 +
 .../spdlog/1.10.0/include/spdlog/cfg/env.h         |   38 +
 .../spdlog/1.10.0/include/spdlog/cfg/helpers-inl.h |  120 +
 .../spdlog/1.10.0/include/spdlog/cfg/helpers.h     |   29 +
 .../spdlog/1.10.0/include/spdlog/common-inl.h      |   82 +
 .../spdlog/1.10.0/include/spdlog/common.h          |  359 ++
 .../1.10.0/include/spdlog/details/backtracer-inl.h |   69 +
 .../1.10.0/include/spdlog/details/backtracer.h     |   45 +
 .../1.10.0/include/spdlog/details/circular_q.h     |  141 +
 .../include/spdlog/details/console_globals.h       |   32 +
 .../include/spdlog/details/file_helper-inl.h       |  172 +
 .../1.10.0/include/spdlog/details/file_helper.h    |   61 +
 .../1.10.0/include/spdlog/details/fmt_helper.h     |  169 +
 .../1.10.0/include/spdlog/details/log_msg-inl.h    |   37 +
 .../spdlog/1.10.0/include/spdlog/details/log_msg.h |   37 +
 .../include/spdlog/details/log_msg_buffer-inl.h    |   58 +
 .../1.10.0/include/spdlog/details/log_msg_buffer.h |   33 +
 .../include/spdlog/details/mpmc_blocking_q.h       |  126 +
 .../1.10.0/include/spdlog/details/null_mutex.h     |   49 +
 .../spdlog/1.10.0/include/spdlog/details/os-inl.h  |  610 ++
 .../spdlog/1.10.0/include/spdlog/details/os.h      |  118 +
 .../include/spdlog/details/periodic_worker-inl.h   |   49 +
 .../include/spdlog/details/periodic_worker.h       |   40 +
 .../1.10.0/include/spdlog/details/registry-inl.h   |  313 +
 .../1.10.0/include/spdlog/details/registry.h       |  115 +
 .../include/spdlog/details/synchronous_factory.h   |   24 +
 .../include/spdlog/details/tcp_client-windows.h    |  160 +
 .../1.10.0/include/spdlog/details/tcp_client.h     |  145 +
 .../include/spdlog/details/thread_pool-inl.h       |  136 +
 .../1.10.0/include/spdlog/details/thread_pool.h    |  121 +
 .../include/spdlog/details/udp_client-windows.h    |  111 +
 .../1.10.0/include/spdlog/details/udp_client.h     |   94 +
 .../include/spdlog/details/windows_include.h       |   11 +
 .../spdlog/1.10.0/include/spdlog/fmt/bin_to_hex.h  |  246 +
 .../1.10.0/include/spdlog/fmt/bundled/args.h       |  234 +
 .../1.10.0/include/spdlog/fmt/bundled/chrono.h     | 2067 +++++++
 .../1.10.0/include/spdlog/fmt/bundled/color.h      |  638 +++
 .../1.10.0/include/spdlog/fmt/bundled/compile.h    |  642 +++
 .../1.10.0/include/spdlog/fmt/bundled/core.h       | 3236 +++++++++++
 .../include/spdlog/fmt/bundled/fmt.license.rst     |   27 +
 .../1.10.0/include/spdlog/fmt/bundled/format-inl.h | 2643 +++++++++
 .../1.10.0/include/spdlog/fmt/bundled/format.h     | 3104 ++++++++++
 .../1.10.0/include/spdlog/fmt/bundled/locale.h     |    2 +
 .../spdlog/1.10.0/include/spdlog/fmt/bundled/os.h  |  527 ++
 .../1.10.0/include/spdlog/fmt/bundled/ostream.h    |  135 +
 .../1.10.0/include/spdlog/fmt/bundled/printf.h     |  657 +++
 .../1.10.0/include/spdlog/fmt/bundled/ranges.h     |  793 +++
 .../1.10.0/include/spdlog/fmt/bundled/xchar.h      |  236 +
 .../spdlog/1.10.0/include/spdlog/fmt/chrono.h      |   22 +
 .../spdlog/1.10.0/include/spdlog/fmt/compile.h     |   22 +
 .../spdlog/1.10.0/include/spdlog/fmt/fmt.h         |   29 +
 .../spdlog/1.10.0/include/spdlog/fmt/ostr.h        |   22 +
 .../spdlog/1.10.0/include/spdlog/fmt/ranges.h      |   22 +
 .../spdlog/1.10.0/include/spdlog/fmt/xchar.h       |   22 +
 .../spdlog/1.10.0/include/spdlog/formatter.h       |   18 +
 cpp/third_party/spdlog/1.10.0/include/spdlog/fwd.h |   18 +
 .../spdlog/1.10.0/include/spdlog/logger-inl.h      |  257 +
 .../spdlog/1.10.0/include/spdlog/logger.h          |  447 ++
 .../1.10.0/include/spdlog/pattern_formatter-inl.h  | 1425 +++++
 .../1.10.0/include/spdlog/pattern_formatter.h      |  127 +
 .../1.10.0/include/spdlog/sinks/android_sink.h     |  119 +
 .../include/spdlog/sinks/ansicolor_sink-inl.h      |  145 +
 .../1.10.0/include/spdlog/sinks/ansicolor_sink.h   |  118 +
 .../1.10.0/include/spdlog/sinks/base_sink-inl.h    |   63 +
 .../spdlog/1.10.0/include/spdlog/sinks/base_sink.h |   52 +
 .../include/spdlog/sinks/basic_file_sink-inl.h     |   44 +
 .../1.10.0/include/spdlog/sinks/basic_file_sink.h  |   60 +
 .../1.10.0/include/spdlog/sinks/daily_file_sink.h  |  294 +
 .../spdlog/1.10.0/include/spdlog/sinks/dist_sink.h |   97 +
 .../1.10.0/include/spdlog/sinks/dup_filter_sink.h  |   94 +
 .../1.10.0/include/spdlog/sinks/hourly_file_sink.h |  196 +
 .../1.10.0/include/spdlog/sinks/mongo_sink.h       |   99 +
 .../spdlog/1.10.0/include/spdlog/sinks/msvc_sink.h |   52 +
 .../spdlog/1.10.0/include/spdlog/sinks/null_sink.h |   44 +
 .../1.10.0/include/spdlog/sinks/ostream_sink.h     |   50 +
 .../spdlog/1.10.0/include/spdlog/sinks/qt_sinks.h  |  102 +
 .../1.10.0/include/spdlog/sinks/ringbuffer_sink.h  |   78 +
 .../include/spdlog/sinks/rotating_file_sink-inl.h  |  152 +
 .../include/spdlog/sinks/rotating_file_sink.h      |   81 +
 .../spdlog/1.10.0/include/spdlog/sinks/sink-inl.h  |   25 +
 .../spdlog/1.10.0/include/spdlog/sinks/sink.h      |   35 +
 .../include/spdlog/sinks/stdout_color_sinks-inl.h  |   38 +
 .../include/spdlog/sinks/stdout_color_sinks.h      |   45 +
 .../1.10.0/include/spdlog/sinks/stdout_sinks-inl.h |  139 +
 .../1.10.0/include/spdlog/sinks/stdout_sinks.h     |   87 +
 .../1.10.0/include/spdlog/sinks/syslog_sink.h      |  109 +
 .../1.10.0/include/spdlog/sinks/systemd_sink.h     |  119 +
 .../spdlog/1.10.0/include/spdlog/sinks/tcp_sink.h  |   81 +
 .../spdlog/1.10.0/include/spdlog/sinks/udp_sink.h  |   74 +
 .../include/spdlog/sinks/win_eventlog_sink.h       |  289 +
 .../include/spdlog/sinks/wincolor_sink-inl.h       |  175 +
 .../1.10.0/include/spdlog/sinks/wincolor_sink.h    |   85 +
 .../spdlog/1.10.0/include/spdlog/spdlog-inl.h      |  125 +
 .../spdlog/1.10.0/include/spdlog/spdlog.h          |  345 ++
 .../spdlog/1.10.0/include/spdlog/stopwatch.h       |   68 +
 .../spdlog/1.10.0/include/spdlog/tweakme.h         |  134 +
 .../spdlog/1.10.0/include/spdlog/version.h         |   10 +
 1028 files changed, 218036 insertions(+), 827 deletions(-)

diff --git a/.github/workflows/cpp_build.yml b/.github/workflows/cpp_build.yml
index aff8315..fbf4e7f 100644
--- a/.github/workflows/cpp_build.yml
+++ b/.github/workflows/cpp_build.yml
@@ -16,7 +16,7 @@ jobs:
       - uses: actions/checkout@v2
       - name: Compile All Targets
         working-directory: ./cpp
-        run: bazel build //...
+        run: bazel build //source/... //examples/...
       - name: Execute Unit Tests
         working-directory: ./cpp
-        run: bazel test //...
+        run: bazel test //source/...
diff --git a/.licenserc.yaml b/.licenserc.yaml
index ad8ecbf..62f7859 100644
--- a/.licenserc.yaml
+++ b/.licenserc.yaml
@@ -45,5 +45,7 @@ header:
     - 'cpp/.clang-tidy'
     - 'cpp/WORKSPACE'
     - 'cpp/.gitignore'
+    - 'cpp/third_party'
+    - 'cpp/cmake'
 
   comment: on-failure
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
new file mode 100644
index 0000000..031130c
--- /dev/null
+++ b/cpp/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.19)
+project(rocketmq)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+set(gRPC_DEBUG ON)
+
+# Assume gRPC is installed $HOME/grpc
+list(APPEND CMAKE_PREFIX_PATH $ENV{HOME}/grpc)
+
+list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
+find_package(protobuf CONFIG REQUIRED)
+find_package(gRPC CONFIG REQUIRED)
+find_package(absl REQUIRED)
+find_package(OpenSSL REQUIRED)
+
+add_subdirectory(proto)
+
+add_library(api INTERFACE)
+target_include_directories(api INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+add_subdirectory(third_party)
+
+add_subdirectory(source)
+
+option(BUILD_EXAMPLES "Build example programs or not" ON)
+if (BUILD_EXAMPLES)
+    message("Would build examples")
+    # Assume gflags is install in $HOME/gflags
+    list(APPEND CMAKE_PREFIX_PATH $ENV{HOME}/gflags)
+    find_package(gflags REQUIRED)
+    add_subdirectory(examples)
+endif ()
\ No newline at end of file
diff --git a/cpp/bazel/rocketmq_deps.bzl b/cpp/bazel/rocketmq_deps.bzl
index 9306f94..eae31a6 100644
--- a/cpp/bazel/rocketmq_deps.bzl
+++ b/cpp/bazel/rocketmq_deps.bzl
@@ -1,4 +1,5 @@
 """Load dependencies needed to compile and test the RocketMQ library as a 3rd-party consumer."""
+
 load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 
@@ -8,15 +9,15 @@ def rocketmq_deps():
         name = "opentelementry_api",
         actual = "@com_github_opentelemetry//api:api",
     )
-    
+
     maybe(
         http_archive,
         name = "com_google_googletest",
         sha256 = "b4870bf121ff7795ba20d20bcdd8627b8e088f2d1dab299a031c1034eddc93d5",
         strip_prefix = "googletest-release-1.11.0",
         urls = [
-        "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/googletest/googletest-release-1.11.0.tar.gz",
-        "https://github.com/google/googletest/archive/refs/tags/release-1.11.0.tar.gz",
+            "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/googletest/googletest-release-1.11.0.tar.gz",
+            "https://github.com/google/googletest/archive/refs/tags/release-1.11.0.tar.gz",
         ],
     )
 
@@ -74,7 +75,7 @@ def rocketmq_deps():
         strip_prefix = "rules_proto_grpc-4.1.1",
         urls = [
             "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/rules_proto_grpc/rules_proto_grpc-4.1.1.tar.gz",
-            "https://github.com/rules-proto-grpc/rules_proto_grpc/archive/refs/tags/4.1.1.tar.gz"
+            "https://github.com/rules-proto-grpc/rules_proto_grpc/archive/refs/tags/4.1.1.tar.gz",
         ],
     )
 
@@ -108,7 +109,7 @@ def rocketmq_deps():
         urls = [
             "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/gflags/gflags-2.2.2.tar.gz",
             "https://github.com/gflags/gflags/archive/refs/tags/v2.2.2.tar.gz",
-        ]
+        ],
     )
 
     maybe(
@@ -140,7 +141,7 @@ def rocketmq_deps():
         sha256 = "e89f15d54b0ddab0cd41d18cb2299e5447db704e2b05ff141cb1769170671466",
         urls = [
             "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/googleapis/googleapis-af7fb72df59a814221b123a4d1acb3f6c3e6cc95.zip",
-            "https://github.com/googleapis/googleapis/archive/af7fb72df59a814221b123a4d1acb3f6c3e6cc95.zip"
+            "https://github.com/googleapis/googleapis/archive/af7fb72df59a814221b123a4d1acb3f6c3e6cc95.zip",
         ],
         strip_prefix = "googleapis-af7fb72df59a814221b123a4d1acb3f6c3e6cc95",
     )
@@ -186,4 +187,4 @@ def rocketmq_deps():
             "https://shutian.oss-cn-hangzhou.aliyuncs.com/cdn/rules_proto/rules_proto-4.0.0-3.20.0.tar.gz",
             "https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0-3.20.0.tar.gz",
         ],
-    )
\ No newline at end of file
+    )
diff --git a/cpp/cmake/FindProtobufWithTargets.cmake b/cpp/cmake/FindProtobufWithTargets.cmake
new file mode 100644
index 0000000..e96bc6c
--- /dev/null
+++ b/cpp/cmake/FindProtobufWithTargets.cmake
@@ -0,0 +1,203 @@
+# ~~~
+# Copyright 2019 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ~~~
+
+#[=======================================================================[.rst:
+FindProtobufWithTargets
+-------------------
+
+A module to use ``Protobuf`` with less complications.
+
+Using ``find_package(Protobuf)`` should be simple, but it is not.
+
+CMake provides a ``FindProtobuf`` module. Unfortunately it does not generate
+``protobuf::*`` targets until CMake-3.9, and ``protobuf::protoc`` does not
+appear until CMake-3.10.
+
+The CMake-config files generated by ``protobuf`` always create these targets,
+but on some Linux distributions (e.g. Fedora>=29, and openSUSE-Tumbleweed) there
+are system packages for protobuf, but these packages are installed without the
+CMake-config files. One must either use the ``FindProtobuf`` module, find the
+libraries via ``pkg-config``, or find the libraries manually.
+
+When the CMake-config files are installed they produce the same targets as
+recent versions of ``FindProtobuf``. However, they do not produce the
+``Protobuf_LIBRARY``, ``Protobuf_INCLUDE_DIR``, etc. that are generated by the
+module. Furthermore, the ``protobuf::protoc`` library is not usable when loaded
+from the CMake-config files: its ``IMPORTED_LOCATION`` variable is not defined.
+
+This module is designed to provide a single, uniform, ``find_package()``
+module that always produces the same outputs:
+
+- It always generates the ``protobuf::*`` targets.
+- It always defines ``ProtobufWithTargets_FOUND`` and
+  ``ProtobufWithTargets_VERSION``.
+- It *prefers* using the CMake config files if they are available.
+- It fallsback on the ``FindProtobuf`` module if the config files are not found.
+- It populates any missing targets and their properties.
+
+The following ``IMPORTED`` targets are defined:
+
+``protobuf::libprotobuf``
+  The protobuf library.
+``protobuf::libprotobuf-lite``
+  The protobuf lite library.
+``protobuf::libprotoc``
+  The protoc library.
+``protobuf::protoc``
+  The protoc compiler.
+
+Example:
+
+.. code-block:: cmake
+
+  find_package(ProtobufWithTargets REQUIRED)
+  add_executable(bar bar.cc)
+  target_link_libraries(bar PRIVATE protobuf::libprotobuf)
+
+#]=======================================================================]
+
+if (protobuf_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "protobuf_USE_STATIC_LIBS = ${protobuf_USE_STATIC_LIBS}"
+                   " ProtobufWithTargets = ${ProtobufWithTargets_FOUND}")
+endif ()
+
+# Always load thread support, even on Windows.
+find_package(Threads REQUIRED)
+
+# First try to use the ``protobufConfig.cmake`` or ``protobuf-config.cmake``
+# file if it was installed. This is common on systems (or package managers)
+# where protobuf was compiled and installed with `CMake`. Note that on Linux
+# this *must* be all lowercase ``protobuf``, while on Windows it does not
+# matter.
+find_package(Protobuf CONFIG QUIET)
+
+if (protobuf_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "Protobuf_FOUND = ${Protobuf_FOUND}"
+                   " Protobuf_VERSION = ${Protobuf_VERSION}")
+endif ()
+
+if (NOT Protobuf_FOUND)
+    find_package(Protobuf QUIET)
+endif ()
+
+if (Protobuf_FOUND)
+    set(ProtobufWithTargets_FOUND 1)
+    set(ProtobufWithTargets_VERSION ${Protobuf_VERSION})
+
+    if (NOT TARGET protobuf::libprotobuf)
+        add_library(protobuf::libprotobuf INTERFACE IMPORTED)
+        set_property(
+            TARGET protobuf::libprotobuf PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+                                                  ${Protobuf_INCLUDE_DIR})
+        set_property(
+            TARGET protobuf::libprotobuf
+            APPEND
+            PROPERTY INTERFACE_LINK_LIBRARIES ${Protobuf_LIBRARY}
+                     Threads::Threads)
+    endif ()
+
+    if (NOT TARGET protobuf::libprotobuf-lite)
+        add_library(protobuf::libprotobuf-lite INTERFACE IMPORTED)
+        set_property(
+            TARGET protobuf::libprotobuf-lite
+            PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Protobuf_INCLUDE_DIR})
+        set_property(
+            TARGET protobuf::libprotobuf-lite
+            APPEND
+            PROPERTY INTERFACE_LINK_LIBRARIES ${Protobuf_LITE_LIBRARY}
+                     Threads::Threads)
+    endif ()
+
+    if (NOT TARGET protobuf::libprotoc)
+        add_library(protobuf::libprotoc INTERFACE IMPORTED)
+        set_property(
+            TARGET protobuf::libprotoc PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+                                                ${Protobuf_INCLUDE_DIR})
+        set_property(
+            TARGET protobuf::libprotoc
+            APPEND
+            PROPERTY INTERFACE_LINK_LIBRARIES ${Protobuf_PROTOC_LIBRARY}
+                     Threads::Threads)
+    endif ()
+
+    if (NOT TARGET protobuf::protoc)
+        add_executable(protobuf::protoc IMPORTED)
+
+        # Discover the protoc compiler location.
+        find_program(
+            _protobuf_PROTOC_EXECUTABLE
+            NAMES protoc
+            DOC "The Google Protocol Buffers Compiler")
+        if (protobuf_DEBUG)
+            message(
+                STATUS
+                    "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                    "ProtobufWithTargets_FOUND = ${ProtobufWithTargets_FOUND}"
+                    " ProtobufWithTargets_VERSION = ${ProtobufWithTargets_VERSION}"
+                    " EXE = ${_protobuf_PROTOC_EXECUTABLE}")
+        endif ()
+        set_property(TARGET protobuf::protoc
+                     PROPERTY IMPORTED_LOCATION ${_protobuf_PROTOC_EXECUTABLE})
+        set_property(
+            TARGET protobuf::protoc PROPERTY IMPORTED_LOCATION_DEBUG
+                                             ${_protobuf_PROTOC_EXECUTABLE})
+        set_property(
+            TARGET protobuf::protoc PROPERTY IMPORTED_LOCATION_RELEASE
+                                             ${_protobuf_PROTOC_EXECUTABLE})
+        unset(_protobuf_PROTOC_EXECUTABLE)
+
+        if (protobuf_DEBUG)
+            get_target_property(_protobuf_PROTOC_EXECUTABLE protobuf::protoc
+                                IMPORTED_LOCATION)
+            message(
+                STATUS
+                    "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                    "LOCATION=${_protobuf_PROTOC_EXECUTABLE}")
+        endif ()
+    endif ()
+endif ()
+
+if (protobuf_DEBUG)
+    message(
+        STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+               "ProtobufWithTargets_FOUND = ${ProtobufWithTargets_FOUND}"
+               " ProtobufWithTargets_VERSION = ${ProtobufWithTargets_VERSION}")
+endif ()
+
+if (protobuf_DEBUG)
+    message(
+        STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+               "ProtobufWithTargets_FOUND = ${ProtobufWithTargets_FOUND}"
+               " ProtobufWithTargets_VERSION = ${ProtobufWithTargets_VERSION}")
+    if (ProtobufWithTargets_FOUND)
+        foreach (_target protobuf::libprotobuf protobuf::libprotobuf-lite
+                         protobuf::libprotoc)
+            if (NOT TARGET ${_target})
+                message(
+                    STATUS
+                        "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                        "target=${_target} is NOT a target")
+            endif ()
+        endforeach ()
+        unset(_target)
+    endif ()
+endif ()
+
+find_package_handle_standard_args(
+    ProtobufWithTargets REQUIRED_VARS ProtobufWithTargets_FOUND
+                                      ProtobufWithTargets_VERSION)
diff --git a/cpp/cmake/FindgRPC.cmake b/cpp/cmake/FindgRPC.cmake
new file mode 100644
index 0000000..7ca10ae
--- /dev/null
+++ b/cpp/cmake/FindgRPC.cmake
@@ -0,0 +1,357 @@
+# ~~~
+# Copyright 2019 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ~~~
+
+#[=======================================================================[.rst:
+FindgRPC
+--------
+
+Locate and configure the ``gRPC`` library.
+
+The following variables can be set and are optional:
+
+``gRPC_DEBUG``
+  Show debug messages.
+``gRPC_USE_STATIC_LIBS``
+  Set to ON to force the use of the static libraries.
+  Default is OFF.
+
+Defines the following variables:
+
+``gRPC_FOUND``
+  Found the gRPC library
+``gRPC_VERSION``
+  Version of package found.
+
+The following ``IMPORTED`` targets are also defined:
+
+``gRPC::grpc++``
+  The gRPC C++ library.
+``gRPC::grpc``
+  The gRPC C core library.
+``gRPC::cpp_plugin``
+  The C++ plugin for the Protobuf protoc compiler.
+
+The following cache variables are also available to set or use:
+
+Example:
+
+.. code-block:: cmake
+
+  find_package(gRPC REQUIRED)
+  add_executable(bar bar.cc)
+  target_link_libraries(bar PRIVATE gRPC::grpc++)
+
+#]=======================================================================]
+
+if (gRPC_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "gRPC_USE_STATIC_LIBS = ${gRPC_USE_STATIC_LIBS}"
+                   " gRPC_FOUND = ${gRPC_FOUND}")
+endif ()
+
+# gRPC always requires Thread support.
+find_package(Threads REQUIRED)
+
+# Load the module to find protobuf with proper targets. Do not use
+# `find_package()` because we (have to) install this module in non-standard
+# locations.
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
+find_package(ProtobufWithTargets)
+
+# The gRPC::grpc_cpp_plugin target is sometimes defined, but without a
+# IMPORTED_LOCATION
+function (_grpc_fix_grpc_cpp_plugin_target)
+    # The target may already exist, do not create it again if it does.
+    if (NOT TARGET gRPC::grpc_cpp_plugin)
+        add_executable(gRPC::grpc_cpp_plugin IMPORTED)
+    endif ()
+    get_target_property(_gRPC_CPP_PLUGIN_EXECUTABLE gRPC::grpc_cpp_plugin
+                        IMPORTED_LOCATION)
+    if (gRPC_DEBUG)
+        message(
+            STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "LOCATION=${_gRPC_CPP_PLUGIN_EXECUTABLE}")
+    endif ()
+    # Even if the target exists, gRPC CMake support files do not define the
+    # executable for the imported target (at least they do not in v1.19.1), so
+    # we need to define it ourselves.
+    if (NOT _gRPC_CPP_PLUGIN_EXECUTABLE)
+        find_program(_gRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin
+                     DOC "The gRPC C++ plugin for protoc")
+        mark_as_advanced(_gRPC_CPP_PLUGIN_EXECUTABLE)
+        if (_gRPC_CPP_PLUGIN_EXECUTABLE)
+            set_property(
+                TARGET gRPC::grpc_cpp_plugin
+                PROPERTY IMPORTED_LOCATION ${_gRPC_CPP_PLUGIN_EXECUTABLE})
+        else ()
+            set(gRPC_FOUND "grpc_cpp_plugin-NOTFOUND")
+        endif ()
+    endif ()
+endfunction ()
+
+# The gRPC::* targets sometimes lack the right definitions to compile cleanly on
+# WIN32
+function (_grpc_fix_grpc_target_definitions)
+    # Including gRPC headers without this definition results in a build error.
+    if (WIN32)
+        set_property(
+            TARGET gRPC::grpc
+            APPEND
+            PROPERTY INTERFACE_COMPILE_DEFINITIONS _WIN32_WINNT=0x600)
+        set_property(
+            TARGET gRPC::grpc++
+            APPEND
+            PROPERTY INTERFACE_COMPILE_DEFINITIONS _WIN32_WINNT=0x600)
+    endif ()
+endfunction ()
+
+# First try to use the `gRPCConfig.cmake` or `grpc-config.cmake` file if it was
+# installed. This is common on systems (or package managers) where gRPC was
+# compiled and installed with `CMake`.
+
+find_package(gRPC NO_MODULE QUIET)
+
+if (gRPC_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "NO_MODULE result gRPC_FOUND = ${gRPC_FOUND}")
+endif ()
+
+if (gRPC_FOUND)
+    _grpc_fix_grpc_cpp_plugin_target()
+    _grpc_fix_grpc_target_definitions()
+    return()
+endif ()
+
+include(SelectLibraryConfigurations)
+
+# Internal function: search for normal library as well as a debug one if the
+# debug one is specified also include debug/optimized keywords in *_LIBRARIES
+# variable
+function (_gRPC_find_library name filename)
+    if (${name}_LIBRARY)
+        # Use result recorded by a previous call.
+        return()
+    else ()
+        find_library(${name}_LIBRARY_RELEASE NAMES ${filename})
+        mark_as_advanced(${name}_LIBRARY_RELEASE)
+
+        find_library(${name}_LIBRARY_DEBUG NAMES ${filename}d ${filename})
+        mark_as_advanced(${name}_LIBRARY_DEBUG)
+
+        select_library_configurations(${name})
+
+        if (gRPC_DEBUG)
+            message(
+                STATUS
+                    "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                    "${name} ${filename} RELEASE=${${name}_LIBRARY}"
+                    " DEBUG=${${name}_LIBRARY_DEBUG} DEFAULT=${${name}_LIBRARY}"
+            )
+        endif ()
+
+        set(${name}_LIBRARY
+            "${${name}_LIBRARY}"
+            PARENT_SCOPE)
+    endif ()
+endfunction ()
+
+#
+# Main
+#
+
+# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
+if (_gRPC_USE_STATIC_LIBS)
+    set(_gRPC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+    if (WIN32)
+        set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+    else ()
+        set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
+    endif ()
+endif ()
+
+_grpc_find_library(_gRPC_grpc grpc)
+_grpc_find_library(_gRPC_grpc++ grpc++)
+
+if (NOT _gRPC_INCLUDE_DIR)
+    find_path(_gRPC_INCLUDE_DIR grpcpp/grpcpp.h)
+    mark_as_advanced(_gRPC_INCLUDE_DIR)
+endif ()
+
+if (gRPC_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   " _gRPC_grpc_LIBRARY = ${_gRPC_grpc_LIBRARY}")
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   " _gRPC_grpc++_LIBRARY = ${_gRPC_grpc++_LIBRARY}")
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   " _gRPC_INCLUDE_DIR = ${_gRPC_INCLUDE_DIR}")
+endif ()
+
+if (_gRPC_grpc_LIBRARY)
+    if (NOT TARGET gRPC::grpc)
+        add_library(gRPC::grpc UNKNOWN IMPORTED)
+        set_target_properties(
+            gRPC::grpc PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
+                                  "${_gRPC_INCLUDE_DIR}")
+        if (EXISTS "${_gRPC_grpc_LIBRARY}")
+            set_target_properties(gRPC::grpc PROPERTIES IMPORTED_LOCATION
+                                                        "${_gRPC_grpc_LIBRARY}")
+        endif ()
+        if (EXISTS "${_gRPC_grpc_LIBRARY_RELEASE}")
+            set_property(
+                TARGET gRPC::grpc
+                APPEND
+                PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+            set_target_properties(
+                gRPC::grpc PROPERTIES IMPORTED_LOCATION_RELEASE
+                                      "${_gRPC_grpc_LIBRARY_RELEASE}")
+        endif ()
+        if (EXISTS "${_gRPC_grpc_LIBRARY_DEBUG}")
+            set_property(
+                TARGET gRPC::grpc
+                APPEND
+                PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+            set_target_properties(
+                gRPC::grpc PROPERTIES IMPORTED_LOCATION_DEBUG
+                                      "${_gRPC_grpc_LIBRARY_DEBUG}")
+        endif ()
+        set_property(
+            TARGET gRPC::grpc
+            APPEND
+            PROPERTY INTERFACE_LINK_LIBRARIES protobuf::libprotobuf
+                     Threads::Threads)
+    endif ()
+endif ()
+
+if (_gRPC_grpc++_LIBRARY)
+    if (NOT TARGET gRPC::grpc++)
+        add_library(gRPC::grpc++ UNKNOWN IMPORTED)
+        set_target_properties(
+            gRPC::grpc++ PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
+                                    "${_gRPC++_INCLUDE_DIR}")
+        if (EXISTS "${_gRPC_grpc++_LIBRARY}")
+            set_target_properties(
+                gRPC::grpc++ PROPERTIES IMPORTED_LOCATION
+                                        "${_gRPC_grpc++_LIBRARY}")
+        endif ()
+        if (EXISTS "${_gRPC_grpc++_LIBRARY_RELEASE}")
+            set_property(
+                TARGET gRPC::grpc++
+                APPEND
+                PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+            set_target_properties(
+                gRPC::grpc++ PROPERTIES IMPORTED_LOCATION_RELEASE
+                                        "${_gRPC_grpc++_LIBRARY_RELEASE}")
+        endif ()
+        if (EXISTS "${_gRPC_grpc++_LIBRARY_DEBUG}")
+            set_property(
+                TARGET gRPC::grpc++
+                APPEND
+                PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+            set_target_properties(
+                gRPC::grpc++ PROPERTIES IMPORTED_LOCATION_DEBUG
+                                        "${_gRPC_grpc++_LIBRARY_DEBUG}")
+        endif ()
+        set_property(
+            TARGET gRPC::grpc++
+            APPEND
+            PROPERTY INTERFACE_LINK_LIBRARIES gRPC::grpc protobuf::libprotobuf
+                     Threads::Threads)
+        if (CMAKE_VERSION VERSION_GREATER 3.8)
+            # gRPC++ requires C++14 (soon), but only CMake-3.8 introduced a
+            # compiler feature to meet that requirement.
+            set_property(
+                TARGET gRPC::grpc++
+                APPEND
+                PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_14)
+        elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+            # CMake 3.5 is still alive and kicking in some older distros, use
+            # the compiler-specific versions in these cases.
+            set_property(
+                TARGET gRPC::grpc++
+                APPEND
+                PROPERTY INTERFACE_COMPILE_OPTIONS "-std=c++14")
+        elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+            set_property(
+                TARGET gRPC::grpc++
+                APPEND
+                PROPERTY INTERFACE_COMPILE_OPTIONS "-std=c++14")
+        else ()
+            message(
+                WARNING
+                    "gRPC::grpc++ requires C++14, but this module"
+                    " (${CMAKE_CURRENT_LIST_FILE})"
+                    " cannot enable it for the library target in your CMake and"
+                    " compiler versions. You need to enable C++14 in the"
+                    " CMakeLists.txt for your project. Consider filing a bug"
+                    " so we can fix this problem.")
+        endif ()
+    endif ()
+endif ()
+
+# Restore original find library prefixes
+if (_gRPC_USE_STATIC_LIBS)
+    set(CMAKE_FIND_LIBRARY_PREFIXES "${_gRPC_ORIG_FIND_LIBRARY_PREFIXES}")
+endif ()
+
+file(
+    WRITE "${CMAKE_BINARY_DIR}/get_gRPC_version.cc"
+    [====[
+#include <grpcpp/grpcpp.h>
+#include <iostream>
+int main() {
+  std::cout << grpc::Version(); // no newline to simplify CMake module
+  return 0;
+}
+        ]====])
+
+try_run(
+    _gRPC_GET_VERSION_STATUS
+    _gRPC_GET_VERSION_COMPILE_STATUS
+    "${CMAKE_BINARY_DIR}"
+    "${CMAKE_BINARY_DIR}/get_gRPC_version.cc"
+    LINK_LIBRARIES
+    gRPC::grpc++
+    gRPC::grpc
+    COMPILE_OUTPUT_VARIABLE _gRPC_GET_VERSION_COMPILE_OUTPUT
+    RUN_OUTPUT_VARIABLE gRPC_VERSION)
+
+file(REMOVE "${CMAKE_BINARY_DIR}/get_gRPC_version.cc")
+
+_grpc_fix_grpc_cpp_plugin_target()
+
+if (gRPC_DEBUG)
+    foreach (
+        _var
+        _gRPC_CPP_PLUGIN_EXECUTABLE
+        _gRPC_VERSION_RAW
+        _gRPC_GET_VERSION_STATUS
+        _gRPC_GET_VERSION_COMPILE_STATUS
+        _gRPC_GET_VERSION_COMPILE_OUTPUT
+        _gRPC_grpc_LIBRARY
+        _gRPC_grpc++_LIBRARY
+        _gRPC_INCLUDE_DIR)
+        message(
+            STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "${_var} = ${${_var}}")
+    endforeach ()
+    unset(_var)
+endif ()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+    gRPC
+    REQUIRED_VARS _gRPC_grpc_LIBRARY _gRPC_INCLUDE_DIR
+    VERSION_VAR gRPC_VERSION)
diff --git a/cpp/cmake/OpenCensusHelpers.cmake b/cpp/cmake/OpenCensusHelpers.cmake
new file mode 100644
index 0000000..df894ea
--- /dev/null
+++ b/cpp/cmake/OpenCensusHelpers.cmake
@@ -0,0 +1,90 @@
+# Copyright 2018, OpenCensus Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Prepends opencensus_ to all deps that aren't in a :: namespace.
+function(prepend_opencensus OUT DEPS)
+  set(_DEPS "")
+  foreach(dep ${DEPS})
+    if("${dep}" MATCHES "::")
+      list(APPEND _DEPS "${dep}")
+    else()
+      list(APPEND _DEPS "opencensus_${dep}")
+    endif()
+  endforeach()
+  set(${OUT} ${_DEPS} PARENT_SCOPE)
+endfunction()
+
+# Helper function like bazel's cc_test. Usage:
+#
+# opencensus_test(trace_some_test internal/some_test.cc dep1 dep2...)
+function(opencensus_test NAME SRC)
+  if(BUILD_TESTING)
+    set(_NAME "opencensus_${NAME}")
+    add_executable(${_NAME} ${SRC})
+    prepend_opencensus(DEPS "${ARGN}")
+    target_link_libraries(${_NAME}
+                          "${DEPS}"
+                          gmock
+                          gtest_main)
+    add_test(NAME ${_NAME} COMMAND ${_NAME})
+  endif()
+endfunction()
+
+# Helper function like bazel's cc_benchmark. Usage:
+#
+# opencensus_benchmark(trace_some_benchmark internal/some_benchmark.cc dep1
+# dep2...)
+function(opencensus_benchmark NAME SRC)
+  if(BUILD_TESTING)
+    set(_NAME "opencensus_${NAME}")
+    add_executable(${_NAME} ${SRC})
+    prepend_opencensus(DEPS "${ARGN}")
+    target_link_libraries(${_NAME} "${DEPS}" benchmark)
+  endif()
+endfunction()
+
+# Helper function like bazel's cc_library.  Libraries are namespaced as
+# opencensus_* and public libraries are also aliased as opencensus-cpp::*.
+function(opencensus_lib NAME)
+  cmake_parse_arguments(ARG
+                        "PUBLIC"
+                        ""
+                        "SRCS;DEPS"
+                        ${ARGN})
+  set(_NAME "opencensus_${NAME}")
+  prepend_opencensus(ARG_DEPS "${ARG_DEPS}")
+  if(ARG_SRCS)
+    add_library(${_NAME} ${ARG_SRCS})
+    target_link_libraries(${_NAME} PUBLIC ${ARG_DEPS} opencensus_api)
+  else()
+    add_library(${_NAME} INTERFACE)
+    target_link_libraries(${_NAME} INTERFACE ${ARG_DEPS} opencensus_api)
+  endif()
+  if(ARG_PUBLIC)
+    add_library(opencensus::${NAME} ALIAS ${_NAME})
+  endif()
+endfunction()
+
+# Helper function for fuzzing. Usage:
+#
+# opencensus_fuzzer(trace_some_fuzzer internal/some_fuzzer.cc dep1 dep2...)
+function(opencensus_fuzzer NAME SRC)
+  if(FUZZER)
+    set(_NAME "opencensus_${NAME}")
+    add_executable(${_NAME} ${SRC})
+    prepend_opencensus(DEPS "${ARGN}")
+    target_link_libraries(${_NAME} "${DEPS}" ${FUZZER})
+    target_compile_options(${_NAME} PRIVATE ${FUZZER})
+  endif()
+endfunction()
diff --git a/cpp/examples/CMakeLists.txt b/cpp/examples/CMakeLists.txt
new file mode 100644
index 0000000..16e3ef3
--- /dev/null
+++ b/cpp/examples/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_executable(example_producer ExampleProducer.cpp)
+target_link_libraries(example_producer
+        PRIVATE
+            api
+            gflags
+            rocketmq)
\ No newline at end of file
diff --git a/cpp/proto/CMakeLists.txt b/cpp/proto/CMakeLists.txt
new file mode 100644
index 0000000..5af468c
--- /dev/null
+++ b/cpp/proto/CMakeLists.txt
@@ -0,0 +1,19 @@
+set(PROTO_FILES
+        apache/rocketmq/v2/admin.proto
+        apache/rocketmq/v2/definition.proto
+        apache/rocketmq/v2/service.proto)
+
+add_library(proto ${PROTO_FILES})
+target_link_libraries(proto
+        PUBLIC
+            protobuf::libprotobuf
+            gRPC::grpc
+            gRPC::grpc++)
+target_include_directories(proto PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
+
+#
+# Compile protobuf and grpc files in myproto target to cpp
+#
+get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION)
+protobuf_generate(TARGET proto LANGUAGE cpp)
+protobuf_generate(TARGET proto LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${grpc_cpp_plugin_location}")
\ No newline at end of file
diff --git a/cpp/source/CMakeLists.txt b/cpp/source/CMakeLists.txt
new file mode 100644
index 0000000..bb855b6
--- /dev/null
+++ b/cpp/source/CMakeLists.txt
@@ -0,0 +1,31 @@
+add_subdirectory(admin)
+add_subdirectory(base)
+add_subdirectory(client)
+add_subdirectory(concurrent)
+add_subdirectory(log)
+add_subdirectory(scheduler)
+add_subdirectory(stats)
+add_subdirectory(trace)
+add_subdirectory(rocketmq)
+
+add_library(rocketmq STATIC
+            $<TARGET_OBJECTS:admin>
+            $<TARGET_OBJECTS:base>
+            $<TARGET_OBJECTS:client>
+            $<TARGET_OBJECTS:concurrent>
+            $<TARGET_OBJECTS:log>
+            $<TARGET_OBJECTS:rocketmq_stats>
+            $<TARGET_OBJECTS:rocketmq_trace>
+            $<TARGET_OBJECTS:impl>
+            $<TARGET_OBJECTS:scheduler>)
+
+target_link_libraries(rocketmq
+        PUBLIC
+            absl::base
+            gRPC::grpc++
+            fmt
+            proto
+            opencensus::trace
+            opencensus::stats
+            opencensus_proto
+            spdlog)
\ No newline at end of file
diff --git a/cpp/source/admin/CMakeLists.txt b/cpp/source/admin/CMakeLists.txt
new file mode 100644
index 0000000..73ec877
--- /dev/null
+++ b/cpp/source/admin/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_library(admin
+        OBJECT
+            AdminFacade.cpp
+            AdminServerImpl.cpp
+            AdminServiceImpl.cpp)
+target_include_directories(admin
+        PRIVATE
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_link_libraries(admin
+        PRIVATE
+            api
+            proto
+            spdlog)
\ No newline at end of file
diff --git a/cpp/source/base/CMakeLists.txt b/cpp/source/base/CMakeLists.txt
new file mode 100644
index 0000000..124d942
--- /dev/null
+++ b/cpp/source/base/CMakeLists.txt
@@ -0,0 +1,15 @@
+file(GLOB SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
+add_library(base OBJECT ${SRC_FILES})
+target_include_directories(base
+        PUBLIC
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_link_libraries(base
+        PRIVATE
+            absl::flat_hash_map
+            api
+            asio
+            filesystem
+            fmt
+            OpenSSL::SSL
+            proto
+            spdlog)
\ No newline at end of file
diff --git a/cpp/source/base/MixAll.cpp b/cpp/source/base/MixAll.cpp
index 0514c71..676d048 100644
--- a/cpp/source/base/MixAll.cpp
+++ b/cpp/source/base/MixAll.cpp
@@ -21,7 +21,8 @@
 #include <cstdlib>
 #include <system_error>
 
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "absl/random/random.h"
 #include "absl/strings/str_split.h"
 #include "fmt/format.h"
diff --git a/cpp/source/base/UniqueIdGenerator.cpp b/cpp/source/base/UniqueIdGenerator.cpp
index aab5b14..16c30d9 100644
--- a/cpp/source/base/UniqueIdGenerator.cpp
+++ b/cpp/source/base/UniqueIdGenerator.cpp
@@ -15,11 +15,14 @@
  * limitations under the License.
  */
 #include "UniqueIdGenerator.h"
-#include "LoggerImpl.h"
+
+#include <cstring>
+
+#include "spdlog/spdlog.h"
 #include "MixAll.h"
 #include "UtilAll.h"
 #include "absl/base/internal/endian.h"
-#include <cstring>
+
 
 #ifdef _WIN32
 #include <process.h>
diff --git a/cpp/source/base/UtilAll.cpp b/cpp/source/base/UtilAll.cpp
index 892dc87..fc04559 100644
--- a/cpp/source/base/UtilAll.cpp
+++ b/cpp/source/base/UtilAll.cpp
@@ -16,7 +16,8 @@
  */
 #include "UtilAll.h"
 
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "zlib.h"
 #include <cstring>
 
diff --git a/cpp/source/base/include/InvocationContext.h b/cpp/source/base/include/InvocationContext.h
index 910a65d..0e138c8 100644
--- a/cpp/source/base/include/InvocationContext.h
+++ b/cpp/source/base/include/InvocationContext.h
@@ -27,7 +27,8 @@
 #include "grpcpp/impl/codegen/async_stream.h"
 #include "grpcpp/impl/codegen/async_unary_call.h"
 
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "MetadataConstants.h"
 #include "UniqueIdGenerator.h"
 
diff --git a/cpp/source/client/CMakeLists.txt b/cpp/source/client/CMakeLists.txt
new file mode 100644
index 0000000..7b06197
--- /dev/null
+++ b/cpp/source/client/CMakeLists.txt
@@ -0,0 +1,18 @@
+file(GLOB SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
+add_library(client OBJECT ${SRC_FILES})
+target_include_directories(client
+        PUBLIC
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_link_libraries(client
+        PRIVATE
+            api
+            asio
+            base
+            proto
+            fmt
+            gRPC::grpc
+            OpenSSL::SSL
+            opencensus::stats
+            opencensus::trace
+            scheduler
+            spdlog)
\ No newline at end of file
diff --git a/cpp/source/client/ClientManagerImpl.cpp b/cpp/source/client/ClientManagerImpl.cpp
index b3a4559..a39bb73 100644
--- a/cpp/source/client/ClientManagerImpl.cpp
+++ b/cpp/source/client/ClientManagerImpl.cpp
@@ -16,8 +16,6 @@
  */
 #include "ClientManagerImpl.h"
 
-#include <apache/rocketmq/v2/definition.pb.h>
-
 #include <atomic>
 #include <cassert>
 #include <chrono>
@@ -26,10 +24,12 @@
 #include <utility>
 #include <vector>
 
+#include "apache/rocketmq/v2/definition.pb.h"
 #include "InvocationContext.h"
 #include "LogInterceptor.h"
 #include "LogInterceptorFactory.h"
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "MessageExt.h"
 #include "MetadataConstants.h"
 #include "MixAll.h"
diff --git a/cpp/source/client/ReceiveMessageStreamReader.cpp b/cpp/source/client/ReceiveMessageStreamReader.cpp
index af99874..4eccb9f 100644
--- a/cpp/source/client/ReceiveMessageStreamReader.cpp
+++ b/cpp/source/client/ReceiveMessageStreamReader.cpp
@@ -17,9 +17,10 @@
 
 #include "ReceiveMessageStreamReader.h"
 
-#include <apache/rocketmq/v2/definition.pb.h>
+#include "apache/rocketmq/v2/definition.pb.h"
 
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "rocketmq/ErrorCode.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
diff --git a/cpp/source/client/SessionImpl.cpp b/cpp/source/client/SessionImpl.cpp
index 1ecf326..0ca3fff 100644
--- a/cpp/source/client/SessionImpl.cpp
+++ b/cpp/source/client/SessionImpl.cpp
@@ -16,7 +16,8 @@
  */
 
 #include "SessionImpl.h"
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
diff --git a/cpp/source/client/TelemetryBidiReactor.cpp b/cpp/source/client/TelemetryBidiReactor.cpp
index 995df3a..5120ad2 100644
--- a/cpp/source/client/TelemetryBidiReactor.cpp
+++ b/cpp/source/client/TelemetryBidiReactor.cpp
@@ -22,7 +22,8 @@
 #include <utility>
 
 #include "ClientManager.h"
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "MessageExt.h"
 #include "Metadata.h"
 #include "RpcClient.h"
diff --git a/cpp/source/client/TopicAssignmentInfo.cpp b/cpp/source/client/TopicAssignmentInfo.cpp
index 9ebd8e1..dd17aec 100644
--- a/cpp/source/client/TopicAssignmentInfo.cpp
+++ b/cpp/source/client/TopicAssignmentInfo.cpp
@@ -16,7 +16,8 @@
  */
 
 #include "TopicAssignmentInfo.h"
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
diff --git a/cpp/source/client/include/TopicAssignmentInfo.h b/cpp/source/client/include/TopicAssignmentInfo.h
index 76777a9..6df2592 100644
--- a/cpp/source/client/include/TopicAssignmentInfo.h
+++ b/cpp/source/client/include/TopicAssignmentInfo.h
@@ -16,11 +16,11 @@
  */
 #pragma once
 
-#include <apache/rocketmq/v2/definition.pb.h>
 #include <atomic>
 #include <vector>
 
 #include "Protocol.h"
+#include "apache/rocketmq/v2/definition.pb.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
diff --git a/cpp/source/concurrent/CMakeLists.txt b/cpp/source/concurrent/CMakeLists.txt
new file mode 100644
index 0000000..2d32336
--- /dev/null
+++ b/cpp/source/concurrent/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_library(concurrent OBJECT CountdownLatch.cpp)
+target_include_directories(concurrent
+        PRIVATE
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_link_libraries(concurrent
+        PRIVATE
+            absl::base
+            api
+            spdlog)
\ No newline at end of file
diff --git a/cpp/source/concurrent/CountdownLatch.cpp b/cpp/source/concurrent/CountdownLatch.cpp
index 363494e..3d3a651 100644
--- a/cpp/source/concurrent/CountdownLatch.cpp
+++ b/cpp/source/concurrent/CountdownLatch.cpp
@@ -15,7 +15,9 @@
  * limitations under the License.
  */
 #include "CountdownLatch.h"
-#include "LoggerImpl.h"
+
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
diff --git a/cpp/source/log/CMakeLists.txt b/cpp/source/log/CMakeLists.txt
new file mode 100644
index 0000000..cb3965e
--- /dev/null
+++ b/cpp/source/log/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(log
+        OBJECT
+            LoggerImpl.cpp)
+target_include_directories(log
+        PRIVATE
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_link_libraries(log
+        PRIVATE
+            api
+            filesystem
+            spdlog)
\ No newline at end of file
diff --git a/cpp/source/remoting/BUILD.bazel b/cpp/source/remoting/BUILD.bazel
deleted file mode 100644
index 6c070e8..0000000
--- a/cpp/source/remoting/BUILD.bazel
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-load("@rules_cc//cc:defs.bzl", "cc_library")
-package(default_visibility = ["//visibility:public"])
-
-cc_library(
-    name = "remoting",
-    hdrs = glob(["include/*.h"]),
-    srcs = glob(["*.cpp"]),
-    strip_include_prefix = "//source/remoting/include",
-    deps = [
-        "//include:rocketmq_interface",
-        "@asio//:asio",
-        "@com_google_protobuf//:protobuf",
-        "@com_google_absl//absl/memory",
-        "@com_google_absl//absl/container:flat_hash_map",
-    ]
-)
\ No newline at end of file
diff --git a/cpp/source/remoting/BrokerData.cpp b/cpp/source/remoting/BrokerData.cpp
deleted file mode 100644
index 51650ae..0000000
--- a/cpp/source/remoting/BrokerData.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "BrokerData.h"
-#include <string>
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-BrokerData BrokerData::decode(const google::protobuf::Struct& root) {
-  BrokerData broker_data;
-  auto fields = root.fields();
-  if (fields.contains("cluster")) {
-    broker_data.cluster_ = fields["cluster"].string_value();
-  }
-
-  if (fields.contains("brokerName")) {
-    broker_data.broker_name_ = fields["brokerName"].string_value();
-  }
-
-  if (fields.contains("brokerAddrs")) {
-    auto items = fields["brokerAddrs"].struct_value().fields();
-    for (const auto& item : items) {
-      auto k = std::stoll(item.first);
-      broker_data.broker_addresses_.insert({k, item.second.string_value()});
-    }
-  }
-  return broker_data;
-}
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/QueryRouteRequestHeader.cpp b/cpp/source/remoting/QueryRouteRequestHeader.cpp
deleted file mode 100644
index 551f3a2..0000000
--- a/cpp/source/remoting/QueryRouteRequestHeader.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "QueryRouteRequestHeader.h"
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-void QueryRouteRequestHeader::encode(google::protobuf::Value& root) const {
-  auto fields = root.mutable_struct_value()->mutable_fields();
-  google::protobuf::Value topic;
-  topic.set_string_value(topic_);
-  fields->insert({"topic", topic});
-}
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/QueueData.cpp b/cpp/source/remoting/QueueData.cpp
deleted file mode 100644
index 1a0796e..0000000
--- a/cpp/source/remoting/QueueData.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "QueueData.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-QueueData QueueData::decode(const google::protobuf::Struct& root) {
-  auto fields = root.fields();
-
-  QueueData queue_data;
-
-  if (fields.contains("brokerName")) {
-    queue_data.broker_name_ = fields["brokerName"].string_value();
-  }
-
-  if (fields.contains("readQueueNums")) {
-    queue_data.read_queue_number_ = fields["readQueueNums"].number_value();
-  }
-
-  if (fields.contains("writeQueueNums")) {
-    queue_data.write_queue_number_ = fields["writeQueueNums"].number_value();
-  }
-
-  if (fields.contains("perm")) {
-    queue_data.perm_ = fields["perm"].number_value();
-  }
-
-  if (fields.contains("topicSynFlag")) {
-    queue_data.topic_system_flag_ = fields["topicSynFlag"].number_value();
-  }
-
-  return queue_data;
-}
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/RemotingCommand.cpp b/cpp/source/remoting/RemotingCommand.cpp
deleted file mode 100644
index 743096a..0000000
--- a/cpp/source/remoting/RemotingCommand.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "RemotingCommand.h"
-
-#include <atomic>
-#include <cstdint>
-#include <memory>
-
-#include "LanguageCode.h"
-#include "absl/memory/memory.h"
-
-#include "QueryRouteRequestHeader.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-std::int32_t RemotingCommand::nextRequestId() {
-  static std::atomic_int32_t request_id{0};
-  return request_id.fetch_add(1, std::memory_order_relaxed);
-}
-
-RemotingCommand RemotingCommand::createRequest(RequestCode code, CommandCustomHeader* ext_fields) {
-  RemotingCommand command;
-  command.code_ = static_cast<std::int32_t>(code);
-  command.ext_fields_ = ext_fields;
-  return command;
-}
-
-RemotingCommand RemotingCommand::createResponse(ResponseCode code, CommandCustomHeader* ext_fields) {
-  RemotingCommand response;
-  response.code_ = static_cast<std::int32_t>(code);
-  response.ext_fields_ = ext_fields;
-  response.flag_ |= (1 << RPC_TYPE_RESPONSE);
-  return response;
-}
-
-void RemotingCommand::encodeHeader(google::protobuf::Value& root) {
-  auto fields = root.mutable_struct_value()->mutable_fields();
-
-  google::protobuf::Value code;
-  code.set_number_value(code_);
-  fields->insert({"code", code});
-
-  google::protobuf::Value language;
-  switch (language_) {
-    case LanguageCode::CPP: {
-      language.set_string_value("CPP");
-      break;
-    }
-    case LanguageCode::JAVA: {
-      language.set_string_value("JAVA");
-      break;
-    }
-    case LanguageCode::GO: {
-      language.set_string_value("GO");
-      break;
-    }
-    case LanguageCode::DOTNET: {
-      language.set_string_value("DOTNET");
-      break;
-    }
-    default: {
-      language.set_string_value("OTHER");
-      break;
-    }
-  }
-  fields->insert({"language", language});
-
-  if (version_) {
-    google::protobuf::Value version;
-    version.set_number_value(version_);
-    fields->insert({"version", version});
-  }
-
-  google::protobuf::Value opaque;
-  opaque.set_number_value(opaque_);
-  fields->insert({"opaque", opaque});
-
-  google::protobuf::Value flag;
-  flag.set_number_value(flag_);
-  fields->insert({"flag", flag});
-
-  if (!remark_.empty()) {
-    google::protobuf::Value remark;
-    remark.set_string_value(remark_);
-    fields->insert({"remark", remark});
-  }
-
-  if (ext_fields_) {
-    google::protobuf::Value ext_fields;
-    ext_fields_->encode(ext_fields);
-    fields->insert({"extFields", ext_fields});
-  }
-}
-
-const std::uint8_t RemotingCommand::RPC_TYPE_RESPONSE = 0;
-
-const std::uint8_t RemotingCommand::RPC_TYPE_ONE_WAY = 1;
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/TopicRouteData.cpp b/cpp/source/remoting/TopicRouteData.cpp
deleted file mode 100644
index 71a9f3c..0000000
--- a/cpp/source/remoting/TopicRouteData.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "TopicRouteData.h"
-#include "BrokerData.h"
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-TopicRouteData TopicRouteData::decode(const google::protobuf::Struct& root) {
-  auto fields = root.fields();
-
-  TopicRouteData topic_route_data;
-
-  if (fields.contains("queueDatas")) {
-    auto queue_data_list = fields.at("queueDatas");
-
-    for (auto& item : queue_data_list.list_value().values()) {
-      topic_route_data.queue_data_.push_back(QueueData::decode(item.struct_value()));
-    }
-  }
-
-  if (fields.contains("brokerDatas")) {
-    auto broker_data_list = fields.at("brokerDatas");
-    for (auto& item : broker_data_list.list_value().values()) {
-      topic_route_data.broker_data_.push_back(BrokerData::decode(item.struct_value()));
-    }
-  }
-
-  return topic_route_data;
-}
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/BrokerData.h b/cpp/source/remoting/include/BrokerData.h
deleted file mode 100644
index 83ef5fd..0000000
--- a/cpp/source/remoting/include/BrokerData.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <cstdint>
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "google/protobuf/struct.pb.h"
-#include "google/protobuf/util/json_util.h"
-
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-struct BrokerData {
-  std::string cluster_;
-  std::string broker_name_;
-  absl::flat_hash_map<std::int64_t, std::string> broker_addresses_;
-
-  static BrokerData decode(const google::protobuf::Struct& root);
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/CommandCustomHeader.h b/cpp/source/remoting/include/CommandCustomHeader.h
deleted file mode 100644
index a6afbc2..0000000
--- a/cpp/source/remoting/include/CommandCustomHeader.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include "google/protobuf/struct.pb.h"
-#include "google/protobuf/util/json_util.h"
-
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class CommandCustomHeader {
-public:
-  virtual ~CommandCustomHeader() = default;
-
-  virtual void encode(google::protobuf::Value& root) const = 0;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/LanguageCode.h b/cpp/source/remoting/include/LanguageCode.h
deleted file mode 100644
index 7151faf..0000000
--- a/cpp/source/remoting/include/LanguageCode.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <cstdint>
-
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-enum class LanguageCode : std::uint8_t
-{
-  JAVA = 0,
-  CPP = 1,
-  DOTNET = 2,
-  PYTHON = 3,
-  DELPHI = 4,
-  ERLANG = 5,
-  RUBY = 6,
-  OTHER = 7,
-  HTTP = 8,
-  GO = 9,
-  PHP = 10,
-  OMS = 11,
-};
-
-ROCKETMQ_NAMESPACE_END
diff --git a/cpp/source/remoting/include/QueryRouteRequestHeader.h b/cpp/source/remoting/include/QueryRouteRequestHeader.h
deleted file mode 100644
index b566969..0000000
--- a/cpp/source/remoting/include/QueryRouteRequestHeader.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-
-#include "CommandCustomHeader.h"
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-class QueryRouteRequestHeader : public CommandCustomHeader {
-public:
-  ~QueryRouteRequestHeader() override = default;
-
-  void topic(absl::string_view topic) {
-    topic_ = std::string(topic.data(), topic.length());
-  }
-
-  const std::string& topic() const {
-    return topic_;
-  }
-
-  void encode(google::protobuf::Value& root) const override;
-
-private:
-  std::string topic_;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/QueueData.h b/cpp/source/remoting/include/QueueData.h
deleted file mode 100644
index 9530cfc..0000000
--- a/cpp/source/remoting/include/QueueData.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <cstdint>
-#include <string>
-
-#include "google/protobuf/struct.pb.h"
-#include "google/protobuf/util/json_util.h"
-
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-struct QueueData {
-  std::string broker_name_;
-  std::int32_t read_queue_number_{0};
-  std::int32_t write_queue_number_{0};
-  std::uint32_t perm_{0};
-
-  /**
-   * @brief in Java, it's named "topicSynFlag"
-   *
-   */
-  std::uint32_t topic_system_flag_{0};
-
-  static QueueData decode(const google::protobuf::Struct& root);
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/RemotingCommand.h b/cpp/source/remoting/include/RemotingCommand.h
deleted file mode 100644
index 67e5ff4..0000000
--- a/cpp/source/remoting/include/RemotingCommand.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "CommandCustomHeader.h"
-#include "LanguageCode.h"
-#include "RequestCode.h"
-#include "ResponseCode.h"
-#include "Version.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-/**
- * RemotingCommand is non-copyable. It is movable.
- */
-class RemotingCommand {
-public:
-  RemotingCommand(const RemotingCommand&) = delete;
-
-  RemotingCommand(RemotingCommand&& rhs) noexcept {
-    code_ = rhs.code_;
-    language_ = rhs.language_;
-    version_ = rhs.version_;
-    opaque_ = rhs.opaque_;
-    remark_ = std::move(rhs.remark_);
-    body_ = std::move(rhs.body_);
-    ext_fields_ = rhs.ext_fields_;
-    rhs.ext_fields_ = nullptr;
-  }
-
-  RemotingCommand& operator=(const RemotingCommand&) = delete;
-
-  RemotingCommand& operator=(RemotingCommand&& rhs) noexcept {
-    if (this == &rhs) {
-      return *this;
-    }
-
-    code_ = rhs.code_;
-    language_ = rhs.language_;
-    version_ = rhs.version_;
-    opaque_ = rhs.opaque_;
-    remark_ = std::move(rhs.remark_);
-    body_ = std::move(rhs.body_);
-    ext_fields_ = rhs.ext_fields_;
-    rhs.ext_fields_ = nullptr;
-    return *this;
-  }
-
-  virtual ~RemotingCommand() {
-    delete ext_fields_;
-  }
-
-  static std::int32_t nextRequestId();
-
-  static RemotingCommand createRequest(RequestCode, CommandCustomHeader*);
-
-  static RemotingCommand createResponse(ResponseCode, CommandCustomHeader*);
-
-  virtual void encodeHeader(google::protobuf::Value& root);
-
-private:
-  RemotingCommand() = default;
-
-  std::int32_t code_{static_cast<std::int32_t>(RequestCode::QueryRoute)};
-  LanguageCode language_{LanguageCode::CPP};
-  std::int32_t version_{static_cast<std::int32_t>(Version::V4_9_1)};
-  std::int32_t opaque_{nextRequestId()};
-  std::uint32_t flag_{0};
-  std::string remark_;
-
-  CommandCustomHeader* ext_fields_{nullptr};
-
-  std::vector<std::uint8_t> body_;
-
-  /**
-   * Bit-field shift amount for flag_ field, indicating the RPC is a response from broker or name-server.
-   */
-  const static std::uint8_t RPC_TYPE_RESPONSE;
-
-  /**
-   * Bit-field shift amount for flag_ field. Request marked one-way should NOT expect a respose from broker or
-   * name-server.
-   */
-  const static std::uint8_t RPC_TYPE_ONE_WAY;
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/RemotingCommandType.h b/cpp/source/remoting/include/RemotingCommandType.h
deleted file mode 100644
index 9ca78d2..0000000
--- a/cpp/source/remoting/include/RemotingCommandType.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <cstdint>
-
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-enum class RemotingCommandType : std::uint8_t
-{
-  REQUEST = 0,
-  RESPONSE = 1,
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/RequestCode.h b/cpp/source/remoting/include/RequestCode.h
deleted file mode 100644
index cb28eaf..0000000
--- a/cpp/source/remoting/include/RequestCode.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <cstdint>
-
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-enum class RequestCode : std::int32_t
-{
-  SendMessage = 10,
-  PullMessage = 11,
-  QueryRoute = 105,
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/ResponseCode.h b/cpp/source/remoting/include/ResponseCode.h
deleted file mode 100644
index 4cfa924..0000000
--- a/cpp/source/remoting/include/ResponseCode.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <cstdint>
-
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-enum class ResponseCode : std::uint16_t
-{
-  Success = 0,
-  InternalSystemError = 1,
-  TooManyRequests = 2,
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/TopicRouteData.h b/cpp/source/remoting/include/TopicRouteData.h
deleted file mode 100644
index 2c044f8..0000000
--- a/cpp/source/remoting/include/TopicRouteData.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <vector>
-
-#include "BrokerData.h"
-#include "QueueData.h"
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-struct TopicRouteData {
-
-  /**
-   * @brief In Java, it's named "queueDatas"
-   *
-   */
-  std::vector<QueueData> queue_data_;
-
-  /**
-   * @brief In Java, it's named "brokerDatas"
-   *
-   */
-  std::vector<BrokerData> broker_data_;
-
-  static TopicRouteData decode(const google::protobuf::Struct& root);
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/remoting/include/Version.h b/cpp/source/remoting/include/Version.h
deleted file mode 100644
index 85fdc46..0000000
--- a/cpp/source/remoting/include/Version.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <cstdint>
-
-#include "rocketmq/RocketMQ.h"
-
-ROCKETMQ_NAMESPACE_BEGIN
-
-enum class Version : std::int32_t
-{
-  V4_9_1 = 396,
-  V4_9_2 = 398,
-};
-
-ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/rocketmq/AsyncReceiveMessageCallback.cpp b/cpp/source/rocketmq/AsyncReceiveMessageCallback.cpp
index 30cdb7a..1e03802 100644
--- a/cpp/source/rocketmq/AsyncReceiveMessageCallback.cpp
+++ b/cpp/source/rocketmq/AsyncReceiveMessageCallback.cpp
@@ -20,7 +20,8 @@
 
 #include "ClientManagerImpl.h"
 #include "ConsumeMessageType.h"
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "ProcessQueue.h"
 #include "PushConsumerImpl.h"
 
diff --git a/cpp/source/rocketmq/CMakeLists.txt b/cpp/source/rocketmq/CMakeLists.txt
new file mode 100644
index 0000000..843c6c8
--- /dev/null
+++ b/cpp/source/rocketmq/CMakeLists.txt
@@ -0,0 +1,22 @@
+file(GLOB SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
+
+add_library(impl OBJECT ${SRC_FILES})
+target_include_directories(impl
+        PRIVATE
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_link_libraries(impl
+        PRIVATE
+            api
+            absl::strings
+            asio
+            base
+            fmt
+            proto
+            client
+            opencensus_api
+            opencensus_proto
+            rocketmq_stats
+            rocketmq_trace
+            scheduler
+            spdlog
+        )
\ No newline at end of file
diff --git a/cpp/source/rocketmq/ClientImpl.cpp b/cpp/source/rocketmq/ClientImpl.cpp
index d47133a..0532d73 100644
--- a/cpp/source/rocketmq/ClientImpl.cpp
+++ b/cpp/source/rocketmq/ClientImpl.cpp
@@ -31,7 +31,8 @@
 
 #include "ClientManagerImpl.h"
 #include "InvocationContext.h"
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "MessageExt.h"
 #include "NamingScheme.h"
 #include "SessionImpl.h"
diff --git a/cpp/source/rocketmq/ConsumeMessageServiceImpl.cpp b/cpp/source/rocketmq/ConsumeMessageServiceImpl.cpp
index 722347e..11e14ce 100644
--- a/cpp/source/rocketmq/ConsumeMessageServiceImpl.cpp
+++ b/cpp/source/rocketmq/ConsumeMessageServiceImpl.cpp
@@ -18,7 +18,8 @@
 
 #include "ConsumeStats.h"
 #include "ConsumeTask.h"
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "PushConsumerImpl.h"
 #include "Tag.h"
 #include "ThreadPoolImpl.h"
diff --git a/cpp/source/rocketmq/ConsumeTask.cpp b/cpp/source/rocketmq/ConsumeTask.cpp
index 0c9802d..9e87828 100644
--- a/cpp/source/rocketmq/ConsumeTask.cpp
+++ b/cpp/source/rocketmq/ConsumeTask.cpp
@@ -18,7 +18,8 @@
 #include "ConsumeTask.h"
 
 #include "ConsumeStats.h"
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "PushConsumerImpl.h"
 #include "Tag.h"
 #include "rocketmq/ConsumeResult.h"
diff --git a/cpp/source/rocketmq/Producer.cpp b/cpp/source/rocketmq/Producer.cpp
index ce007bc..147fc8b 100644
--- a/cpp/source/rocketmq/Producer.cpp
+++ b/cpp/source/rocketmq/Producer.cpp
@@ -21,7 +21,8 @@
 #include <system_error>
 #include <utility>
 
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "MixAll.h"
 #include "ProducerImpl.h"
 #include "StaticNameServerResolver.h"
diff --git a/cpp/source/rocketmq/StaticNameServerResolver.cpp b/cpp/source/rocketmq/StaticNameServerResolver.cpp
index c7f0804..8f2d255 100644
--- a/cpp/source/rocketmq/StaticNameServerResolver.cpp
+++ b/cpp/source/rocketmq/StaticNameServerResolver.cpp
@@ -18,7 +18,8 @@
 
 #include "absl/strings/str_split.h"
 
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
diff --git a/cpp/source/rocketmq/TopicPublishInfo.cpp b/cpp/source/rocketmq/TopicPublishInfo.cpp
index 9eac1a2..6eeece4 100644
--- a/cpp/source/rocketmq/TopicPublishInfo.cpp
+++ b/cpp/source/rocketmq/TopicPublishInfo.cpp
@@ -19,7 +19,8 @@
 #include <memory>
 #include <utility>
 
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "MixAll.h"
 #include "ProducerImpl.h"
 #include "TopicRouteData.h"
diff --git a/cpp/source/rocketmq/include/ProcessQueueImpl.h b/cpp/source/rocketmq/include/ProcessQueueImpl.h
index 36464fc..822f7c0 100644
--- a/cpp/source/rocketmq/include/ProcessQueueImpl.h
+++ b/cpp/source/rocketmq/include/ProcessQueueImpl.h
@@ -30,7 +30,6 @@
 #include "TopicAssignmentInfo.h"
 #include "absl/container/flat_hash_map.h"
 #include "absl/container/flat_hash_set.h"
-#include "gtest/gtest_prod.h"
 #include "rocketmq/FilterExpression.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
@@ -133,8 +132,6 @@ private:
                              rmq::ReceiveMessageRequest& request);
 
   void wrapFilterExpression(rmq::FilterExpression* filter_expression);
-
-  FRIEND_TEST(ProcessQueueTest, testExpired);
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/scheduler/CMakeLists.txt b/cpp/source/scheduler/CMakeLists.txt
new file mode 100644
index 0000000..22eb435
--- /dev/null
+++ b/cpp/source/scheduler/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_library(scheduler OBJECT SchedulerImpl.cpp)
+target_include_directories(scheduler
+        PUBLIC
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_link_libraries(scheduler
+        PRIVATE
+            absl::base
+            api
+            asio
+            spdlog)
diff --git a/cpp/source/stats/CMakeLists.txt b/cpp/source/stats/CMakeLists.txt
new file mode 100644
index 0000000..15622ea
--- /dev/null
+++ b/cpp/source/stats/CMakeLists.txt
@@ -0,0 +1,17 @@
+file(GLOB SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
+
+add_library(rocketmq_stats OBJECT ${SRC_FILES})
+target_include_directories(rocketmq_stats
+        PUBLIC
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_link_libraries(rocketmq_stats
+        PRIVATE
+            api
+            base
+            client
+            fmt
+            opencensus::stats
+            opencensus_proto
+            proto
+            spdlog
+            scheduler)
\ No newline at end of file
diff --git a/cpp/source/stats/MetricBidiReactor.cpp b/cpp/source/stats/MetricBidiReactor.cpp
index 43e69ed..22363bd 100644
--- a/cpp/source/stats/MetricBidiReactor.cpp
+++ b/cpp/source/stats/MetricBidiReactor.cpp
@@ -18,7 +18,8 @@
 
 #include <chrono>
 
-#include "LoggerImpl.h"
+#include "rocketmq/Logger.h"
+#include "spdlog/spdlog.h"
 #include "OpencensusExporter.h"
 #include "Signature.h"
 
diff --git a/cpp/source/stats/StdoutHandler.cpp b/cpp/source/stats/StdoutHandler.cpp
index 9d18d78..3cc7538 100644
--- a/cpp/source/stats/StdoutHandler.cpp
+++ b/cpp/source/stats/StdoutHandler.cpp
@@ -26,14 +26,14 @@ void StdoutHandler::ExportViewData(
   for (const auto& datum : data) {
     const auto& view_data = datum.second;
     const auto& descriptor = datum.first;
-    auto start_times = view_data.start_times();
+    auto record_time = view_data.end_time();
     auto columns = descriptor.columns();
 
     switch (view_data.type()) {
       case opencensus::stats::ViewData::Type::kInt64: {
         auto data_map = view_data.int_data();
         for (const auto& entry : data_map) {
-          absl::Time time = start_times[entry.first];
+          absl::Time time = record_time;
           std::string line;
           line.append(absl::FormatTime(time)).append(" ");
           line.append(descriptor.name());
diff --git a/cpp/source/trace/CMakeLists.txt b/cpp/source/trace/CMakeLists.txt
new file mode 100644
index 0000000..caf1a1a
--- /dev/null
+++ b/cpp/source/trace/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_library(rocketmq_trace OBJECT TracingUtility.cpp)
+target_include_directories(rocketmq_trace
+        PUBLIC
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_link_libraries(rocketmq_trace
+        PRIVATE
+            api
+            base
+            client
+            fmt
+            opencensus::stats
+            proto
+            spdlog)
\ No newline at end of file
diff --git a/cpp/third_party/CMakeLists.txt b/cpp/third_party/CMakeLists.txt
new file mode 100644
index 0000000..e2ba5ac
--- /dev/null
+++ b/cpp/third_party/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_subdirectory(asio/1.18.2)
+add_subdirectory(filesystem/1.5.12)
+add_subdirectory(fmt/9.0.0)
+add_subdirectory(spdlog/1.10.0)
+
+include(OpenCensusHelpers)
+add_subdirectory(opencensus/0.5.0-alpha)
+add_subdirectory(opencensus/proto)
\ No newline at end of file
diff --git a/cpp/third_party/asio/1.18.2/CMakeLists.txt b/cpp/third_party/asio/1.18.2/CMakeLists.txt
new file mode 100644
index 0000000..cec071a
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_library(asio INTERFACE)
+target_include_directories(asio
+        INTERFACE
+            ${CMAKE_CURRENT_SOURCE_DIR}/include)
\ No newline at end of file
diff --git a/cpp/third_party/asio/1.18.2/include/Makefile.am b/cpp/third_party/asio/1.18.2/include/Makefile.am
new file mode 100644
index 0000000..5ff1d26
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/Makefile.am
@@ -0,0 +1,566 @@
+# find . -name "*.*pp" | sed -e 's/^\.\///' | sed -e 's/^.*$/  & \\/' | sort
+nobase_include_HEADERS = \
+	asio/any_io_executor.hpp \
+	asio/associated_allocator.hpp \
+	asio/associated_executor.hpp \
+	asio/async_result.hpp \
+	asio/awaitable.hpp \
+	asio/basic_datagram_socket.hpp \
+	asio/basic_deadline_timer.hpp \
+	asio/basic_io_object.hpp \
+	asio/basic_raw_socket.hpp \
+	asio/basic_seq_packet_socket.hpp \
+	asio/basic_serial_port.hpp \
+	asio/basic_signal_set.hpp \
+	asio/basic_socket_acceptor.hpp \
+	asio/basic_socket.hpp \
+	asio/basic_socket_iostream.hpp \
+	asio/basic_socket_streambuf.hpp \
+	asio/basic_streambuf_fwd.hpp \
+	asio/basic_streambuf.hpp \
+	asio/basic_stream_socket.hpp \
+	asio/basic_waitable_timer.hpp \
+	asio/bind_executor.hpp \
+	asio/buffered_read_stream_fwd.hpp \
+	asio/buffered_read_stream.hpp \
+	asio/buffered_stream_fwd.hpp \
+	asio/buffered_stream.hpp \
+	asio/buffered_write_stream_fwd.hpp \
+	asio/buffered_write_stream.hpp \
+	asio/buffer.hpp \
+	asio/buffers_iterator.hpp \
+	asio/co_spawn.hpp \
+	asio/completion_condition.hpp \
+	asio/compose.hpp \
+	asio/connect.hpp \
+	asio/coroutine.hpp \
+	asio/deadline_timer.hpp \
+	asio/defer.hpp \
+	asio/detached.hpp \
+	asio/detail/array_fwd.hpp \
+	asio/detail/array.hpp \
+	asio/detail/assert.hpp \
+	asio/detail/atomic_count.hpp \
+	asio/detail/base_from_completion_cond.hpp \
+	asio/detail/bind_handler.hpp \
+	asio/detail/blocking_executor_op.hpp \
+	asio/detail/buffered_stream_storage.hpp \
+	asio/detail/buffer_resize_guard.hpp \
+	asio/detail/buffer_sequence_adapter.hpp \
+	asio/detail/bulk_executor_op.hpp \
+	asio/detail/call_stack.hpp \
+	asio/detail/chrono.hpp \
+	asio/detail/chrono_time_traits.hpp \
+	asio/detail/completion_handler.hpp \
+	asio/detail/concurrency_hint.hpp \
+	asio/detail/conditionally_enabled_event.hpp \
+	asio/detail/conditionally_enabled_mutex.hpp \
+	asio/detail/config.hpp \
+	asio/detail/consuming_buffers.hpp \
+	asio/detail/cstddef.hpp \
+	asio/detail/cstdint.hpp \
+	asio/detail/date_time_fwd.hpp \
+	asio/detail/deadline_timer_service.hpp \
+	asio/detail/dependent_type.hpp \
+	asio/detail/descriptor_ops.hpp \
+	asio/detail/descriptor_read_op.hpp \
+	asio/detail/descriptor_write_op.hpp \
+	asio/detail/dev_poll_reactor.hpp \
+	asio/detail/epoll_reactor.hpp \
+	asio/detail/eventfd_select_interrupter.hpp \
+	asio/detail/event.hpp \
+	asio/detail/executor_function.hpp \
+	asio/detail/executor_op.hpp \
+	asio/detail/fd_set_adapter.hpp \
+	asio/detail/fenced_block.hpp \
+	asio/detail/functional.hpp \
+	asio/detail/future.hpp \
+	asio/detail/gcc_arm_fenced_block.hpp \
+	asio/detail/gcc_hppa_fenced_block.hpp \
+	asio/detail/gcc_sync_fenced_block.hpp \
+	asio/detail/gcc_x86_fenced_block.hpp \
+	asio/detail/global.hpp \
+	asio/detail/handler_alloc_helpers.hpp \
+	asio/detail/handler_cont_helpers.hpp \
+	asio/detail/handler_invoke_helpers.hpp \
+	asio/detail/handler_tracking.hpp \
+	asio/detail/handler_type_requirements.hpp \
+	asio/detail/handler_work.hpp \
+	asio/detail/hash_map.hpp \
+	asio/detail/impl/buffer_sequence_adapter.ipp \
+	asio/detail/impl/descriptor_ops.ipp \
+	asio/detail/impl/dev_poll_reactor.hpp \
+	asio/detail/impl/dev_poll_reactor.ipp \
+	asio/detail/impl/epoll_reactor.hpp \
+	asio/detail/impl/epoll_reactor.ipp \
+	asio/detail/impl/eventfd_select_interrupter.ipp \
+	asio/detail/impl/handler_tracking.ipp \
+	asio/detail/impl/kqueue_reactor.hpp \
+	asio/detail/impl/kqueue_reactor.ipp \
+	asio/detail/impl/null_event.ipp \
+	asio/detail/impl/pipe_select_interrupter.ipp \
+	asio/detail/impl/posix_event.ipp \
+	asio/detail/impl/posix_mutex.ipp \
+	asio/detail/impl/posix_thread.ipp \
+	asio/detail/impl/posix_tss_ptr.ipp \
+	asio/detail/impl/reactive_descriptor_service.ipp \
+	asio/detail/impl/reactive_serial_port_service.ipp \
+	asio/detail/impl/reactive_socket_service_base.ipp \
+	asio/detail/impl/resolver_service_base.ipp \
+	asio/detail/impl/scheduler.ipp \
+	asio/detail/impl/select_reactor.hpp \
+	asio/detail/impl/select_reactor.ipp \
+	asio/detail/impl/service_registry.hpp \
+	asio/detail/impl/service_registry.ipp \
+	asio/detail/impl/signal_set_service.ipp \
+	asio/detail/impl/socket_ops.ipp \
+	asio/detail/impl/socket_select_interrupter.ipp \
+	asio/detail/impl/strand_executor_service.hpp \
+	asio/detail/impl/strand_executor_service.ipp \
+	asio/detail/impl/strand_service.hpp \
+	asio/detail/impl/strand_service.ipp \
+	asio/detail/impl/thread_context.ipp \
+	asio/detail/impl/throw_error.ipp \
+	asio/detail/impl/timer_queue_ptime.ipp \
+	asio/detail/impl/timer_queue_set.ipp \
+	asio/detail/impl/win_event.ipp \
+	asio/detail/impl/win_iocp_handle_service.ipp \
+	asio/detail/impl/win_iocp_io_context.hpp \
+	asio/detail/impl/win_iocp_io_context.ipp \
+	asio/detail/impl/win_iocp_serial_port_service.ipp \
+	asio/detail/impl/win_iocp_socket_service_base.ipp \
+	asio/detail/impl/win_mutex.ipp \
+	asio/detail/impl/win_object_handle_service.ipp \
+	asio/detail/impl/winrt_ssocket_service_base.ipp \
+	asio/detail/impl/winrt_timer_scheduler.hpp \
+	asio/detail/impl/winrt_timer_scheduler.ipp \
+	asio/detail/impl/winsock_init.ipp \
+	asio/detail/impl/win_static_mutex.ipp \
+	asio/detail/impl/win_thread.ipp \
+	asio/detail/impl/win_tss_ptr.ipp \
+	asio/detail/io_control.hpp \
+	asio/detail/io_object_impl.hpp \
+	asio/detail/is_buffer_sequence.hpp \
+	asio/detail/is_executor.hpp \
+	asio/detail/keyword_tss_ptr.hpp \
+	asio/detail/kqueue_reactor.hpp \
+	asio/detail/limits.hpp \
+	asio/detail/local_free_on_block_exit.hpp \
+	asio/detail/macos_fenced_block.hpp \
+	asio/detail/memory.hpp \
+	asio/detail/mutex.hpp \
+	asio/detail/non_const_lvalue.hpp \
+	asio/detail/noncopyable.hpp \
+	asio/detail/null_event.hpp \
+	asio/detail/null_fenced_block.hpp \
+	asio/detail/null_global.hpp \
+	asio/detail/null_mutex.hpp \
+	asio/detail/null_reactor.hpp \
+	asio/detail/null_signal_blocker.hpp \
+	asio/detail/null_socket_service.hpp \
+	asio/detail/null_static_mutex.hpp \
+	asio/detail/null_thread.hpp \
+	asio/detail/null_tss_ptr.hpp \
+	asio/detail/object_pool.hpp \
+	asio/detail/old_win_sdk_compat.hpp \
+	asio/detail/operation.hpp \
+	asio/detail/op_queue.hpp \
+	asio/detail/pipe_select_interrupter.hpp \
+	asio/detail/pop_options.hpp \
+	asio/detail/posix_event.hpp \
+	asio/detail/posix_fd_set_adapter.hpp \
+	asio/detail/posix_global.hpp \
+	asio/detail/posix_mutex.hpp \
+	asio/detail/posix_signal_blocker.hpp \
+	asio/detail/posix_static_mutex.hpp \
+	asio/detail/posix_thread.hpp \
+	asio/detail/posix_tss_ptr.hpp \
+	asio/detail/push_options.hpp \
+	asio/detail/reactive_descriptor_service.hpp \
+	asio/detail/reactive_null_buffers_op.hpp \
+	asio/detail/reactive_serial_port_service.hpp \
+	asio/detail/reactive_socket_accept_op.hpp \
+	asio/detail/reactive_socket_connect_op.hpp \
+	asio/detail/reactive_socket_recvfrom_op.hpp \
+	asio/detail/reactive_socket_recvmsg_op.hpp \
+	asio/detail/reactive_socket_recv_op.hpp \
+	asio/detail/reactive_socket_send_op.hpp \
+	asio/detail/reactive_socket_sendto_op.hpp \
+	asio/detail/reactive_socket_service_base.hpp \
+	asio/detail/reactive_socket_service.hpp \
+	asio/detail/reactive_wait_op.hpp \
+	asio/detail/reactor_fwd.hpp \
+	asio/detail/reactor.hpp \
+	asio/detail/reactor_op.hpp \
+	asio/detail/reactor_op_queue.hpp \
+	asio/detail/recycling_allocator.hpp \
+	asio/detail/regex_fwd.hpp \
+	asio/detail/resolve_endpoint_op.hpp \
+	asio/detail/resolve_op.hpp \
+	asio/detail/resolve_query_op.hpp \
+	asio/detail/resolver_service_base.hpp \
+	asio/detail/resolver_service.hpp \
+	asio/detail/scheduler.hpp \
+	asio/detail/scheduler_operation.hpp \
+	asio/detail/scheduler_thread_info.hpp \
+	asio/detail/scoped_lock.hpp \
+	asio/detail/scoped_ptr.hpp \
+	asio/detail/select_interrupter.hpp \
+	asio/detail/select_reactor.hpp \
+	asio/detail/service_registry.hpp \
+	asio/detail/signal_blocker.hpp \
+	asio/detail/signal_handler.hpp \
+	asio/detail/signal_init.hpp \
+	asio/detail/signal_op.hpp \
+	asio/detail/signal_set_service.hpp \
+	asio/detail/socket_holder.hpp \
+	asio/detail/socket_ops.hpp \
+	asio/detail/socket_option.hpp \
+	asio/detail/socket_select_interrupter.hpp \
+	asio/detail/socket_types.hpp \
+	asio/detail/solaris_fenced_block.hpp \
+	asio/detail/source_location.hpp \
+	asio/detail/static_mutex.hpp \
+	asio/detail/std_event.hpp \
+	asio/detail/std_fenced_block.hpp \
+	asio/detail/std_global.hpp \
+	asio/detail/std_mutex.hpp \
+	asio/detail/std_static_mutex.hpp \
+	asio/detail/std_thread.hpp \
+	asio/detail/strand_executor_service.hpp \
+	asio/detail/strand_service.hpp \
+	asio/detail/string_view.hpp \
+	asio/detail/thread_context.hpp \
+	asio/detail/thread_group.hpp \
+	asio/detail/thread.hpp \
+	asio/detail/thread_info_base.hpp \
+	asio/detail/throw_error.hpp \
+	asio/detail/throw_exception.hpp \
+	asio/detail/timer_queue_base.hpp \
+	asio/detail/timer_queue.hpp \
+	asio/detail/timer_queue_ptime.hpp \
+	asio/detail/timer_queue_set.hpp \
+	asio/detail/timer_scheduler_fwd.hpp \
+	asio/detail/timer_scheduler.hpp \
+	asio/detail/tss_ptr.hpp \
+	asio/detail/type_traits.hpp \
+	asio/detail/variadic_templates.hpp \
+	asio/detail/wait_handler.hpp \
+	asio/detail/wait_op.hpp \
+	asio/detail/winapp_thread.hpp \
+	asio/detail/wince_thread.hpp \
+	asio/detail/win_event.hpp \
+	asio/detail/win_fd_set_adapter.hpp \
+	asio/detail/win_fenced_block.hpp \
+	asio/detail/win_global.hpp \
+	asio/detail/win_iocp_handle_read_op.hpp \
+	asio/detail/win_iocp_handle_service.hpp \
+	asio/detail/win_iocp_handle_write_op.hpp \
+	asio/detail/win_iocp_io_context.hpp \
+	asio/detail/win_iocp_null_buffers_op.hpp \
+	asio/detail/win_iocp_operation.hpp \
+	asio/detail/win_iocp_overlapped_op.hpp \
+	asio/detail/win_iocp_overlapped_ptr.hpp \
+	asio/detail/win_iocp_serial_port_service.hpp \
+	asio/detail/win_iocp_socket_accept_op.hpp \
+	asio/detail/win_iocp_socket_connect_op.hpp \
+	asio/detail/win_iocp_socket_recvfrom_op.hpp \
+	asio/detail/win_iocp_socket_recvmsg_op.hpp \
+	asio/detail/win_iocp_socket_recv_op.hpp \
+	asio/detail/win_iocp_socket_send_op.hpp \
+	asio/detail/win_iocp_socket_service_base.hpp \
+	asio/detail/win_iocp_socket_service.hpp \
+	asio/detail/win_iocp_thread_info.hpp \
+	asio/detail/win_iocp_wait_op.hpp \
+	asio/detail/win_mutex.hpp \
+	asio/detail/win_object_handle_service.hpp \
+	asio/detail/winrt_async_manager.hpp \
+	asio/detail/winrt_async_op.hpp \
+	asio/detail/winrt_resolve_op.hpp \
+	asio/detail/winrt_resolver_service.hpp \
+	asio/detail/winrt_socket_connect_op.hpp \
+	asio/detail/winrt_socket_recv_op.hpp \
+	asio/detail/winrt_socket_send_op.hpp \
+	asio/detail/winrt_ssocket_service_base.hpp \
+	asio/detail/winrt_ssocket_service.hpp \
+	asio/detail/winrt_timer_scheduler.hpp \
+	asio/detail/winrt_utils.hpp \
+	asio/detail/winsock_init.hpp \
+	asio/detail/win_static_mutex.hpp \
+	asio/detail/win_thread.hpp \
+	asio/detail/win_tss_ptr.hpp \
+	asio/detail/work_dispatcher.hpp \
+	asio/detail/wrapped_handler.hpp \
+	asio/dispatch.hpp \
+	asio/error_code.hpp \
+	asio/error.hpp \
+	asio/execution.hpp \
+	asio/execution_context.hpp \
+	asio/execution/allocator.hpp \
+	asio/execution/any_executor.hpp \
+	asio/execution/bad_executor.hpp \
+	asio/execution/blocking.hpp \
+	asio/execution/blocking_adaptation.hpp \
+	asio/execution/bulk_execute.hpp \
+	asio/execution/bulk_guarantee.hpp \
+	asio/execution/connect.hpp \
+	asio/execution/context.hpp \
+	asio/execution/context_as.hpp \
+	asio/execution/detail/as_invocable.hpp \
+	asio/execution/detail/as_operation.hpp \
+	asio/execution/detail/as_receiver.hpp \
+	asio/execution/detail/bulk_sender.hpp \
+	asio/execution/detail/void_receiver.hpp \
+	asio/execution/detail/submit_receiver.hpp \
+	asio/execution/execute.hpp \
+	asio/execution/executor.hpp \
+	asio/execution/impl/bad_executor.ipp \
+	asio/execution/impl/receiver_invocation_error.ipp \
+	asio/execution/invocable_archetype.hpp \
+	asio/execution/mapping.hpp \
+	asio/execution/occupancy.hpp \
+	asio/execution/operation_state.hpp \
+	asio/execution/outstanding_work.hpp \
+	asio/execution/prefer_only.hpp \
+	asio/execution/receiver.hpp \
+	asio/execution/receiver_invocation_error.hpp \
+	asio/execution/relationship.hpp \
+	asio/execution/schedule.hpp \
+	asio/execution/scheduler.hpp \
+	asio/execution/sender.hpp \
+	asio/execution/set_done.hpp \
+	asio/execution/set_error.hpp \
+	asio/execution/set_value.hpp \
+	asio/execution/start.hpp \
+	asio/execution/submit.hpp \
+	asio/executor.hpp \
+	asio/executor_work_guard.hpp \
+	asio/experimental/as_single.hpp \
+	asio/experimental/impl/as_single.hpp \
+	asio/generic/basic_endpoint.hpp \
+	asio/generic/datagram_protocol.hpp \
+	asio/generic/detail/endpoint.hpp \
+	asio/generic/detail/impl/endpoint.ipp \
+	asio/generic/raw_protocol.hpp \
+	asio/generic/seq_packet_protocol.hpp \
+	asio/generic/stream_protocol.hpp \
+	asio/handler_alloc_hook.hpp \
+	asio/handler_continuation_hook.hpp \
+	asio/handler_invoke_hook.hpp \
+	asio/high_resolution_timer.hpp \
+	asio.hpp \
+	asio/impl/awaitable.hpp \
+	asio/impl/buffered_read_stream.hpp \
+	asio/impl/buffered_write_stream.hpp \
+	asio/impl/co_spawn.hpp \
+	asio/impl/compose.hpp \
+	asio/impl/connect.hpp \
+	asio/impl/defer.hpp \
+	asio/impl/detached.hpp \
+	asio/impl/dispatch.hpp \
+	asio/impl/error_code.ipp \
+	asio/impl/error.ipp \
+	asio/impl/execution_context.hpp \
+	asio/impl/execution_context.ipp \
+	asio/impl/executor.hpp \
+	asio/impl/executor.ipp \
+	asio/impl/handler_alloc_hook.ipp \
+	asio/impl/io_context.hpp \
+	asio/impl/io_context.ipp \
+	asio/impl/multiple_exceptions.ipp \
+	asio/impl/post.hpp \
+	asio/impl/read_at.hpp \
+	asio/impl/read.hpp \
+	asio/impl/read_until.hpp \
+	asio/impl/redirect_error.hpp \
+	asio/impl/serial_port_base.hpp \
+	asio/impl/serial_port_base.ipp \
+	asio/impl/spawn.hpp \
+	asio/impl/src.hpp \
+	asio/impl/system_context.hpp \
+	asio/impl/system_context.ipp \
+	asio/impl/system_executor.hpp \
+	asio/impl/thread_pool.hpp \
+	asio/impl/thread_pool.ipp \
+	asio/impl/use_awaitable.hpp \
+	asio/impl/use_future.hpp \
+	asio/impl/write_at.hpp \
+	asio/impl/write.hpp \
+	asio/io_context.hpp \
+	asio/io_context_strand.hpp \
+	asio/io_service.hpp \
+	asio/io_service_strand.hpp \
+	asio/ip/address.hpp \
+	asio/ip/address_v4.hpp \
+	asio/ip/address_v4_iterator.hpp \
+	asio/ip/address_v4_range.hpp \
+	asio/ip/address_v6.hpp \
+	asio/ip/address_v6_iterator.hpp \
+	asio/ip/address_v6_range.hpp \
+	asio/ip/bad_address_cast.hpp \
+	asio/ip/basic_endpoint.hpp \
+	asio/ip/basic_resolver_entry.hpp \
+	asio/ip/basic_resolver.hpp \
+	asio/ip/basic_resolver_iterator.hpp \
+	asio/ip/basic_resolver_query.hpp \
+	asio/ip/basic_resolver_results.hpp \
+	asio/ip/detail/endpoint.hpp \
+	asio/ip/detail/impl/endpoint.ipp \
+	asio/ip/detail/socket_option.hpp \
+	asio/ip/host_name.hpp \
+	asio/ip/icmp.hpp \
+	asio/ip/impl/address.hpp \
+	asio/ip/impl/address.ipp \
+	asio/ip/impl/address_v4.hpp \
+	asio/ip/impl/address_v4.ipp \
+	asio/ip/impl/address_v6.hpp \
+	asio/ip/impl/address_v6.ipp \
+	asio/ip/impl/basic_endpoint.hpp \
+	asio/ip/impl/host_name.ipp \
+	asio/ip/impl/network_v4.hpp \
+	asio/ip/impl/network_v4.ipp \
+	asio/ip/impl/network_v6.hpp \
+	asio/ip/impl/network_v6.ipp \
+	asio/ip/multicast.hpp \
+	asio/ip/network_v4.hpp \
+	asio/ip/network_v6.hpp \
+	asio/ip/resolver_base.hpp \
+	asio/ip/resolver_query_base.hpp \
+	asio/ip/tcp.hpp \
+	asio/ip/udp.hpp \
+	asio/ip/unicast.hpp \
+	asio/ip/v6_only.hpp \
+	asio/is_applicable_property.hpp \
+	asio/is_executor.hpp \
+	asio/is_read_buffered.hpp \
+	asio/is_write_buffered.hpp \
+	asio/local/basic_endpoint.hpp \
+	asio/local/connect_pair.hpp \
+	asio/local/datagram_protocol.hpp \
+	asio/local/detail/endpoint.hpp \
+	asio/local/detail/impl/endpoint.ipp \
+	asio/local/stream_protocol.hpp \
+	asio/multiple_exceptions.hpp \
+	asio/packaged_task.hpp \
+	asio/placeholders.hpp \
+	asio/posix/basic_descriptor.hpp \
+	asio/posix/basic_stream_descriptor.hpp \
+	asio/posix/descriptor_base.hpp \
+	asio/posix/descriptor.hpp \
+	asio/posix/stream_descriptor.hpp \
+	asio/post.hpp \
+	asio/prefer.hpp \
+	asio/query.hpp \
+	asio/read_at.hpp \
+	asio/read.hpp \
+	asio/read_until.hpp \
+	asio/redirect_error.hpp \
+	asio/require.hpp \
+	asio/require_concept.hpp \
+	asio/serial_port_base.hpp \
+	asio/serial_port.hpp \
+	asio/signal_set.hpp \
+	asio/socket_base.hpp \
+	asio/spawn.hpp \
+	asio/ssl/context_base.hpp \
+	asio/ssl/context.hpp \
+	asio/ssl/detail/buffered_handshake_op.hpp \
+	asio/ssl/detail/engine.hpp \
+	asio/ssl/detail/handshake_op.hpp \
+	asio/ssl/detail/impl/engine.ipp \
+	asio/ssl/detail/impl/openssl_init.ipp \
+	asio/ssl/detail/io.hpp \
+	asio/ssl/detail/openssl_init.hpp \
+	asio/ssl/detail/openssl_types.hpp \
+	asio/ssl/detail/password_callback.hpp \
+	asio/ssl/detail/read_op.hpp \
+	asio/ssl/detail/shutdown_op.hpp \
+	asio/ssl/detail/stream_core.hpp \
+	asio/ssl/detail/verify_callback.hpp \
+	asio/ssl/detail/write_op.hpp \
+	asio/ssl/error.hpp \
+	asio/ssl.hpp \
+	asio/ssl/host_name_verification.hpp \
+	asio/ssl/impl/context.hpp \
+	asio/ssl/impl/context.ipp \
+	asio/ssl/impl/error.ipp \
+	asio/ssl/impl/host_name_verification.ipp \
+	asio/ssl/impl/rfc2818_verification.ipp \
+	asio/ssl/impl/src.hpp \
+	asio/ssl/rfc2818_verification.hpp \
+	asio/ssl/stream_base.hpp \
+	asio/ssl/stream.hpp \
+	asio/ssl/verify_context.hpp \
+	asio/ssl/verify_mode.hpp \
+	asio/static_thread_pool.hpp \
+	asio/steady_timer.hpp \
+	asio/strand.hpp \
+	asio/streambuf.hpp \
+	asio/system_context.hpp \
+	asio/system_error.hpp \
+	asio/system_executor.hpp \
+	asio/system_timer.hpp \
+	asio/this_coro.hpp \
+	asio/thread.hpp \
+	asio/thread_pool.hpp \
+	asio/time_traits.hpp \
+	asio/traits/bulk_execute_free.hpp \
+	asio/traits/bulk_execute_member.hpp \
+	asio/traits/connect_free.hpp \
+	asio/traits/connect_member.hpp \
+	asio/traits/equality_comparable.hpp \
+	asio/traits/execute_free.hpp \
+	asio/traits/execute_member.hpp \
+	asio/traits/prefer_free.hpp \
+	asio/traits/prefer_member.hpp \
+	asio/traits/query_free.hpp \
+	asio/traits/query_member.hpp \
+	asio/traits/query_static_constexpr_member.hpp \
+	asio/traits/require_concept_free.hpp \
+	asio/traits/require_concept_member.hpp \
+	asio/traits/require_free.hpp \
+	asio/traits/require_member.hpp \
+	asio/traits/schedule_free.hpp \
+	asio/traits/schedule_member.hpp \
+	asio/traits/set_done_free.hpp \
+	asio/traits/set_done_member.hpp \
+	asio/traits/set_error_free.hpp \
+	asio/traits/set_error_member.hpp \
+	asio/traits/set_value_free.hpp \
+	asio/traits/set_value_member.hpp \
+	asio/traits/start_free.hpp \
+	asio/traits/start_member.hpp \
+	asio/traits/static_query.hpp \
+	asio/traits/static_require.hpp \
+	asio/traits/static_require_concept.hpp \
+	asio/traits/submit_free.hpp \
+	asio/traits/submit_member.hpp \
+	asio/ts/buffer.hpp \
+	asio/ts/executor.hpp \
+	asio/ts/internet.hpp \
+	asio/ts/io_context.hpp \
+	asio/ts/netfwd.hpp \
+	asio/ts/net.hpp \
+	asio/ts/socket.hpp \
+	asio/ts/timer.hpp \
+	asio/unyield.hpp \
+	asio/use_awaitable.hpp \
+	asio/use_future.hpp \
+	asio/uses_executor.hpp \
+	asio/version.hpp \
+	asio/wait_traits.hpp \
+	asio/windows/basic_object_handle.hpp \
+	asio/windows/basic_overlapped_handle.hpp \
+	asio/windows/basic_random_access_handle.hpp \
+	asio/windows/basic_stream_handle.hpp \
+	asio/windows/object_handle.hpp \
+	asio/windows/overlapped_handle.hpp \
+	asio/windows/overlapped_ptr.hpp \
+	asio/windows/random_access_handle.hpp \
+	asio/windows/stream_handle.hpp \
+	asio/write_at.hpp \
+	asio/write.hpp \
+	asio/yield.hpp
+
+MAINTAINERCLEANFILES = \
+	$(srcdir)/Makefile.in
diff --git a/cpp/third_party/asio/1.18.2/include/Makefile.in b/cpp/third_party/asio/1.18.2/include/Makefile.in
new file mode 100644
index 0000000..fc25627
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/Makefile.in
@@ -0,0 +1,1105 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = include
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(includedir)"
+HEADERS = $(nobase_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# find . -name "*.*pp" | sed -e 's/^\.\///' | sed -e 's/^.*$/  & \\/' | sort
+nobase_include_HEADERS = \
+	asio/any_io_executor.hpp \
+	asio/associated_allocator.hpp \
+	asio/associated_executor.hpp \
+	asio/async_result.hpp \
+	asio/awaitable.hpp \
+	asio/basic_datagram_socket.hpp \
+	asio/basic_deadline_timer.hpp \
+	asio/basic_io_object.hpp \
+	asio/basic_raw_socket.hpp \
+	asio/basic_seq_packet_socket.hpp \
+	asio/basic_serial_port.hpp \
+	asio/basic_signal_set.hpp \
+	asio/basic_socket_acceptor.hpp \
+	asio/basic_socket.hpp \
+	asio/basic_socket_iostream.hpp \
+	asio/basic_socket_streambuf.hpp \
+	asio/basic_streambuf_fwd.hpp \
+	asio/basic_streambuf.hpp \
+	asio/basic_stream_socket.hpp \
+	asio/basic_waitable_timer.hpp \
+	asio/bind_executor.hpp \
+	asio/buffered_read_stream_fwd.hpp \
+	asio/buffered_read_stream.hpp \
+	asio/buffered_stream_fwd.hpp \
+	asio/buffered_stream.hpp \
+	asio/buffered_write_stream_fwd.hpp \
+	asio/buffered_write_stream.hpp \
+	asio/buffer.hpp \
+	asio/buffers_iterator.hpp \
+	asio/co_spawn.hpp \
+	asio/completion_condition.hpp \
+	asio/compose.hpp \
+	asio/connect.hpp \
+	asio/coroutine.hpp \
+	asio/deadline_timer.hpp \
+	asio/defer.hpp \
+	asio/detached.hpp \
+	asio/detail/array_fwd.hpp \
+	asio/detail/array.hpp \
+	asio/detail/assert.hpp \
+	asio/detail/atomic_count.hpp \
+	asio/detail/base_from_completion_cond.hpp \
+	asio/detail/bind_handler.hpp \
+	asio/detail/blocking_executor_op.hpp \
+	asio/detail/buffered_stream_storage.hpp \
+	asio/detail/buffer_resize_guard.hpp \
+	asio/detail/buffer_sequence_adapter.hpp \
+	asio/detail/bulk_executor_op.hpp \
+	asio/detail/call_stack.hpp \
+	asio/detail/chrono.hpp \
+	asio/detail/chrono_time_traits.hpp \
+	asio/detail/completion_handler.hpp \
+	asio/detail/concurrency_hint.hpp \
+	asio/detail/conditionally_enabled_event.hpp \
+	asio/detail/conditionally_enabled_mutex.hpp \
+	asio/detail/config.hpp \
+	asio/detail/consuming_buffers.hpp \
+	asio/detail/cstddef.hpp \
+	asio/detail/cstdint.hpp \
+	asio/detail/date_time_fwd.hpp \
+	asio/detail/deadline_timer_service.hpp \
+	asio/detail/dependent_type.hpp \
+	asio/detail/descriptor_ops.hpp \
+	asio/detail/descriptor_read_op.hpp \
+	asio/detail/descriptor_write_op.hpp \
+	asio/detail/dev_poll_reactor.hpp \
+	asio/detail/epoll_reactor.hpp \
+	asio/detail/eventfd_select_interrupter.hpp \
+	asio/detail/event.hpp \
+	asio/detail/executor_function.hpp \
+	asio/detail/executor_op.hpp \
+	asio/detail/fd_set_adapter.hpp \
+	asio/detail/fenced_block.hpp \
+	asio/detail/functional.hpp \
+	asio/detail/future.hpp \
+	asio/detail/gcc_arm_fenced_block.hpp \
+	asio/detail/gcc_hppa_fenced_block.hpp \
+	asio/detail/gcc_sync_fenced_block.hpp \
+	asio/detail/gcc_x86_fenced_block.hpp \
+	asio/detail/global.hpp \
+	asio/detail/handler_alloc_helpers.hpp \
+	asio/detail/handler_cont_helpers.hpp \
+	asio/detail/handler_invoke_helpers.hpp \
+	asio/detail/handler_tracking.hpp \
+	asio/detail/handler_type_requirements.hpp \
+	asio/detail/handler_work.hpp \
+	asio/detail/hash_map.hpp \
+	asio/detail/impl/buffer_sequence_adapter.ipp \
+	asio/detail/impl/descriptor_ops.ipp \
+	asio/detail/impl/dev_poll_reactor.hpp \
+	asio/detail/impl/dev_poll_reactor.ipp \
+	asio/detail/impl/epoll_reactor.hpp \
+	asio/detail/impl/epoll_reactor.ipp \
+	asio/detail/impl/eventfd_select_interrupter.ipp \
+	asio/detail/impl/handler_tracking.ipp \
+	asio/detail/impl/kqueue_reactor.hpp \
+	asio/detail/impl/kqueue_reactor.ipp \
+	asio/detail/impl/null_event.ipp \
+	asio/detail/impl/pipe_select_interrupter.ipp \
+	asio/detail/impl/posix_event.ipp \
+	asio/detail/impl/posix_mutex.ipp \
+	asio/detail/impl/posix_thread.ipp \
+	asio/detail/impl/posix_tss_ptr.ipp \
+	asio/detail/impl/reactive_descriptor_service.ipp \
+	asio/detail/impl/reactive_serial_port_service.ipp \
+	asio/detail/impl/reactive_socket_service_base.ipp \
+	asio/detail/impl/resolver_service_base.ipp \
+	asio/detail/impl/scheduler.ipp \
+	asio/detail/impl/select_reactor.hpp \
+	asio/detail/impl/select_reactor.ipp \
+	asio/detail/impl/service_registry.hpp \
+	asio/detail/impl/service_registry.ipp \
+	asio/detail/impl/signal_set_service.ipp \
+	asio/detail/impl/socket_ops.ipp \
+	asio/detail/impl/socket_select_interrupter.ipp \
+	asio/detail/impl/strand_executor_service.hpp \
+	asio/detail/impl/strand_executor_service.ipp \
+	asio/detail/impl/strand_service.hpp \
+	asio/detail/impl/strand_service.ipp \
+	asio/detail/impl/thread_context.ipp \
+	asio/detail/impl/throw_error.ipp \
+	asio/detail/impl/timer_queue_ptime.ipp \
+	asio/detail/impl/timer_queue_set.ipp \
+	asio/detail/impl/win_event.ipp \
+	asio/detail/impl/win_iocp_handle_service.ipp \
+	asio/detail/impl/win_iocp_io_context.hpp \
+	asio/detail/impl/win_iocp_io_context.ipp \
+	asio/detail/impl/win_iocp_serial_port_service.ipp \
+	asio/detail/impl/win_iocp_socket_service_base.ipp \
+	asio/detail/impl/win_mutex.ipp \
+	asio/detail/impl/win_object_handle_service.ipp \
+	asio/detail/impl/winrt_ssocket_service_base.ipp \
+	asio/detail/impl/winrt_timer_scheduler.hpp \
+	asio/detail/impl/winrt_timer_scheduler.ipp \
+	asio/detail/impl/winsock_init.ipp \
+	asio/detail/impl/win_static_mutex.ipp \
+	asio/detail/impl/win_thread.ipp \
+	asio/detail/impl/win_tss_ptr.ipp \
+	asio/detail/io_control.hpp \
+	asio/detail/io_object_impl.hpp \
+	asio/detail/is_buffer_sequence.hpp \
+	asio/detail/is_executor.hpp \
+	asio/detail/keyword_tss_ptr.hpp \
+	asio/detail/kqueue_reactor.hpp \
+	asio/detail/limits.hpp \
+	asio/detail/local_free_on_block_exit.hpp \
+	asio/detail/macos_fenced_block.hpp \
+	asio/detail/memory.hpp \
+	asio/detail/mutex.hpp \
+	asio/detail/non_const_lvalue.hpp \
+	asio/detail/noncopyable.hpp \
+	asio/detail/null_event.hpp \
+	asio/detail/null_fenced_block.hpp \
+	asio/detail/null_global.hpp \
+	asio/detail/null_mutex.hpp \
+	asio/detail/null_reactor.hpp \
+	asio/detail/null_signal_blocker.hpp \
+	asio/detail/null_socket_service.hpp \
+	asio/detail/null_static_mutex.hpp \
+	asio/detail/null_thread.hpp \
+	asio/detail/null_tss_ptr.hpp \
+	asio/detail/object_pool.hpp \
+	asio/detail/old_win_sdk_compat.hpp \
+	asio/detail/operation.hpp \
+	asio/detail/op_queue.hpp \
+	asio/detail/pipe_select_interrupter.hpp \
+	asio/detail/pop_options.hpp \
+	asio/detail/posix_event.hpp \
+	asio/detail/posix_fd_set_adapter.hpp \
+	asio/detail/posix_global.hpp \
+	asio/detail/posix_mutex.hpp \
+	asio/detail/posix_signal_blocker.hpp \
+	asio/detail/posix_static_mutex.hpp \
+	asio/detail/posix_thread.hpp \
+	asio/detail/posix_tss_ptr.hpp \
+	asio/detail/push_options.hpp \
+	asio/detail/reactive_descriptor_service.hpp \
+	asio/detail/reactive_null_buffers_op.hpp \
+	asio/detail/reactive_serial_port_service.hpp \
+	asio/detail/reactive_socket_accept_op.hpp \
+	asio/detail/reactive_socket_connect_op.hpp \
+	asio/detail/reactive_socket_recvfrom_op.hpp \
+	asio/detail/reactive_socket_recvmsg_op.hpp \
+	asio/detail/reactive_socket_recv_op.hpp \
+	asio/detail/reactive_socket_send_op.hpp \
+	asio/detail/reactive_socket_sendto_op.hpp \
+	asio/detail/reactive_socket_service_base.hpp \
+	asio/detail/reactive_socket_service.hpp \
+	asio/detail/reactive_wait_op.hpp \
+	asio/detail/reactor_fwd.hpp \
+	asio/detail/reactor.hpp \
+	asio/detail/reactor_op.hpp \
+	asio/detail/reactor_op_queue.hpp \
+	asio/detail/recycling_allocator.hpp \
+	asio/detail/regex_fwd.hpp \
+	asio/detail/resolve_endpoint_op.hpp \
+	asio/detail/resolve_op.hpp \
+	asio/detail/resolve_query_op.hpp \
+	asio/detail/resolver_service_base.hpp \
+	asio/detail/resolver_service.hpp \
+	asio/detail/scheduler.hpp \
+	asio/detail/scheduler_operation.hpp \
+	asio/detail/scheduler_thread_info.hpp \
+	asio/detail/scoped_lock.hpp \
+	asio/detail/scoped_ptr.hpp \
+	asio/detail/select_interrupter.hpp \
+	asio/detail/select_reactor.hpp \
+	asio/detail/service_registry.hpp \
+	asio/detail/signal_blocker.hpp \
+	asio/detail/signal_handler.hpp \
+	asio/detail/signal_init.hpp \
+	asio/detail/signal_op.hpp \
+	asio/detail/signal_set_service.hpp \
+	asio/detail/socket_holder.hpp \
+	asio/detail/socket_ops.hpp \
+	asio/detail/socket_option.hpp \
+	asio/detail/socket_select_interrupter.hpp \
+	asio/detail/socket_types.hpp \
+	asio/detail/solaris_fenced_block.hpp \
+	asio/detail/source_location.hpp \
+	asio/detail/static_mutex.hpp \
+	asio/detail/std_event.hpp \
+	asio/detail/std_fenced_block.hpp \
+	asio/detail/std_global.hpp \
+	asio/detail/std_mutex.hpp \
+	asio/detail/std_static_mutex.hpp \
+	asio/detail/std_thread.hpp \
+	asio/detail/strand_executor_service.hpp \
+	asio/detail/strand_service.hpp \
+	asio/detail/string_view.hpp \
+	asio/detail/thread_context.hpp \
+	asio/detail/thread_group.hpp \
+	asio/detail/thread.hpp \
+	asio/detail/thread_info_base.hpp \
+	asio/detail/throw_error.hpp \
+	asio/detail/throw_exception.hpp \
+	asio/detail/timer_queue_base.hpp \
+	asio/detail/timer_queue.hpp \
+	asio/detail/timer_queue_ptime.hpp \
+	asio/detail/timer_queue_set.hpp \
+	asio/detail/timer_scheduler_fwd.hpp \
+	asio/detail/timer_scheduler.hpp \
+	asio/detail/tss_ptr.hpp \
+	asio/detail/type_traits.hpp \
+	asio/detail/variadic_templates.hpp \
+	asio/detail/wait_handler.hpp \
+	asio/detail/wait_op.hpp \
+	asio/detail/winapp_thread.hpp \
+	asio/detail/wince_thread.hpp \
+	asio/detail/win_event.hpp \
+	asio/detail/win_fd_set_adapter.hpp \
+	asio/detail/win_fenced_block.hpp \
+	asio/detail/win_global.hpp \
+	asio/detail/win_iocp_handle_read_op.hpp \
+	asio/detail/win_iocp_handle_service.hpp \
+	asio/detail/win_iocp_handle_write_op.hpp \
+	asio/detail/win_iocp_io_context.hpp \
+	asio/detail/win_iocp_null_buffers_op.hpp \
+	asio/detail/win_iocp_operation.hpp \
+	asio/detail/win_iocp_overlapped_op.hpp \
+	asio/detail/win_iocp_overlapped_ptr.hpp \
+	asio/detail/win_iocp_serial_port_service.hpp \
+	asio/detail/win_iocp_socket_accept_op.hpp \
+	asio/detail/win_iocp_socket_connect_op.hpp \
+	asio/detail/win_iocp_socket_recvfrom_op.hpp \
+	asio/detail/win_iocp_socket_recvmsg_op.hpp \
+	asio/detail/win_iocp_socket_recv_op.hpp \
+	asio/detail/win_iocp_socket_send_op.hpp \
+	asio/detail/win_iocp_socket_service_base.hpp \
+	asio/detail/win_iocp_socket_service.hpp \
+	asio/detail/win_iocp_thread_info.hpp \
+	asio/detail/win_iocp_wait_op.hpp \
+	asio/detail/win_mutex.hpp \
+	asio/detail/win_object_handle_service.hpp \
+	asio/detail/winrt_async_manager.hpp \
+	asio/detail/winrt_async_op.hpp \
+	asio/detail/winrt_resolve_op.hpp \
+	asio/detail/winrt_resolver_service.hpp \
+	asio/detail/winrt_socket_connect_op.hpp \
+	asio/detail/winrt_socket_recv_op.hpp \
+	asio/detail/winrt_socket_send_op.hpp \
+	asio/detail/winrt_ssocket_service_base.hpp \
+	asio/detail/winrt_ssocket_service.hpp \
+	asio/detail/winrt_timer_scheduler.hpp \
+	asio/detail/winrt_utils.hpp \
+	asio/detail/winsock_init.hpp \
+	asio/detail/win_static_mutex.hpp \
+	asio/detail/win_thread.hpp \
+	asio/detail/win_tss_ptr.hpp \
+	asio/detail/work_dispatcher.hpp \
+	asio/detail/wrapped_handler.hpp \
+	asio/dispatch.hpp \
+	asio/error_code.hpp \
+	asio/error.hpp \
+	asio/execution.hpp \
+	asio/execution_context.hpp \
+	asio/execution/allocator.hpp \
+	asio/execution/any_executor.hpp \
+	asio/execution/bad_executor.hpp \
+	asio/execution/blocking.hpp \
+	asio/execution/blocking_adaptation.hpp \
+	asio/execution/bulk_execute.hpp \
+	asio/execution/bulk_guarantee.hpp \
+	asio/execution/connect.hpp \
+	asio/execution/context.hpp \
+	asio/execution/context_as.hpp \
+	asio/execution/detail/as_invocable.hpp \
+	asio/execution/detail/as_operation.hpp \
+	asio/execution/detail/as_receiver.hpp \
+	asio/execution/detail/bulk_sender.hpp \
+	asio/execution/detail/void_receiver.hpp \
+	asio/execution/detail/submit_receiver.hpp \
+	asio/execution/execute.hpp \
+	asio/execution/executor.hpp \
+	asio/execution/impl/bad_executor.ipp \
+	asio/execution/impl/receiver_invocation_error.ipp \
+	asio/execution/invocable_archetype.hpp \
+	asio/execution/mapping.hpp \
+	asio/execution/occupancy.hpp \
+	asio/execution/operation_state.hpp \
+	asio/execution/outstanding_work.hpp \
+	asio/execution/prefer_only.hpp \
+	asio/execution/receiver.hpp \
+	asio/execution/receiver_invocation_error.hpp \
+	asio/execution/relationship.hpp \
+	asio/execution/schedule.hpp \
+	asio/execution/scheduler.hpp \
+	asio/execution/sender.hpp \
+	asio/execution/set_done.hpp \
+	asio/execution/set_error.hpp \
+	asio/execution/set_value.hpp \
+	asio/execution/start.hpp \
+	asio/execution/submit.hpp \
+	asio/executor.hpp \
+	asio/executor_work_guard.hpp \
+	asio/experimental/as_single.hpp \
+	asio/experimental/impl/as_single.hpp \
+	asio/generic/basic_endpoint.hpp \
+	asio/generic/datagram_protocol.hpp \
+	asio/generic/detail/endpoint.hpp \
+	asio/generic/detail/impl/endpoint.ipp \
+	asio/generic/raw_protocol.hpp \
+	asio/generic/seq_packet_protocol.hpp \
+	asio/generic/stream_protocol.hpp \
+	asio/handler_alloc_hook.hpp \
+	asio/handler_continuation_hook.hpp \
+	asio/handler_invoke_hook.hpp \
+	asio/high_resolution_timer.hpp \
+	asio.hpp \
+	asio/impl/awaitable.hpp \
+	asio/impl/buffered_read_stream.hpp \
+	asio/impl/buffered_write_stream.hpp \
+	asio/impl/co_spawn.hpp \
+	asio/impl/compose.hpp \
+	asio/impl/connect.hpp \
+	asio/impl/defer.hpp \
+	asio/impl/detached.hpp \
+	asio/impl/dispatch.hpp \
+	asio/impl/error_code.ipp \
+	asio/impl/error.ipp \
+	asio/impl/execution_context.hpp \
+	asio/impl/execution_context.ipp \
+	asio/impl/executor.hpp \
+	asio/impl/executor.ipp \
+	asio/impl/handler_alloc_hook.ipp \
+	asio/impl/io_context.hpp \
+	asio/impl/io_context.ipp \
+	asio/impl/multiple_exceptions.ipp \
+	asio/impl/post.hpp \
+	asio/impl/read_at.hpp \
+	asio/impl/read.hpp \
+	asio/impl/read_until.hpp \
+	asio/impl/redirect_error.hpp \
+	asio/impl/serial_port_base.hpp \
+	asio/impl/serial_port_base.ipp \
+	asio/impl/spawn.hpp \
+	asio/impl/src.hpp \
+	asio/impl/system_context.hpp \
+	asio/impl/system_context.ipp \
+	asio/impl/system_executor.hpp \
+	asio/impl/thread_pool.hpp \
+	asio/impl/thread_pool.ipp \
+	asio/impl/use_awaitable.hpp \
+	asio/impl/use_future.hpp \
+	asio/impl/write_at.hpp \
+	asio/impl/write.hpp \
+	asio/io_context.hpp \
+	asio/io_context_strand.hpp \
+	asio/io_service.hpp \
+	asio/io_service_strand.hpp \
+	asio/ip/address.hpp \
+	asio/ip/address_v4.hpp \
+	asio/ip/address_v4_iterator.hpp \
+	asio/ip/address_v4_range.hpp \
+	asio/ip/address_v6.hpp \
+	asio/ip/address_v6_iterator.hpp \
+	asio/ip/address_v6_range.hpp \
+	asio/ip/bad_address_cast.hpp \
+	asio/ip/basic_endpoint.hpp \
+	asio/ip/basic_resolver_entry.hpp \
+	asio/ip/basic_resolver.hpp \
+	asio/ip/basic_resolver_iterator.hpp \
+	asio/ip/basic_resolver_query.hpp \
+	asio/ip/basic_resolver_results.hpp \
+	asio/ip/detail/endpoint.hpp \
+	asio/ip/detail/impl/endpoint.ipp \
+	asio/ip/detail/socket_option.hpp \
+	asio/ip/host_name.hpp \
+	asio/ip/icmp.hpp \
+	asio/ip/impl/address.hpp \
+	asio/ip/impl/address.ipp \
+	asio/ip/impl/address_v4.hpp \
+	asio/ip/impl/address_v4.ipp \
+	asio/ip/impl/address_v6.hpp \
+	asio/ip/impl/address_v6.ipp \
+	asio/ip/impl/basic_endpoint.hpp \
+	asio/ip/impl/host_name.ipp \
+	asio/ip/impl/network_v4.hpp \
+	asio/ip/impl/network_v4.ipp \
+	asio/ip/impl/network_v6.hpp \
+	asio/ip/impl/network_v6.ipp \
+	asio/ip/multicast.hpp \
+	asio/ip/network_v4.hpp \
+	asio/ip/network_v6.hpp \
+	asio/ip/resolver_base.hpp \
+	asio/ip/resolver_query_base.hpp \
+	asio/ip/tcp.hpp \
+	asio/ip/udp.hpp \
+	asio/ip/unicast.hpp \
+	asio/ip/v6_only.hpp \
+	asio/is_applicable_property.hpp \
+	asio/is_executor.hpp \
+	asio/is_read_buffered.hpp \
+	asio/is_write_buffered.hpp \
+	asio/local/basic_endpoint.hpp \
+	asio/local/connect_pair.hpp \
+	asio/local/datagram_protocol.hpp \
+	asio/local/detail/endpoint.hpp \
+	asio/local/detail/impl/endpoint.ipp \
+	asio/local/stream_protocol.hpp \
+	asio/multiple_exceptions.hpp \
+	asio/packaged_task.hpp \
+	asio/placeholders.hpp \
+	asio/posix/basic_descriptor.hpp \
+	asio/posix/basic_stream_descriptor.hpp \
+	asio/posix/descriptor_base.hpp \
+	asio/posix/descriptor.hpp \
+	asio/posix/stream_descriptor.hpp \
+	asio/post.hpp \
+	asio/prefer.hpp \
+	asio/query.hpp \
+	asio/read_at.hpp \
+	asio/read.hpp \
+	asio/read_until.hpp \
+	asio/redirect_error.hpp \
+	asio/require.hpp \
+	asio/require_concept.hpp \
+	asio/serial_port_base.hpp \
+	asio/serial_port.hpp \
+	asio/signal_set.hpp \
+	asio/socket_base.hpp \
+	asio/spawn.hpp \
+	asio/ssl/context_base.hpp \
+	asio/ssl/context.hpp \
+	asio/ssl/detail/buffered_handshake_op.hpp \
+	asio/ssl/detail/engine.hpp \
+	asio/ssl/detail/handshake_op.hpp \
+	asio/ssl/detail/impl/engine.ipp \
+	asio/ssl/detail/impl/openssl_init.ipp \
+	asio/ssl/detail/io.hpp \
+	asio/ssl/detail/openssl_init.hpp \
+	asio/ssl/detail/openssl_types.hpp \
+	asio/ssl/detail/password_callback.hpp \
+	asio/ssl/detail/read_op.hpp \
+	asio/ssl/detail/shutdown_op.hpp \
+	asio/ssl/detail/stream_core.hpp \
+	asio/ssl/detail/verify_callback.hpp \
+	asio/ssl/detail/write_op.hpp \
+	asio/ssl/error.hpp \
+	asio/ssl.hpp \
+	asio/ssl/host_name_verification.hpp \
+	asio/ssl/impl/context.hpp \
+	asio/ssl/impl/context.ipp \
+	asio/ssl/impl/error.ipp \
+	asio/ssl/impl/host_name_verification.ipp \
+	asio/ssl/impl/rfc2818_verification.ipp \
+	asio/ssl/impl/src.hpp \
+	asio/ssl/rfc2818_verification.hpp \
+	asio/ssl/stream_base.hpp \
+	asio/ssl/stream.hpp \
+	asio/ssl/verify_context.hpp \
+	asio/ssl/verify_mode.hpp \
+	asio/static_thread_pool.hpp \
+	asio/steady_timer.hpp \
+	asio/strand.hpp \
+	asio/streambuf.hpp \
+	asio/system_context.hpp \
+	asio/system_error.hpp \
+	asio/system_executor.hpp \
+	asio/system_timer.hpp \
+	asio/this_coro.hpp \
+	asio/thread.hpp \
+	asio/thread_pool.hpp \
+	asio/time_traits.hpp \
+	asio/traits/bulk_execute_free.hpp \
+	asio/traits/bulk_execute_member.hpp \
+	asio/traits/connect_free.hpp \
+	asio/traits/connect_member.hpp \
+	asio/traits/equality_comparable.hpp \
+	asio/traits/execute_free.hpp \
+	asio/traits/execute_member.hpp \
+	asio/traits/prefer_free.hpp \
+	asio/traits/prefer_member.hpp \
+	asio/traits/query_free.hpp \
+	asio/traits/query_member.hpp \
+	asio/traits/query_static_constexpr_member.hpp \
+	asio/traits/require_concept_free.hpp \
+	asio/traits/require_concept_member.hpp \
+	asio/traits/require_free.hpp \
+	asio/traits/require_member.hpp \
+	asio/traits/schedule_free.hpp \
+	asio/traits/schedule_member.hpp \
+	asio/traits/set_done_free.hpp \
+	asio/traits/set_done_member.hpp \
+	asio/traits/set_error_free.hpp \
+	asio/traits/set_error_member.hpp \
+	asio/traits/set_value_free.hpp \
+	asio/traits/set_value_member.hpp \
+	asio/traits/start_free.hpp \
+	asio/traits/start_member.hpp \
+	asio/traits/static_query.hpp \
+	asio/traits/static_require.hpp \
+	asio/traits/static_require_concept.hpp \
+	asio/traits/submit_free.hpp \
+	asio/traits/submit_member.hpp \
+	asio/ts/buffer.hpp \
+	asio/ts/executor.hpp \
+	asio/ts/internet.hpp \
+	asio/ts/io_context.hpp \
+	asio/ts/netfwd.hpp \
+	asio/ts/net.hpp \
+	asio/ts/socket.hpp \
+	asio/ts/timer.hpp \
+	asio/unyield.hpp \
+	asio/use_awaitable.hpp \
+	asio/use_future.hpp \
+	asio/uses_executor.hpp \
+	asio/version.hpp \
+	asio/wait_traits.hpp \
+	asio/windows/basic_object_handle.hpp \
+	asio/windows/basic_overlapped_handle.hpp \
+	asio/windows/basic_random_access_handle.hpp \
+	asio/windows/basic_stream_handle.hpp \
+	asio/windows/object_handle.hpp \
+	asio/windows/overlapped_handle.hpp \
+	asio/windows/overlapped_ptr.hpp \
+	asio/windows/random_access_handle.hpp \
+	asio/windows/stream_handle.hpp \
+	asio/write_at.hpp \
+	asio/write.hpp \
+	asio/yield.hpp
+
+MAINTAINERCLEANFILES = \
+	$(srcdir)/Makefile.in
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign include/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-nobase_includeHEADERS: $(nobase_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+	fi; \
+	$(am__nobase_list) | while read dir files; do \
+	  xfiles=; for file in $$files; do \
+	    if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+	    else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+	  test -z "$$xfiles" || { \
+	    test "x$$dir" = x. || { \
+	      echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
+	      $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
+	    echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
+	    $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
+	done
+
+uninstall-nobase_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+	$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+	dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(includedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-nobase_includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-nobase_includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	cscopelist-am ctags ctags-am distclean distclean-generic \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-nobase_includeHEADERS install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-nobase_includeHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/cpp/third_party/asio/1.18.2/include/asio.hpp b/cpp/third_party/asio/1.18.2/include/asio.hpp
new file mode 100644
index 0000000..31ce82d
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio.hpp
@@ -0,0 +1,182 @@
+//
+// asio.hpp
+// ~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_HPP
+#define ASIO_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/associated_allocator.hpp"
+#include "asio/associated_executor.hpp"
+#include "asio/async_result.hpp"
+#include "asio/awaitable.hpp"
+#include "asio/basic_datagram_socket.hpp"
+#include "asio/basic_deadline_timer.hpp"
+#include "asio/basic_io_object.hpp"
+#include "asio/basic_raw_socket.hpp"
+#include "asio/basic_seq_packet_socket.hpp"
+#include "asio/basic_serial_port.hpp"
+#include "asio/basic_signal_set.hpp"
+#include "asio/basic_socket.hpp"
+#include "asio/basic_socket_acceptor.hpp"
+#include "asio/basic_socket_iostream.hpp"
+#include "asio/basic_socket_streambuf.hpp"
+#include "asio/basic_stream_socket.hpp"
+#include "asio/basic_streambuf.hpp"
+#include "asio/basic_waitable_timer.hpp"
+#include "asio/bind_executor.hpp"
+#include "asio/buffer.hpp"
+#include "asio/buffered_read_stream_fwd.hpp"
+#include "asio/buffered_read_stream.hpp"
+#include "asio/buffered_stream_fwd.hpp"
+#include "asio/buffered_stream.hpp"
+#include "asio/buffered_write_stream_fwd.hpp"
+#include "asio/buffered_write_stream.hpp"
+#include "asio/buffers_iterator.hpp"
+#include "asio/co_spawn.hpp"
+#include "asio/completion_condition.hpp"
+#include "asio/compose.hpp"
+#include "asio/connect.hpp"
+#include "asio/coroutine.hpp"
+#include "asio/deadline_timer.hpp"
+#include "asio/defer.hpp"
+#include "asio/detached.hpp"
+#include "asio/dispatch.hpp"
+#include "asio/error.hpp"
+#include "asio/error_code.hpp"
+#include "asio/execution.hpp"
+#include "asio/execution/allocator.hpp"
+#include "asio/execution/any_executor.hpp"
+#include "asio/execution/blocking.hpp"
+#include "asio/execution/blocking_adaptation.hpp"
+#include "asio/execution/bulk_execute.hpp"
+#include "asio/execution/bulk_guarantee.hpp"
+#include "asio/execution/connect.hpp"
+#include "asio/execution/context.hpp"
+#include "asio/execution/context_as.hpp"
+#include "asio/execution/execute.hpp"
+#include "asio/execution/executor.hpp"
+#include "asio/execution/invocable_archetype.hpp"
+#include "asio/execution/mapping.hpp"
+#include "asio/execution/occupancy.hpp"
+#include "asio/execution/operation_state.hpp"
+#include "asio/execution/outstanding_work.hpp"
+#include "asio/execution/prefer_only.hpp"
+#include "asio/execution/receiver.hpp"
+#include "asio/execution/receiver_invocation_error.hpp"
+#include "asio/execution/relationship.hpp"
+#include "asio/execution/schedule.hpp"
+#include "asio/execution/scheduler.hpp"
+#include "asio/execution/sender.hpp"
+#include "asio/execution/set_done.hpp"
+#include "asio/execution/set_error.hpp"
+#include "asio/execution/set_value.hpp"
+#include "asio/execution/start.hpp"
+#include "asio/execution_context.hpp"
+#include "asio/executor.hpp"
+#include "asio/executor_work_guard.hpp"
+#include "asio/generic/basic_endpoint.hpp"
+#include "asio/generic/datagram_protocol.hpp"
+#include "asio/generic/raw_protocol.hpp"
+#include "asio/generic/seq_packet_protocol.hpp"
+#include "asio/generic/stream_protocol.hpp"
+#include "asio/handler_alloc_hook.hpp"
+#include "asio/handler_continuation_hook.hpp"
+#include "asio/handler_invoke_hook.hpp"
+#include "asio/high_resolution_timer.hpp"
+#include "asio/io_context.hpp"
+#include "asio/io_context_strand.hpp"
+#include "asio/io_service.hpp"
+#include "asio/io_service_strand.hpp"
+#include "asio/ip/address.hpp"
+#include "asio/ip/address_v4.hpp"
+#include "asio/ip/address_v4_iterator.hpp"
+#include "asio/ip/address_v4_range.hpp"
+#include "asio/ip/address_v6.hpp"
+#include "asio/ip/address_v6_iterator.hpp"
+#include "asio/ip/address_v6_range.hpp"
+#include "asio/ip/network_v4.hpp"
+#include "asio/ip/network_v6.hpp"
+#include "asio/ip/bad_address_cast.hpp"
+#include "asio/ip/basic_endpoint.hpp"
+#include "asio/ip/basic_resolver.hpp"
+#include "asio/ip/basic_resolver_entry.hpp"
+#include "asio/ip/basic_resolver_iterator.hpp"
+#include "asio/ip/basic_resolver_query.hpp"
+#include "asio/ip/host_name.hpp"
+#include "asio/ip/icmp.hpp"
+#include "asio/ip/multicast.hpp"
+#include "asio/ip/resolver_base.hpp"
+#include "asio/ip/resolver_query_base.hpp"
+#include "asio/ip/tcp.hpp"
+#include "asio/ip/udp.hpp"
+#include "asio/ip/unicast.hpp"
+#include "asio/ip/v6_only.hpp"
+#include "asio/is_applicable_property.hpp"
+#include "asio/is_executor.hpp"
+#include "asio/is_read_buffered.hpp"
+#include "asio/is_write_buffered.hpp"
+#include "asio/local/basic_endpoint.hpp"
+#include "asio/local/connect_pair.hpp"
+#include "asio/local/datagram_protocol.hpp"
+#include "asio/local/stream_protocol.hpp"
+#include "asio/multiple_exceptions.hpp"
+#include "asio/packaged_task.hpp"
+#include "asio/placeholders.hpp"
+#include "asio/posix/basic_descriptor.hpp"
+#include "asio/posix/basic_stream_descriptor.hpp"
+#include "asio/posix/descriptor.hpp"
+#include "asio/posix/descriptor_base.hpp"
+#include "asio/posix/stream_descriptor.hpp"
+#include "asio/post.hpp"
+#include "asio/prefer.hpp"
+#include "asio/query.hpp"
+#include "asio/read.hpp"
+#include "asio/read_at.hpp"
+#include "asio/read_until.hpp"
+#include "asio/redirect_error.hpp"
+#include "asio/require.hpp"
+#include "asio/require_concept.hpp"
+#include "asio/serial_port.hpp"
+#include "asio/serial_port_base.hpp"
+#include "asio/signal_set.hpp"
+#include "asio/socket_base.hpp"
+#include "asio/static_thread_pool.hpp"
+#include "asio/steady_timer.hpp"
+#include "asio/strand.hpp"
+#include "asio/streambuf.hpp"
+#include "asio/system_context.hpp"
+#include "asio/system_error.hpp"
+#include "asio/system_executor.hpp"
+#include "asio/system_timer.hpp"
+#include "asio/this_coro.hpp"
+#include "asio/thread.hpp"
+#include "asio/thread_pool.hpp"
+#include "asio/time_traits.hpp"
+#include "asio/use_awaitable.hpp"
+#include "asio/use_future.hpp"
+#include "asio/uses_executor.hpp"
+#include "asio/version.hpp"
+#include "asio/wait_traits.hpp"
+#include "asio/windows/basic_object_handle.hpp"
+#include "asio/windows/basic_overlapped_handle.hpp"
+#include "asio/windows/basic_random_access_handle.hpp"
+#include "asio/windows/basic_stream_handle.hpp"
+#include "asio/windows/object_handle.hpp"
+#include "asio/windows/overlapped_handle.hpp"
+#include "asio/windows/overlapped_ptr.hpp"
+#include "asio/windows/random_access_handle.hpp"
+#include "asio/windows/stream_handle.hpp"
+#include "asio/write.hpp"
+#include "asio/write_at.hpp"
+
+#endif // ASIO_HPP
diff --git a/cpp/third_party/asio/1.18.2/include/asio/any_io_executor.hpp b/cpp/third_party/asio/1.18.2/include/asio/any_io_executor.hpp
new file mode 100644
index 0000000..5f2c13f
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio/any_io_executor.hpp
@@ -0,0 +1,300 @@
+//
+// any_io_executor.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_ANY_IO_EXECUTOR_HPP
+#define ASIO_ANY_IO_EXECUTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#if defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
+# include "asio/executor.hpp"
+#else // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
+# include "asio/execution.hpp"
+# include "asio/execution_context.hpp"
+#endif // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+
+#if defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
+
+typedef executor any_io_executor;
+
+#else // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
+
+/// Polymorphic executor type for use with I/O objects.
+/**
+ * The @c any_io_executor type is a polymorphic executor that supports the set
+ * of properties required by I/O objects. It is defined as the
+ * execution::any_executor class template parameterised as follows:
+ * @code execution::any_executor<
+ *   execution::context_as_t<execution_context&>,
+ *   execution::blocking_t::never_t,
+ *   execution::prefer_only<execution::blocking_t::possibly_t>,
+ *   execution::prefer_only<execution::outstanding_work_t::tracked_t>,
+ *   execution::prefer_only<execution::outstanding_work_t::untracked_t>,
+ *   execution::prefer_only<execution::relationship_t::fork_t>,
+ *   execution::prefer_only<execution::relationship_t::continuation_t>
+ * > @endcode
+ */
+class any_io_executor :
+#if defined(GENERATING_DOCUMENTATION)
+  public execution::any_executor<...>
+#else // defined(GENERATING_DOCUMENTATION)
+  public execution::any_executor<
+      execution::context_as_t<execution_context&>,
+      execution::blocking_t::never_t,
+      execution::prefer_only<execution::blocking_t::possibly_t>,
+      execution::prefer_only<execution::outstanding_work_t::tracked_t>,
+      execution::prefer_only<execution::outstanding_work_t::untracked_t>,
+      execution::prefer_only<execution::relationship_t::fork_t>,
+      execution::prefer_only<execution::relationship_t::continuation_t>
+    >
+#endif // defined(GENERATING_DOCUMENTATION)
+{
+public:
+#if !defined(GENERATING_DOCUMENTATION)
+  typedef execution::any_executor<
+      execution::context_as_t<execution_context&>,
+      execution::blocking_t::never_t,
+      execution::prefer_only<execution::blocking_t::possibly_t>,
+      execution::prefer_only<execution::outstanding_work_t::tracked_t>,
+      execution::prefer_only<execution::outstanding_work_t::untracked_t>,
+      execution::prefer_only<execution::relationship_t::fork_t>,
+      execution::prefer_only<execution::relationship_t::continuation_t>
+    > base_type;
+
+  typedef void supportable_properties_type(
+      execution::context_as_t<execution_context&>,
+      execution::blocking_t::never_t,
+      execution::prefer_only<execution::blocking_t::possibly_t>,
+      execution::prefer_only<execution::outstanding_work_t::tracked_t>,
+      execution::prefer_only<execution::outstanding_work_t::untracked_t>,
+      execution::prefer_only<execution::relationship_t::fork_t>,
+      execution::prefer_only<execution::relationship_t::continuation_t>
+    );
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+  /// Default constructor.
+  any_io_executor() ASIO_NOEXCEPT
+    : base_type()
+  {
+  }
+
+  /// Construct in an empty state. Equivalent effects to default constructor.
+  any_io_executor(nullptr_t) ASIO_NOEXCEPT
+    : base_type(nullptr_t())
+  {
+  }
+
+  /// Copy constructor.
+  any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT
+    : base_type(static_cast<const base_type&>(e))
+  {
+  }
+
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move constructor.
+  any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT
+    : base_type(static_cast<base_type&&>(e))
+  {
+  }
+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Construct to point to the same target as another any_executor.
+#if defined(GENERATING_DOCUMENTATION)
+  template <class... OtherSupportableProperties>
+    any_io_executor(execution::any_executor<OtherSupportableProperties...> e);
+#else // defined(GENERATING_DOCUMENTATION)
+  template <typename OtherAnyExecutor>
+  any_io_executor(OtherAnyExecutor e,
+      typename constraint<
+        conditional<
+          !is_same<OtherAnyExecutor, any_io_executor>::value
+            && is_base_of<execution::detail::any_executor_base,
+              OtherAnyExecutor>::value,
+          typename execution::detail::supportable_properties<
+            0, supportable_properties_type>::template
+              is_valid_target<OtherAnyExecutor>,
+          false_type
+        >::type::value
+      >::type = 0)
+    : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e))
+  {
+  }
+#endif // defined(GENERATING_DOCUMENTATION)
+
+  /// Construct a polymorphic wrapper for the specified executor.
+#if defined(GENERATING_DOCUMENTATION)
+  template <ASIO_EXECUTION_EXECUTOR Executor>
+  any_io_executor(Executor e);
+#else // defined(GENERATING_DOCUMENTATION)
+  template <ASIO_EXECUTION_EXECUTOR Executor>
+  any_io_executor(Executor e,
+      typename constraint<
+        conditional<
+          !is_same<Executor, any_io_executor>::value
+            && !is_base_of<execution::detail::any_executor_base,
+              Executor>::value,
+          execution::detail::is_valid_target_executor<
+            Executor, supportable_properties_type>,
+          false_type
+        >::type::value
+      >::type = 0)
+    : base_type(ASIO_MOVE_CAST(Executor)(e))
+  {
+  }
+#endif // defined(GENERATING_DOCUMENTATION)
+
+  /// Assignment operator.
+  any_io_executor& operator=(const any_io_executor& e) ASIO_NOEXCEPT
+  {
+    base_type::operator=(static_cast<const base_type&>(e));
+    return *this;
+  }
+
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move assignment operator.
+  any_io_executor& operator=(any_io_executor&& e) ASIO_NOEXCEPT
+  {
+    base_type::operator=(static_cast<base_type&&>(e));
+    return *this;
+  }
+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Assignment operator that sets the polymorphic wrapper to the empty state.
+  any_io_executor& operator=(nullptr_t)
+  {
+    base_type::operator=(nullptr_t());
+    return *this;
+  }
+
+  /// Destructor.
+  ~any_io_executor()
+  {
+  }
+
+  /// Swap targets with another polymorphic wrapper.
+  void swap(any_io_executor& other) ASIO_NOEXCEPT
+  {
+    static_cast<base_type&>(*this).swap(static_cast<base_type&>(other));
+  }
+
+  /// Obtain a polymorphic wrapper with the specified property.
+  /**
+   * Do not call this function directly. It is intended for use with the
+   * asio::require and asio::prefer customisation points.
+   *
+   * For example:
+   * @code any_io_executor ex = ...;
+   * auto ex2 = asio::require(ex, execution::blocking.possibly); @endcode
+   */
+  template <typename Property>
+  any_io_executor require(const Property& p,
+      typename constraint<
+        traits::require_member<const base_type&, const Property&>::is_valid
+      >::type = 0) const
+  {
+    return static_cast<const base_type&>(*this).require(p);
+  }
+
+  /// Obtain a polymorphic wrapper with the specified property.
+  /**
+   * Do not call this function directly. It is intended for use with the
+   * asio::prefer customisation point.
+   *
+   * For example:
+   * @code any_io_executor ex = ...;
+   * auto ex2 = asio::prefer(ex, execution::blocking.possibly); @endcode
+   */
+  template <typename Property>
+  any_io_executor prefer(const Property& p,
+      typename constraint<
+        traits::prefer_member<const base_type&, const Property&>::is_valid
+      >::type = 0) const
+  {
+    return static_cast<const base_type&>(*this).prefer(p);
+  }
+};
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+namespace traits {
+
+#if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
+
+template <>
+struct equality_comparable<any_io_executor>
+{
+  static const bool is_valid = true;
+  static const bool is_noexcept = true;
+};
+
+#endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
+
+#if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
+
+template <typename F>
+struct execute_member<any_io_executor, F>
+{
+  static const bool is_valid = true;
+  static const bool is_noexcept = false;
+  typedef void result_type;
+};
+
+#endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
+
+#if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
+
+template <typename Prop>
+struct query_member<any_io_executor, Prop> :
+  query_member<any_io_executor::base_type, Prop>
+{
+};
+
+#endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
+
+#if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
+
+template <typename Prop>
+struct require_member<any_io_executor, Prop> :
+  require_member<any_io_executor::base_type, Prop>
+{
+  typedef any_io_executor result_type;
+};
+
+#endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
+
+#if !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
+
+template <typename Prop>
+struct prefer_member<any_io_executor, Prop> :
+  prefer_member<any_io_executor::base_type, Prop>
+{
+  typedef any_io_executor result_type;
+};
+
+#endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
+
+} // namespace traits
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+#endif // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_ANY_IO_EXECUTOR_HPP
diff --git a/cpp/third_party/asio/1.18.2/include/asio/associated_allocator.hpp b/cpp/third_party/asio/1.18.2/include/asio/associated_allocator.hpp
new file mode 100644
index 0000000..8e7a345
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio/associated_allocator.hpp
@@ -0,0 +1,125 @@
+//
+// associated_allocator.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_ASSOCIATED_ALLOCATOR_HPP
+#define ASIO_ASSOCIATED_ALLOCATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include <memory>
+#include "asio/detail/type_traits.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace detail {
+
+template <typename T, typename E, typename = void>
+struct associated_allocator_impl
+{
+  typedef E type;
+
+  static type get(const T&, const E& e) ASIO_NOEXCEPT
+  {
+    return e;
+  }
+};
+
+template <typename T, typename E>
+struct associated_allocator_impl<T, E,
+  typename void_type<typename T::allocator_type>::type>
+{
+  typedef typename T::allocator_type type;
+
+  static type get(const T& t, const E&) ASIO_NOEXCEPT
+  {
+    return t.get_allocator();
+  }
+};
+
+} // namespace detail
+
+/// Traits type used to obtain the allocator associated with an object.
+/**
+ * A program may specialise this traits type if the @c T template parameter in
+ * the specialisation is a user-defined type. The template parameter @c
+ * Allocator shall be a type meeting the Allocator requirements.
+ *
+ * Specialisations shall meet the following requirements, where @c t is a const
+ * reference to an object of type @c T, and @c a is an object of type @c
+ * Allocator.
+ *
+ * @li Provide a nested typedef @c type that identifies a type meeting the
+ * Allocator requirements.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t) and with return type @c type.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t,a) and with return type @c type.
+ */
+template <typename T, typename Allocator = std::allocator<void> >
+struct associated_allocator
+{
+  /// If @c T has a nested type @c allocator_type, <tt>T::allocator_type</tt>.
+  /// Otherwise @c Allocator.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef see_below type;
+#else // defined(GENERATING_DOCUMENTATION)
+  typedef typename detail::associated_allocator_impl<T, Allocator>::type type;
+#endif // defined(GENERATING_DOCUMENTATION)
+
+  /// If @c T has a nested type @c allocator_type, returns
+  /// <tt>t.get_allocator()</tt>. Otherwise returns @c a.
+  static type get(const T& t,
+      const Allocator& a = Allocator()) ASIO_NOEXCEPT
+  {
+    return detail::associated_allocator_impl<T, Allocator>::get(t, a);
+  }
+};
+
+/// Helper function to obtain an object's associated allocator.
+/**
+ * @returns <tt>associated_allocator<T>::get(t)</tt>
+ */
+template <typename T>
+inline typename associated_allocator<T>::type
+get_associated_allocator(const T& t) ASIO_NOEXCEPT
+{
+  return associated_allocator<T>::get(t);
+}
+
+/// Helper function to obtain an object's associated allocator.
+/**
+ * @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>
+ */
+template <typename T, typename Allocator>
+inline typename associated_allocator<T, Allocator>::type
+get_associated_allocator(const T& t, const Allocator& a) ASIO_NOEXCEPT
+{
+  return associated_allocator<T, Allocator>::get(t, a);
+}
+
+#if defined(ASIO_HAS_ALIAS_TEMPLATES)
+
+template <typename T, typename Allocator = std::allocator<void> >
+using associated_allocator_t
+  = typename associated_allocator<T, Allocator>::type;
+
+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_ASSOCIATED_ALLOCATOR_HPP
diff --git a/cpp/third_party/asio/1.18.2/include/asio/associated_executor.hpp b/cpp/third_party/asio/1.18.2/include/asio/associated_executor.hpp
new file mode 100644
index 0000000..3da1a6b
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio/associated_executor.hpp
@@ -0,0 +1,166 @@
+//
+// associated_executor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_ASSOCIATED_EXECUTOR_HPP
+#define ASIO_ASSOCIATED_EXECUTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include "asio/detail/type_traits.hpp"
+#include "asio/execution/executor.hpp"
+#include "asio/is_executor.hpp"
+#include "asio/system_executor.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace detail {
+
+template <typename T, typename E, typename = void>
+struct associated_executor_impl
+{
+  typedef void asio_associated_executor_is_unspecialised;
+
+  typedef E type;
+
+  static type get(const T&, const E& e = E()) ASIO_NOEXCEPT
+  {
+    return e;
+  }
+};
+
+template <typename T, typename E>
+struct associated_executor_impl<T, E,
+  typename void_type<typename T::executor_type>::type>
+{
+  typedef typename T::executor_type type;
+
+  static type get(const T& t, const E& = E()) ASIO_NOEXCEPT
+  {
+    return t.get_executor();
+  }
+};
+
+} // namespace detail
+
+/// Traits type used to obtain the executor associated with an object.
+/**
+ * A program may specialise this traits type if the @c T template parameter in
+ * the specialisation is a user-defined type. The template parameter @c
+ * Executor shall be a type meeting the Executor requirements.
+ *
+ * Specialisations shall meet the following requirements, where @c t is a const
+ * reference to an object of type @c T, and @c e is an object of type @c
+ * Executor.
+ *
+ * @li Provide a nested typedef @c type that identifies a type meeting the
+ * Executor requirements.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t) and with return type @c type.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t,e) and with return type @c type.
+ */
+template <typename T, typename Executor = system_executor>
+struct associated_executor
+#if !defined(GENERATING_DOCUMENTATION)
+  : detail::associated_executor_impl<T, Executor>
+#endif // !defined(GENERATING_DOCUMENTATION)
+{
+#if defined(GENERATING_DOCUMENTATION)
+  /// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>.
+  /// Otherwise @c Executor.
+  typedef see_below type;
+
+  /// If @c T has a nested type @c executor_type, returns
+  /// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
+  static type get(const T& t,
+      const Executor& ex = Executor()) ASIO_NOEXCEPT;
+#endif // defined(GENERATING_DOCUMENTATION)
+};
+
+/// Helper function to obtain an object's associated executor.
+/**
+ * @returns <tt>associated_executor<T>::get(t)</tt>
+ */
+template <typename T>
+inline typename associated_executor<T>::type
+get_associated_executor(const T& t) ASIO_NOEXCEPT
+{
+  return associated_executor<T>::get(t);
+}
+
+/// Helper function to obtain an object's associated executor.
+/**
+ * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
+ */
+template <typename T, typename Executor>
+inline typename associated_executor<T, Executor>::type
+get_associated_executor(const T& t, const Executor& ex,
+    typename constraint<
+      is_executor<Executor>::value || execution::is_executor<Executor>::value
+    >::type = 0) ASIO_NOEXCEPT
+{
+  return associated_executor<T, Executor>::get(t, ex);
+}
+
+/// Helper function to obtain an object's associated executor.
+/**
+ * @returns <tt>associated_executor<T, typename
+ * ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
+ */
+template <typename T, typename ExecutionContext>
+inline typename associated_executor<T,
+  typename ExecutionContext::executor_type>::type
+get_associated_executor(const T& t, ExecutionContext& ctx,
+    typename constraint<is_convertible<ExecutionContext&,
+      execution_context&>::value>::type = 0) ASIO_NOEXCEPT
+{
+  return associated_executor<T,
+    typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
+}
+
+#if defined(ASIO_HAS_ALIAS_TEMPLATES)
+
+template <typename T, typename Executor = system_executor>
+using associated_executor_t = typename associated_executor<T, Executor>::type;
+
+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)
+
+namespace detail {
+
+template <typename T, typename E, typename = void>
+struct associated_executor_forwarding_base
+{
+};
+
+template <typename T, typename E>
+struct associated_executor_forwarding_base<T, E,
+    typename enable_if<
+      is_same<
+        typename associated_executor<T,
+          E>::asio_associated_executor_is_unspecialised,
+        void
+      >::value
+    >::type>
+{
+  typedef void asio_associated_executor_is_unspecialised;
+};
+
+} // namespace detail
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_ASSOCIATED_EXECUTOR_HPP
diff --git a/cpp/third_party/asio/1.18.2/include/asio/async_result.hpp b/cpp/third_party/asio/1.18.2/include/asio/async_result.hpp
new file mode 100644
index 0000000..56bdcc3
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio/async_result.hpp
@@ -0,0 +1,582 @@
+//
+// async_result.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_ASYNC_RESULT_HPP
+#define ASIO_ASYNC_RESULT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include "asio/detail/type_traits.hpp"
+#include "asio/detail/variadic_templates.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+
+#if defined(ASIO_HAS_CONCEPTS) \
+  && defined(ASIO_HAS_VARIADIC_TEMPLATES) \
+  && defined(ASIO_HAS_DECLTYPE)
+
+namespace detail {
+
+template <typename T>
+struct is_completion_signature : false_type
+{
+};
+
+template <typename R, typename... Args>
+struct is_completion_signature<R(Args...)> : true_type
+{
+};
+
+template <typename T, typename... Args>
+ASIO_CONCEPT callable_with = requires(T t, Args&&... args)
+{
+  t(static_cast<Args&&>(args)...);
+};
+
+template <typename T, typename Signature>
+struct is_completion_handler_for : false_type
+{
+};
+
+template <typename T, typename R, typename... Args>
+struct is_completion_handler_for<T, R(Args...)>
+  : integral_constant<bool, (callable_with<T, Args...>)>
+{
+};
+
+} // namespace detail
+
+template <typename T>
+ASIO_CONCEPT completion_signature =
+  detail::is_completion_signature<T>::value;
+
+#define ASIO_COMPLETION_SIGNATURE \
+  ::asio::completion_signature
+
+template <typename T, typename Signature>
+ASIO_CONCEPT completion_handler_for =
+  detail::is_completion_signature<Signature>::value
+    && detail::is_completion_handler_for<T, Signature>::value;
+
+#define ASIO_COMPLETION_HANDLER_FOR(s) \
+  ::asio::completion_handler_for<s>
+
+#else // defined(ASIO_HAS_CONCEPTS)
+      //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)
+      //   && defined(ASIO_HAS_DECLTYPE)
+
+#define ASIO_COMPLETION_SIGNATURE typename
+#define ASIO_COMPLETION_HANDLER_FOR(s) typename
+
+#endif // defined(ASIO_HAS_CONCEPTS)
+       //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)
+       //   && defined(ASIO_HAS_DECLTYPE)
+
+/// An interface for customising the behaviour of an initiating function.
+/**
+ * The async_result traits class is used for determining:
+ *
+ * @li the concrete completion handler type to be called at the end of the
+ * asynchronous operation;
+ *
+ * @li the initiating function return type; and
+ *
+ * @li how the return value of the initiating function is obtained.
+ *
+ * The trait allows the handler and return types to be determined at the point
+ * where the specific completion handler signature is known.
+ *
+ * This template may be specialised for user-defined completion token types.
+ * The primary template assumes that the CompletionToken is the completion
+ * handler.
+ */
+template <typename CompletionToken, ASIO_COMPLETION_SIGNATURE Signature>
+class async_result
+{
+public:
+  /// The concrete completion handler type for the specific signature.
+  typedef CompletionToken completion_handler_type;
+
+  /// The return type of the initiating function.
+  typedef void return_type;
+
+  /// Construct an async result from a given handler.
+  /**
+   * When using a specalised async_result, the constructor has an opportunity
+   * to initialise some state associated with the completion handler, which is
+   * then returned from the initiating function.
+   */
+  explicit async_result(completion_handler_type& h)
+  {
+    (void)h;
+  }
+
+  /// Obtain the value to be returned from the initiating function.
+  return_type get()
+  {
+  }
+
+#if defined(GENERATING_DOCUMENTATION)
+
+  /// Initiate the asynchronous operation that will produce the result, and
+  /// obtain the value to be returned from the initiating function.
+  template <typename Initiation, typename RawCompletionToken, typename... Args>
+  static return_type initiate(
+      ASIO_MOVE_ARG(Initiation) initiation,
+      ASIO_MOVE_ARG(RawCompletionToken) token,
+      ASIO_MOVE_ARG(Args)... args);
+
+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+  template <typename Initiation,
+      ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken,
+      typename... Args>
+  static return_type initiate(
+      ASIO_MOVE_ARG(Initiation) initiation,
+      ASIO_MOVE_ARG(RawCompletionToken) token,
+      ASIO_MOVE_ARG(Args)... args)
+  {
+    ASIO_MOVE_CAST(Initiation)(initiation)(
+        ASIO_MOVE_CAST(RawCompletionToken)(token),
+        ASIO_MOVE_CAST(Args)(args)...);
+  }
+
+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+  template <typename Initiation,
+      ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken>
+  static return_type initiate(
+      ASIO_MOVE_ARG(Initiation) initiation,
+      ASIO_MOVE_ARG(RawCompletionToken) token)
+  {
+    ASIO_MOVE_CAST(Initiation)(initiation)(
+        ASIO_MOVE_CAST(RawCompletionToken)(token));
+  }
+
+#define ASIO_PRIVATE_INITIATE_DEF(n) \
+  template <typename Initiation, \
+      ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken, \
+      ASIO_VARIADIC_TPARAMS(n)> \
+  static return_type initiate( \
+      ASIO_MOVE_ARG(Initiation) initiation, \
+      ASIO_MOVE_ARG(RawCompletionToken) token, \
+      ASIO_VARIADIC_MOVE_PARAMS(n)) \
+  { \
+    ASIO_MOVE_CAST(Initiation)(initiation)( \
+        ASIO_MOVE_CAST(RawCompletionToken)(token), \
+        ASIO_VARIADIC_MOVE_ARGS(n)); \
+  } \
+  /**/
+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)
+#undef ASIO_PRIVATE_INITIATE_DEF
+
+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+private:
+  async_result(const async_result&) ASIO_DELETED;
+  async_result& operator=(const async_result&) ASIO_DELETED;
+};
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <ASIO_COMPLETION_SIGNATURE Signature>
+class async_result<void, Signature>
+{
+  // Empty.
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+/// Helper template to deduce the handler type from a CompletionToken, capture
+/// a local copy of the handler, and then create an async_result for the
+/// handler.
+template <typename CompletionToken, ASIO_COMPLETION_SIGNATURE Signature>
+struct async_completion
+{
+  /// The real handler type to be used for the asynchronous operation.
+  typedef typename asio::async_result<
+    typename decay<CompletionToken>::type,
+      Signature>::completion_handler_type completion_handler_type;
+
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Constructor.
+  /**
+   * The constructor creates the concrete completion handler and makes the link
+   * between the handler and the asynchronous result.
+   */
+  explicit async_completion(CompletionToken& token)
+    : completion_handler(static_cast<typename conditional<
+        is_same<CompletionToken, completion_handler_type>::value,
+        completion_handler_type&, CompletionToken&&>::type>(token)),
+      result(completion_handler)
+  {
+  }
+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  explicit async_completion(typename decay<CompletionToken>::type& token)
+    : completion_handler(token),
+      result(completion_handler)
+  {
+  }
+
+  explicit async_completion(const typename decay<CompletionToken>::type& token)
+    : completion_handler(token),
+      result(completion_handler)
+  {
+  }
+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// A copy of, or reference to, a real handler object.
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  typename conditional<
+    is_same<CompletionToken, completion_handler_type>::value,
+    completion_handler_type&, completion_handler_type>::type completion_handler;
+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  completion_handler_type completion_handler;
+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// The result of the asynchronous operation's initiating function.
+  async_result<typename decay<CompletionToken>::type, Signature> result;
+};
+
+namespace detail {
+
+template <typename CompletionToken, typename Signature>
+struct async_result_helper
+  : async_result<typename decay<CompletionToken>::type, Signature>
+{
+};
+
+struct async_result_memfns_base
+{
+  void initiate();
+};
+
+template <typename T>
+struct async_result_memfns_derived
+  : T, async_result_memfns_base
+{
+};
+
+template <typename T, T>
+struct async_result_memfns_check
+{
+};
+
+template <typename>
+char (&async_result_initiate_memfn_helper(...))[2];
+
+template <typename T>
+char async_result_initiate_memfn_helper(
+    async_result_memfns_check<
+      void (async_result_memfns_base::*)(),
+      &async_result_memfns_derived<T>::initiate>*);
+
+template <typename CompletionToken, typename Signature>
+struct async_result_has_initiate_memfn
+  : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
+      async_result<typename decay<CompletionToken>::type, Signature>
+    >(0)) != 1>
+{
+};
+
+} // namespace detail
+
+#if defined(GENERATING_DOCUMENTATION)
+# define ASIO_INITFN_RESULT_TYPE(ct, sig) \
+  void_or_deduced
+#elif defined(_MSC_VER) && (_MSC_VER < 1500)
+# define ASIO_INITFN_RESULT_TYPE(ct, sig) \
+  typename ::asio::detail::async_result_helper< \
+    ct, sig>::return_type
+#define ASIO_HANDLER_TYPE(ct, sig) \
+  typename ::asio::detail::async_result_helper< \
+    ct, sig>::completion_handler_type
+#else
+# define ASIO_INITFN_RESULT_TYPE(ct, sig) \
+  typename ::asio::async_result< \
+    typename ::asio::decay<ct>::type, sig>::return_type
+#define ASIO_HANDLER_TYPE(ct, sig) \
+  typename ::asio::async_result< \
+    typename ::asio::decay<ct>::type, sig>::completion_handler_type
+#endif
+
+#if defined(GENERATING_DOCUMENTATION)
+# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
+  auto
+#elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)
+# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
+  auto
+#else
+# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
+  ASIO_INITFN_RESULT_TYPE(ct, sig)
+#endif
+
+#if defined(GENERATING_DOCUMENTATION)
+# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
+  void_or_deduced
+#elif defined(ASIO_HAS_DECLTYPE)
+# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
+  decltype expr
+#else
+# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
+  ASIO_INITFN_RESULT_TYPE(ct, sig)
+#endif
+
+#if defined(GENERATING_DOCUMENTATION)
+
+template <typename CompletionToken,
+    completion_signature Signature,
+    typename Initiation, typename... Args>
+void_or_deduced async_initiate(
+    ASIO_MOVE_ARG(Initiation) initiation,
+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),
+    ASIO_MOVE_ARG(Args)... args);
+
+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+template <typename CompletionToken,
+    ASIO_COMPLETION_SIGNATURE Signature,
+    typename Initiation, typename... Args>
+inline typename constraint<
+    detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
+    ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature,
+      (async_result<typename decay<CompletionToken>::type,
+        Signature>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),
+          declval<ASIO_MOVE_ARG(CompletionToken)>(),
+          declval<ASIO_MOVE_ARG(Args)>()...)))>::type
+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
+    ASIO_MOVE_ARG(Args)... args)
+{
+  return async_result<typename decay<CompletionToken>::type,
+    Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
+      ASIO_MOVE_CAST(CompletionToken)(token),
+      ASIO_MOVE_CAST(Args)(args)...);
+}
+
+template <typename CompletionToken,
+    ASIO_COMPLETION_SIGNATURE Signature,
+    typename Initiation, typename... Args>
+inline typename constraint<
+    !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
+    ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
+    ASIO_MOVE_ARG(Args)... args)
+{
+  async_completion<CompletionToken, Signature> completion(token);
+
+  ASIO_MOVE_CAST(Initiation)(initiation)(
+      ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,
+        Signature))(completion.completion_handler),
+      ASIO_MOVE_CAST(Args)(args)...);
+
+  return completion.result.get();
+}
+
+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+template <typename CompletionToken,
+    ASIO_COMPLETION_SIGNATURE Signature,
+    typename Initiation>
+inline typename constraint<
+    detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
+    ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature,
+      (async_result<typename decay<CompletionToken>::type,
+        Signature>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),
+          declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type
+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
+{
+  return async_result<typename decay<CompletionToken>::type,
+    Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
+      ASIO_MOVE_CAST(CompletionToken)(token));
+}
+
+template <typename CompletionToken,
+    ASIO_COMPLETION_SIGNATURE Signature,
+    typename Initiation>
+inline typename constraint<
+    !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
+    ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
+{
+  async_completion<CompletionToken, Signature> completion(token);
+
+  ASIO_MOVE_CAST(Initiation)(initiation)(
+      ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,
+        Signature))(completion.completion_handler));
+
+  return completion.result.get();
+}
+
+#define ASIO_PRIVATE_INITIATE_DEF(n) \
+  template <typename CompletionToken, \
+      ASIO_COMPLETION_SIGNATURE Signature, \
+      typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
+  inline typename constraint< \
+      detail::async_result_has_initiate_memfn< \
+        CompletionToken, Signature>::value, \
+      ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, \
+        (async_result<typename decay<CompletionToken>::type, \
+          Signature>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(), \
+            declval<ASIO_MOVE_ARG(CompletionToken)>(), \
+            ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \
+  async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
+      ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
+      ASIO_VARIADIC_MOVE_PARAMS(n)) \
+  { \
+    return async_result<typename decay<CompletionToken>::type, \
+      Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation), \
+        ASIO_MOVE_CAST(CompletionToken)(token), \
+        ASIO_VARIADIC_MOVE_ARGS(n)); \
+  } \
+  \
+  template <typename CompletionToken, \
+      ASIO_COMPLETION_SIGNATURE Signature, \
+      typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
+  inline typename constraint< \
+      !detail::async_result_has_initiate_memfn< \
+        CompletionToken, Signature>::value, \
+      ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
+  async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
+      ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
+      ASIO_VARIADIC_MOVE_PARAMS(n)) \
+  { \
+    async_completion<CompletionToken, Signature> completion(token); \
+  \
+    ASIO_MOVE_CAST(Initiation)(initiation)( \
+        ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, \
+          Signature))(completion.completion_handler), \
+        ASIO_VARIADIC_MOVE_ARGS(n)); \
+  \
+    return completion.result.get(); \
+  } \
+  /**/
+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)
+#undef ASIO_PRIVATE_INITIATE_DEF
+
+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+#if defined(ASIO_HAS_CONCEPTS) \
+  && defined(ASIO_HAS_VARIADIC_TEMPLATES) \
+  && defined(ASIO_HAS_DECLTYPE)
+
+namespace detail {
+
+template <typename Signature>
+struct initiation_archetype
+{
+  template <completion_handler_for<Signature> CompletionHandler>
+  void operator()(CompletionHandler&&) const
+  {
+  }
+};
+
+} // namespace detail
+
+template <typename T, typename Signature>
+ASIO_CONCEPT completion_token_for =
+  detail::is_completion_signature<Signature>::value
+  &&
+  requires(T&& t)
+  {
+    async_initiate<T, Signature>(detail::initiation_archetype<Signature>{}, t);
+  };
+
+#define ASIO_COMPLETION_TOKEN_FOR(s) \
+  ::asio::completion_token_for<s>
+
+#else // defined(ASIO_HAS_CONCEPTS)
+      //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)
+      //   && defined(ASIO_HAS_DECLTYPE)
+
+#define ASIO_COMPLETION_TOKEN_FOR(s) typename
+
+#endif // defined(ASIO_HAS_CONCEPTS)
+       //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)
+       //   && defined(ASIO_HAS_DECLTYPE)
+
+namespace detail {
+
+template <typename T, typename = void>
+struct default_completion_token_impl
+{
+  typedef void type;
+};
+
+template <typename T>
+struct default_completion_token_impl<T,
+  typename void_type<typename T::default_completion_token_type>::type>
+{
+  typedef typename T::default_completion_token_type type;
+};
+
+} // namespace detail
+
+#if defined(GENERATING_DOCUMENTATION)
+
+/// Traits type used to determine the default completion token type associated
+/// with a type (such as an executor).
+/**
+ * A program may specialise this traits type if the @c T template parameter in
+ * the specialisation is a user-defined type.
+ *
+ * Specialisations of this trait may provide a nested typedef @c type, which is
+ * a default-constructible completion token type.
+ */
+template <typename T>
+struct default_completion_token
+{
+  /// If @c T has a nested type @c default_completion_token_type,
+  /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type
+  /// is not defined.
+  typedef see_below type;
+};
+#else
+template <typename T>
+struct default_completion_token
+  : detail::default_completion_token_impl<T>
+{
+};
+#endif
+
+#if defined(ASIO_HAS_ALIAS_TEMPLATES)
+
+template <typename T>
+using default_completion_token_t = typename default_completion_token<T>::type;
+
+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)
+
+#if defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
+
+#define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \
+  = typename ::asio::default_completion_token<e>::type
+#define ASIO_DEFAULT_COMPLETION_TOKEN(e) \
+  = typename ::asio::default_completion_token<e>::type()
+
+#else // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
+
+#define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e)
+#define ASIO_DEFAULT_COMPLETION_TOKEN(e)
+
+#endif // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_ASYNC_RESULT_HPP
diff --git a/cpp/third_party/asio/1.18.2/include/asio/awaitable.hpp b/cpp/third_party/asio/1.18.2/include/asio/awaitable.hpp
new file mode 100644
index 0000000..4897049
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio/awaitable.hpp
@@ -0,0 +1,133 @@
+//
+// awaitable.hpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_AWAITABLE_HPP
+#define ASIO_AWAITABLE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#if defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
+
+#if defined(ASIO_HAS_STD_COROUTINE)
+# include <coroutine>
+#else // defined(ASIO_HAS_STD_COROUTINE)
+# include <experimental/coroutine>
+#endif // defined(ASIO_HAS_STD_COROUTINE)
+
+#include "asio/any_io_executor.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace detail {
+
+#if defined(ASIO_HAS_STD_COROUTINE)
+using std::coroutine_handle;
+using std::suspend_always;
+#else // defined(ASIO_HAS_STD_COROUTINE)
+using std::experimental::coroutine_handle;
+using std::experimental::suspend_always;
+#endif // defined(ASIO_HAS_STD_COROUTINE)
+
+template <typename> class awaitable_thread;
+template <typename, typename> class awaitable_frame;
+
+} // namespace detail
+
+/// The return type of a coroutine or asynchronous operation.
+template <typename T, typename Executor = any_io_executor>
+class awaitable
+{
+public:
+  /// The type of the awaited value.
+  typedef T value_type;
+
+  /// The executor type that will be used for the coroutine.
+  typedef Executor executor_type;
+
+  /// Default constructor.
+  constexpr awaitable() noexcept
+    : frame_(nullptr)
+  {
+  }
+
+  /// Move constructor.
+  awaitable(awaitable&& other) noexcept
+    : frame_(std::exchange(other.frame_, nullptr))
+  {
+  }
+
+  /// Destructor
+  ~awaitable()
+  {
+    if (frame_)
+      frame_->destroy();
+  }
+
+  /// Checks if the awaitable refers to a future result.
+  bool valid() const noexcept
+  {
+    return !!frame_;
+  }
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+  // Support for co_await keyword.
+  bool await_ready() const noexcept
+  {
+    return false;
+  }
+
+  // Support for co_await keyword.
+  template <class U>
+  void await_suspend(
+      detail::coroutine_handle<detail::awaitable_frame<U, Executor>> h)
+  {
+    frame_->push_frame(&h.promise());
+  }
+
+  // Support for co_await keyword.
+  T await_resume()
+  {
+    return awaitable(static_cast<awaitable&&>(*this)).frame_->get();
+  }
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+private:
+  template <typename> friend class detail::awaitable_thread;
+  template <typename, typename> friend class detail::awaitable_frame;
+
+  // Not copy constructible or copy assignable.
+  awaitable(const awaitable&) = delete;
+  awaitable& operator=(const awaitable&) = delete;
+
+  // Construct the awaitable from a coroutine's frame object.
+  explicit awaitable(detail::awaitable_frame<T, Executor>* a)
+    : frame_(a)
+  {
+  }
+
+  detail::awaitable_frame<T, Executor>* frame_;
+};
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#include "asio/impl/awaitable.hpp"
+
+#endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
+
+#endif // ASIO_AWAITABLE_HPP
diff --git a/cpp/third_party/asio/1.18.2/include/asio/basic_datagram_socket.hpp b/cpp/third_party/asio/1.18.2/include/asio/basic_datagram_socket.hpp
new file mode 100644
index 0000000..d9fba8a
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio/basic_datagram_socket.hpp
@@ -0,0 +1,1223 @@
+//
+// basic_datagram_socket.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_BASIC_DATAGRAM_SOCKET_HPP
+#define ASIO_BASIC_DATAGRAM_SOCKET_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include <cstddef>
+#include "asio/basic_socket.hpp"
+#include "asio/detail/handler_type_requirements.hpp"
+#include "asio/detail/non_const_lvalue.hpp"
+#include "asio/detail/throw_error.hpp"
+#include "asio/detail/type_traits.hpp"
+#include "asio/error.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+
+#if !defined(ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
+#define ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = any_io_executor>
+class basic_datagram_socket;
+
+#endif // !defined(ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
+
+/// Provides datagram-oriented socket functionality.
+/**
+ * The basic_datagram_socket class template provides asynchronous and blocking
+ * datagram-oriented socket functionality.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * Synchronous @c send, @c send_to, @c receive, @c receive_from, and @c connect
+ * operations are thread safe with respect to each other, if the underlying
+ * operating system calls are also thread safe. This means that it is permitted
+ * to perform concurrent calls to these synchronous operations on a single
+ * socket object. Other synchronous operations, such as @c open or @c close, are
+ * not thread safe.
+ */
+template <typename Protocol, typename Executor>
+class basic_datagram_socket
+  : public basic_socket<Protocol, Executor>
+{
+public:
+  /// The type of the executor associated with the object.
+  typedef Executor executor_type;
+
+  /// Rebinds the socket type to another executor.
+  template <typename Executor1>
+  struct rebind_executor
+  {
+    /// The socket type when rebound to the specified executor.
+    typedef basic_datagram_socket<Protocol, Executor1> other;
+  };
+
+  /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_handle_type;
+#else
+  typedef typename basic_socket<Protocol,
+    Executor>::native_handle_type native_handle_type;
+#endif
+
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+  /// Construct a basic_datagram_socket without opening it.
+  /**
+   * This constructor creates a datagram socket without opening it. The open()
+   * function must be called before data can be sent or received on the socket.
+   *
+   * @param ex The I/O executor that the socket will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   */
+  explicit basic_datagram_socket(const executor_type& ex)
+    : basic_socket<Protocol, Executor>(ex)
+  {
+  }
+
+  /// Construct a basic_datagram_socket without opening it.
+  /**
+   * This constructor creates a datagram socket without opening it. The open()
+   * function must be called before data can be sent or received on the socket.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the socket will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the socket.
+   */
+  template <typename ExecutionContext>
+  explicit basic_datagram_socket(ExecutionContext& context,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type = 0)
+    : basic_socket<Protocol, Executor>(context)
+  {
+  }
+
+  /// Construct and open a basic_datagram_socket.
+  /**
+   * This constructor creates and opens a datagram socket.
+   *
+   * @param ex The I/O executor that the socket will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  basic_datagram_socket(const executor_type& ex, const protocol_type& protocol)
+    : basic_socket<Protocol, Executor>(ex, protocol)
+  {
+  }
+
+  /// Construct and open a basic_datagram_socket.
+  /**
+   * This constructor creates and opens a datagram socket.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the socket will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  template <typename ExecutionContext>
+  basic_datagram_socket(ExecutionContext& context,
+      const protocol_type& protocol,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value,
+        defaulted_constraint
+      >::type = defaulted_constraint())
+    : basic_socket<Protocol, Executor>(context, protocol)
+  {
+  }
+
+  /// Construct a basic_datagram_socket, opening it and binding it to the given
+  /// local endpoint.
+  /**
+   * This constructor creates a datagram socket and automatically opens it bound
+   * to the specified endpoint on the local machine. The protocol used is the
+   * protocol associated with the given endpoint.
+   *
+   * @param ex The I/O executor that the socket will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param endpoint An endpoint on the local machine to which the datagram
+   * socket will be bound.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint)
+    : basic_socket<Protocol, Executor>(ex, endpoint)
+  {
+  }
+
+  /// Construct a basic_datagram_socket, opening it and binding it to the given
+  /// local endpoint.
+  /**
+   * This constructor creates a datagram socket and automatically opens it bound
+   * to the specified endpoint on the local machine. The protocol used is the
+   * protocol associated with the given endpoint.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the socket will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the socket.
+   *
+   * @param endpoint An endpoint on the local machine to which the datagram
+   * socket will be bound.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  template <typename ExecutionContext>
+  basic_datagram_socket(ExecutionContext& context,
+      const endpoint_type& endpoint,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type = 0)
+    : basic_socket<Protocol, Executor>(context, endpoint)
+  {
+  }
+
+  /// Construct a basic_datagram_socket on an existing native socket.
+  /**
+   * This constructor creates a datagram socket object to hold an existing
+   * native socket.
+   *
+   * @param ex The I/O executor that the socket will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_socket The new underlying socket implementation.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  basic_datagram_socket(const executor_type& ex,
+      const protocol_type& protocol, const native_handle_type& native_socket)
+    : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
+  {
+  }
+
+  /// Construct a basic_datagram_socket on an existing native socket.
+  /**
+   * This constructor creates a datagram socket object to hold an existing
+   * native socket.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the socket will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_socket The new underlying socket implementation.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  template <typename ExecutionContext>
+  basic_datagram_socket(ExecutionContext& context,
+      const protocol_type& protocol, const native_handle_type& native_socket,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type = 0)
+    : basic_socket<Protocol, Executor>(context, protocol, native_socket)
+  {
+  }
+
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_datagram_socket from another.
+  /**
+   * This constructor moves a datagram socket from one object to another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(const executor_type&)
+   * constructor.
+   */
+  basic_datagram_socket(basic_datagram_socket&& other) ASIO_NOEXCEPT
+    : basic_socket<Protocol, Executor>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_datagram_socket from another.
+  /**
+   * This assignment operator moves a datagram socket from one object to
+   * another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(const executor_type&)
+   * constructor.
+   */
+  basic_datagram_socket& operator=(basic_datagram_socket&& other)
+  {
+    basic_socket<Protocol, Executor>::operator=(std::move(other));
+    return *this;
+  }
+
+  /// Move-construct a basic_datagram_socket from a socket of another protocol
+  /// type.
+  /**
+   * This constructor moves a datagram socket from one object to another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(const executor_type&)
+   * constructor.
+   */
+  template <typename Protocol1, typename Executor1>
+  basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
+      typename constraint<
+        is_convertible<Protocol1, Protocol>::value
+          && is_convertible<Executor1, Executor>::value
+      >::type = 0)
+    : basic_socket<Protocol, Executor>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_datagram_socket from a socket of another protocol
+  /// type.
+  /**
+   * This assignment operator moves a datagram socket from one object to
+   * another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(const executor_type&)
+   * constructor.
+   */
+  template <typename Protocol1, typename Executor1>
+  typename constraint<
+    is_convertible<Protocol1, Protocol>::value
+      && is_convertible<Executor1, Executor>::value,
+    basic_datagram_socket&
+  >::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)
+  {
+    basic_socket<Protocol, Executor>::operator=(std::move(other));
+    return *this;
+  }
+#endif // defined(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()
+  {
+  }
+
+  /// 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 asio::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(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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().send(
+        this->impl_.get_implementation(), buffers, 0, ec);
+    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 asio::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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().send(
+        this->impl_.get_implementation(), buffers, flags, ec);
+    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, asio::error_code& ec)
+  {
+    return this->impl_.get_service().send(
+        this->impl_.get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous send on a connected socket.
+  /**
+   * This function is used to asynchronously send data on the datagram socket.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent on the socket. Although
+   * the buffers object may be copied as necessary, ownership of the underlying
+   * memory blocks is retained by the caller, which must guarantee that they
+   * remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @note The async_send operation can only be used with a connected socket.
+   * Use the async_send_to function to send data on an unconnected datagram
+   * socket.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.async_send(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,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) WriteHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
+      void (asio::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      ASIO_MOVE_ARG(WriteHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<WriteHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_send(this), handler,
+        buffers, socket_base::message_flags(0));
+  }
+
+  /// Start an asynchronous send on a connected socket.
+  /**
+   * This function is used to asynchronously send data on the datagram socket.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent on the socket. Although
+   * the buffers object may be copied as necessary, ownership of the underlying
+   * memory blocks is retained by the caller, which must guarantee that they
+   * remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @note The async_send operation can only be used with a connected socket.
+   * Use the async_send_to function to send data on an unconnected datagram
+   * socket.
+   */
+  template <typename ConstBufferSequence,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) WriteHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
+      void (asio::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags,
+      ASIO_MOVE_ARG(WriteHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<WriteHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_send(this), handler, buffers, flags);
+  }
+
+  /// Send a datagram to the specified endpoint.
+  /**
+   * This function is used to send a datagram to the specified remote endpoint.
+   * The function call will block until the data has been sent successfully or
+   * an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * asio::ip::udp::endpoint destination(
+   *     asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.send_to(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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().send_to(
+        this->impl_.get_implementation(), buffers, destination, 0, ec);
+    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 asio::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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().send_to(
+        this->impl_.get_implementation(), buffers, destination, flags, ec);
+    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,
+      asio::error_code& ec)
+  {
+    return this->impl_.get_service().send_to(this->impl_.get_implementation(),
+        buffers, destination, flags, ec);
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send a datagram to the specified
+   * remote endpoint. The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   * Copies will be made of the endpoint as required.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * asio::ip::udp::endpoint destination(
+   *     asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.async_send_to(
+   *     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,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) WriteHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
+      void (asio::error_code, std::size_t))
+  async_send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination,
+      ASIO_MOVE_ARG(WriteHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<WriteHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_send_to(this), handler, buffers,
+        destination, socket_base::message_flags(0));
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send a datagram to the specified
+   * remote endpoint. The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   * Copies will be made of the endpoint as required.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   */
+  template <typename ConstBufferSequence,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) WriteHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
+      void (asio::error_code, std::size_t))
+  async_send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination, socket_base::message_flags flags,
+      ASIO_MOVE_ARG(WriteHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<WriteHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_send_to(this), handler, buffers, destination, flags);
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the datagram socket. The function
+   * call will block until data has been received successfully or an error
+   * occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws asio::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(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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().receive(
+        this->impl_.get_implementation(), buffers, 0, ec);
+    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 asio::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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().receive(
+        this->impl_.get_implementation(), buffers, flags, ec);
+    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, asio::error_code& ec)
+  {
+    return this->impl_.get_service().receive(
+        this->impl_.get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous receive on a connected socket.
+  /**
+   * This function is used to asynchronously receive data from the datagram
+   * socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @note The async_receive operation can only be used with a connected socket.
+   * Use the async_receive_from function to receive data on an unconnected
+   * datagram socket.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.async_receive(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,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) ReadHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
+      void (asio::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      ASIO_MOVE_ARG(ReadHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<ReadHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_receive(this), handler,
+        buffers, socket_base::message_flags(0));
+  }
+
+  /// Start an asynchronous receive on a connected socket.
+  /**
+   * This function is used to asynchronously receive data from the datagram
+   * socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @note The async_receive operation can only be used with a connected socket.
+   * Use the async_receive_from function to receive data on an unconnected
+   * datagram socket.
+   */
+  template <typename MutableBufferSequence,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) ReadHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
+      void (asio::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags,
+      ASIO_MOVE_ARG(ReadHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<ReadHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_receive(this), handler, buffers, flags);
+  }
+
+  /// Receive a datagram with the endpoint of the sender.
+  /**
+   * This function is used to receive a datagram. The function call will block
+   * until data has been received successfully or an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the datagram.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * asio::ip::udp::endpoint sender_endpoint;
+   * socket.receive_from(
+   *     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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().receive_from(
+        this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
+    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 asio::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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().receive_from(
+        this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
+    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,
+      asio::error_code& ec)
+  {
+    return this->impl_.get_service().receive_from(
+        this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive a datagram. The function
+   * call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the datagram. Ownership of the sender_endpoint object
+   * is retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code socket.async_receive_from(
+   *     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,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) ReadHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
+      void (asio::error_code, std::size_t))
+  async_receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint,
+      ASIO_MOVE_ARG(ReadHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<ReadHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_receive_from(this), handler, buffers,
+        &sender_endpoint, socket_base::message_flags(0));
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive a datagram. The function
+   * call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the datagram. Ownership of the sender_endpoint object
+   * is retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   */
+  template <typename MutableBufferSequence,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) ReadHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
+      void (asio::error_code, std::size_t))
+  async_receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint, socket_base::message_flags flags,
+      ASIO_MOVE_ARG(ReadHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<ReadHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_receive_from(this), handler,
+        buffers, &sender_endpoint, flags);
+  }
+
+private:
+  // Disallow copying and assignment.
+  basic_datagram_socket(const basic_datagram_socket&) ASIO_DELETED;
+  basic_datagram_socket& operator=(
+      const basic_datagram_socket&) ASIO_DELETED;
+
+  class initiate_async_send
+  { 
+  public:
+    typedef Executor executor_type;
+
+    explicit initiate_async_send(basic_datagram_socket* self)
+      : self_(self)
+    {
+    }
+
+    executor_type get_executor() const ASIO_NOEXCEPT
+    {
+      return self_->get_executor();
+    }
+
+    template <typename WriteHandler, typename ConstBufferSequence>
+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
+        const ConstBufferSequence& buffers,
+        socket_base::message_flags flags) const
+    {
+      // If you get an error on the following line it means that your handler
+      // does not meet the documented type requirements for a WriteHandler.
+      ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+      detail::non_const_lvalue<WriteHandler> handler2(handler);
+      self_->impl_.get_service().async_send(
+          self_->impl_.get_implementation(), buffers, flags,
+          handler2.value, self_->impl_.get_executor());
+    }
+
+  private:
+    basic_datagram_socket* self_;
+  };
+
+  class initiate_async_send_to
+  {
+  public:
+    typedef Executor executor_type;
+
+    explicit initiate_async_send_to(basic_datagram_socket* self)
+      : self_(self)
+    {
+    }
+
+    executor_type get_executor() const ASIO_NOEXCEPT
+    {
+      return self_->get_executor();
+    }
+
+    template <typename WriteHandler, typename ConstBufferSequence>
+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
+        const ConstBufferSequence& buffers, const endpoint_type& destination,
+        socket_base::message_flags flags) const
+    {
+      // If you get an error on the following line it means that your handler
+      // does not meet the documented type requirements for a WriteHandler.
+      ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+      detail::non_const_lvalue<WriteHandler> handler2(handler);
+      self_->impl_.get_service().async_send_to(
+          self_->impl_.get_implementation(), buffers, destination,
+          flags, handler2.value, self_->impl_.get_executor());
+    }
+
+  private:
+    basic_datagram_socket* self_;
+  };
+
+  class initiate_async_receive
+  {
+  public:
+    typedef Executor executor_type;
+
+    explicit initiate_async_receive(basic_datagram_socket* self)
+      : self_(self)
+    {
+    }
+
+    executor_type get_executor() const ASIO_NOEXCEPT
+    {
+      return self_->get_executor();
+    }
+
+    template <typename ReadHandler, typename MutableBufferSequence>
+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
+        const MutableBufferSequence& buffers,
+        socket_base::message_flags flags) const
+    {
+      // If you get an error on the following line it means that your handler
+      // does not meet the documented type requirements for a ReadHandler.
+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+      detail::non_const_lvalue<ReadHandler> handler2(handler);
+      self_->impl_.get_service().async_receive(
+          self_->impl_.get_implementation(), buffers, flags,
+          handler2.value, self_->impl_.get_executor());
+    }
+
+  private:
+    basic_datagram_socket* self_;
+  };
+
+  class initiate_async_receive_from
+  {
+  public:
+    typedef Executor executor_type;
+
+    explicit initiate_async_receive_from(basic_datagram_socket* self)
+      : self_(self)
+    {
+    }
+
+    executor_type get_executor() const ASIO_NOEXCEPT
+    {
+      return self_->get_executor();
+    }
+
+    template <typename ReadHandler, typename MutableBufferSequence>
+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
+        const MutableBufferSequence& buffers, endpoint_type* sender_endpoint,
+        socket_base::message_flags flags) const
+    {
+      // If you get an error on the following line it means that your handler
+      // does not meet the documented type requirements for a ReadHandler.
+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+      detail::non_const_lvalue<ReadHandler> handler2(handler);
+      self_->impl_.get_service().async_receive_from(
+          self_->impl_.get_implementation(), buffers, *sender_endpoint,
+          flags, handler2.value, self_->impl_.get_executor());
+    }
+
+  private:
+    basic_datagram_socket* self_;
+  };
+};
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_BASIC_DATAGRAM_SOCKET_HPP
diff --git a/cpp/third_party/asio/1.18.2/include/asio/basic_deadline_timer.hpp b/cpp/third_party/asio/1.18.2/include/asio/basic_deadline_timer.hpp
new file mode 100644
index 0000000..1104c61
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio/basic_deadline_timer.hpp
@@ -0,0 +1,693 @@
+//
+// basic_deadline_timer.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_BASIC_DEADLINE_TIMER_HPP
+#define ASIO_BASIC_DEADLINE_TIMER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#if defined(ASIO_HAS_BOOST_DATE_TIME) \
+  || defined(GENERATING_DOCUMENTATION)
+
+#include <cstddef>
+#include "asio/any_io_executor.hpp"
+#include "asio/detail/deadline_timer_service.hpp"
+#include "asio/detail/handler_type_requirements.hpp"
+#include "asio/detail/io_object_impl.hpp"
+#include "asio/detail/non_const_lvalue.hpp"
+#include "asio/detail/throw_error.hpp"
+#include "asio/error.hpp"
+#include "asio/execution_context.hpp"
+#include "asio/time_traits.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+
+/// Provides waitable timer functionality.
+/**
+ * The basic_deadline_timer class template provides the ability to perform a
+ * blocking or asynchronous wait for a timer to expire.
+ *
+ * A deadline timer is always in one of two states: "expired" or "not expired".
+ * If the wait() or async_wait() function is called on an expired timer, the
+ * wait operation will complete immediately.
+ *
+ * Most applications will use the asio::deadline_timer typedef.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Examples
+ * Performing a blocking wait:
+ * @code
+ * // Construct a timer without setting an expiry time.
+ * asio::deadline_timer timer(my_context);
+ *
+ * // Set an expiry time relative to now.
+ * timer.expires_from_now(boost::posix_time::seconds(5));
+ *
+ * // Wait for the timer to expire.
+ * timer.wait();
+ * @endcode
+ *
+ * @par 
+ * Performing an asynchronous wait:
+ * @code
+ * void handler(const asio::error_code& error)
+ * {
+ *   if (!error)
+ *   {
+ *     // Timer expired.
+ *   }
+ * }
+ *
+ * ...
+ *
+ * // Construct a timer with an absolute expiry time.
+ * asio::deadline_timer timer(my_context,
+ *     boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
+ *
+ * // Start an asynchronous wait.
+ * timer.async_wait(handler);
+ * @endcode
+ *
+ * @par Changing an active deadline_timer's expiry time
+ *
+ * Changing the expiry time of a timer while there are pending asynchronous
+ * waits causes those wait operations to be cancelled. To ensure that the action
+ * associated with the timer is performed only once, use something like this:
+ * used:
+ *
+ * @code
+ * void on_some_event()
+ * {
+ *   if (my_timer.expires_from_now(seconds(5)) > 0)
+ *   {
+ *     // We managed to cancel the timer. Start new asynchronous wait.
+ *     my_timer.async_wait(on_timeout);
+ *   }
+ *   else
+ *   {
+ *     // Too late, timer has already expired!
+ *   }
+ * }
+ *
+ * void on_timeout(const asio::error_code& e)
+ * {
+ *   if (e != asio::error::operation_aborted)
+ *   {
+ *     // Timer was not cancelled, take necessary action.
+ *   }
+ * }
+ * @endcode
+ *
+ * @li The asio::basic_deadline_timer::expires_from_now() function
+ * cancels any pending asynchronous waits, and returns the number of
+ * asynchronous waits that were cancelled. If it returns 0 then you were too
+ * late and the wait handler has already been executed, or will soon be
+ * executed. If it returns 1 then the wait handler was successfully cancelled.
+ *
+ * @li If a wait handler is cancelled, the asio::error_code passed to
+ * it contains the value asio::error::operation_aborted.
+ */
+template <typename Time,
+    typename TimeTraits = asio::time_traits<Time>,
+    typename Executor = any_io_executor>
+class basic_deadline_timer
+{
+public:
+  /// The type of the executor associated with the object.
+  typedef Executor executor_type;
+
+  /// Rebinds the timer type to another executor.
+  template <typename Executor1>
+  struct rebind_executor
+  {
+    /// The timer type when rebound to the specified executor.
+    typedef basic_deadline_timer<Time, TimeTraits, Executor1> other;
+  };
+
+  /// The time traits type.
+  typedef TimeTraits traits_type;
+
+  /// The time type.
+  typedef typename traits_type::time_type time_type;
+
+  /// The duration type.
+  typedef typename traits_type::duration_type duration_type;
+
+  /// Constructor.
+  /**
+   * This constructor creates a timer without setting an expiry time. The
+   * expires_at() or expires_from_now() functions must be called to set an
+   * expiry time before the timer can be waited on.
+   *
+   * @param ex The I/O executor that the timer will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the timer.
+   */
+  explicit basic_deadline_timer(const executor_type& ex)
+    : impl_(0, ex)
+  {
+  }
+
+  /// Constructor.
+  /**
+   * This constructor creates a timer without setting an expiry time. The
+   * expires_at() or expires_from_now() functions must be called to set an
+   * expiry time before the timer can be waited on.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the timer will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the timer.
+   */
+  template <typename ExecutionContext>
+  explicit basic_deadline_timer(ExecutionContext& context,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type = 0)
+    : impl_(0, 0, context)
+  {
+  }
+
+  /// Constructor to set a particular expiry time as an absolute time.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param ex The I/O executor that the timer will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, expressed
+   * as an absolute time.
+   */
+  basic_deadline_timer(const executor_type& ex, const time_type& expiry_time)
+    : impl_(0, ex)
+  {
+    asio::error_code ec;
+    impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
+    asio::detail::throw_error(ec, "expires_at");
+  }
+
+  /// Constructor to set a particular expiry time as an absolute time.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the timer will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, expressed
+   * as an absolute time.
+   */
+  template <typename ExecutionContext>
+  basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type = 0)
+    : impl_(0, 0, context)
+  {
+    asio::error_code ec;
+    impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
+    asio::detail::throw_error(ec, "expires_at");
+  }
+
+  /// Constructor to set a particular expiry time relative to now.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param ex The I/O executor that the timer will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, relative to
+   * now.
+   */
+  basic_deadline_timer(const executor_type& ex,
+      const duration_type& expiry_time)
+    : impl_(0, ex)
+  {
+    asio::error_code ec;
+    impl_.get_service().expires_from_now(
+        impl_.get_implementation(), expiry_time, ec);
+    asio::detail::throw_error(ec, "expires_from_now");
+  }
+
+  /// Constructor to set a particular expiry time relative to now.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the timer will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, relative to
+   * now.
+   */
+  template <typename ExecutionContext>
+  basic_deadline_timer(ExecutionContext& context,
+      const duration_type& expiry_time,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type = 0)
+    : impl_(0, 0, context)
+  {
+    asio::error_code ec;
+    impl_.get_service().expires_from_now(
+        impl_.get_implementation(), expiry_time, ec);
+    asio::detail::throw_error(ec, "expires_from_now");
+  }
+
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_deadline_timer from another.
+  /**
+   * This constructor moves a timer from one object to another.
+   *
+   * @param other The other basic_deadline_timer 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_deadline_timer(const executor_type&)
+   * constructor.
+   */
+  basic_deadline_timer(basic_deadline_timer&& other)
+    : impl_(std::move(other.impl_))
+  {
+  }
+
+  /// Move-assign a basic_deadline_timer from another.
+  /**
+   * This assignment operator moves a timer from one object to another. Cancels
+   * any outstanding asynchronous operations associated with the target object.
+   *
+   * @param other The other basic_deadline_timer 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_deadline_timer(const executor_type&)
+   * constructor.
+   */
+  basic_deadline_timer& operator=(basic_deadline_timer&& other)
+  {
+    impl_ = std::move(other.impl_);
+    return *this;
+  }
+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destroys the timer.
+  /**
+   * This function destroys the timer, cancelling any outstanding asynchronous
+   * wait operations associated with the timer as if by calling @c cancel.
+   */
+  ~basic_deadline_timer()
+  {
+  }
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() ASIO_NOEXCEPT
+  {
+    return impl_.get_executor();
+  }
+
+  /// Cancel any asynchronous operations that are waiting on the timer.
+  /**
+   * This function forces the completion of any pending asynchronous wait
+   * operations against the timer. The handler for each cancelled operation will
+   * be invoked with the asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when cancel() is called, then the
+   * handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel()
+  {
+    asio::error_code ec;
+    std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec);
+    asio::detail::throw_error(ec, "cancel");
+    return s;
+  }
+
+  /// Cancel any asynchronous operations that are waiting on the timer.
+  /**
+   * This function forces the completion of any pending asynchronous wait
+   * operations against the timer. The handler for each cancelled operation will
+   * be invoked with the asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when cancel() is called, then the
+   * handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel(asio::error_code& ec)
+  {
+    return impl_.get_service().cancel(impl_.get_implementation(), ec);
+  }
+
+  /// Cancels one asynchronous operation that is waiting on the timer.
+  /**
+   * This function forces the completion of one pending asynchronous wait
+   * operation against the timer. Handlers are cancelled in FIFO order. The
+   * handler for the cancelled operation will be invoked with the
+   * asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @return The number of asynchronous operations that were cancelled. That is,
+   * either 0 or 1.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when cancel_one() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel_one()
+  {
+    asio::error_code ec;
+    std::size_t s = impl_.get_service().cancel_one(
+        impl_.get_implementation(), ec);
+    asio::detail::throw_error(ec, "cancel_one");
+    return s;
+  }
+
+  /// Cancels one asynchronous operation that is waiting on the timer.
+  /**
+   * This function forces the completion of one pending asynchronous wait
+   * operation against the timer. Handlers are cancelled in FIFO order. The
+   * handler for the cancelled operation will be invoked with the
+   * asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled. That is,
+   * either 0 or 1.
+   *
+   * @note If the timer has already expired when cancel_one() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel_one(asio::error_code& ec)
+  {
+    return impl_.get_service().cancel_one(impl_.get_implementation(), ec);
+  }
+
+  /// Get the timer's expiry time as an absolute time.
+  /**
+   * This function may be used to obtain the timer's current expiry time.
+   * Whether the timer has expired or not does not affect this value.
+   */
+  time_type expires_at() const
+  {
+    return impl_.get_service().expires_at(impl_.get_implementation());
+  }
+
+  /// Set the timer's expiry time as an absolute time.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when expires_at() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_at(const time_type& expiry_time)
+  {
+    asio::error_code ec;
+    std::size_t s = impl_.get_service().expires_at(
+        impl_.get_implementation(), expiry_time, ec);
+    asio::detail::throw_error(ec, "expires_at");
+    return s;
+  }
+
+  /// Set the timer's expiry time as an absolute time.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when expires_at() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_at(const time_type& expiry_time,
+      asio::error_code& ec)
+  {
+    return impl_.get_service().expires_at(
+        impl_.get_implementation(), expiry_time, ec);
+  }
+
+  /// Get the timer's expiry time relative to now.
+  /**
+   * This function may be used to obtain the timer's current expiry time.
+   * Whether the timer has expired or not does not affect this value.
+   */
+  duration_type expires_from_now() const
+  {
+    return impl_.get_service().expires_from_now(impl_.get_implementation());
+  }
+
+  /// Set the timer's expiry time relative to now.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when expires_from_now() is called,
+   * then the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_from_now(const duration_type& expiry_time)
+  {
+    asio::error_code ec;
+    std::size_t s = impl_.get_service().expires_from_now(
+        impl_.get_implementation(), expiry_time, ec);
+    asio::detail::throw_error(ec, "expires_from_now");
+    return s;
+  }
+
+  /// Set the timer's expiry time relative to now.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when expires_from_now() is called,
+   * then the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_from_now(const duration_type& expiry_time,
+      asio::error_code& ec)
+  {
+    return impl_.get_service().expires_from_now(
+        impl_.get_implementation(), expiry_time, ec);
+  }
+
+  /// Perform a blocking wait on the timer.
+  /**
+   * This function is used to wait for the timer to expire. This function
+   * blocks and does not return until the timer has expired.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  void wait()
+  {
+    asio::error_code ec;
+    impl_.get_service().wait(impl_.get_implementation(), ec);
+    asio::detail::throw_error(ec, "wait");
+  }
+
+  /// Perform a blocking wait on the timer.
+  /**
+   * This function is used to wait for the timer to expire. This function
+   * blocks and does not return until the timer has expired.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  void wait(asio::error_code& ec)
+  {
+    impl_.get_service().wait(impl_.get_implementation(), ec);
+  }
+
+  /// Start an asynchronous wait on the timer.
+  /**
+   * This function may be used to initiate an asynchronous wait against the
+   * timer. It always returns immediately.
+   *
+   * For each call to async_wait(), the supplied handler will be called exactly
+   * once. The handler will be called when:
+   *
+   * @li The timer has expired.
+   *
+   * @li The timer was cancelled, in which case the handler is passed the error
+   * code asio::error::operation_aborted.
+   *
+   * @param handler The handler to be called when the timer expires. Copies
+   * will be made of the handler as required. The function signature of the
+   * handler must be:
+   * @code void handler(
+   *   const asio::error_code& error // Result of operation.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   */
+  template <
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))
+        WaitHandler ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
+      void (asio::error_code))
+  async_wait(
+      ASIO_MOVE_ARG(WaitHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<WaitHandler, void (asio::error_code)>(
+        initiate_async_wait(this), handler);
+  }
+
+private:
+  // Disallow copying and assignment.
+  basic_deadline_timer(const basic_deadline_timer&) ASIO_DELETED;
+  basic_deadline_timer& operator=(
+      const basic_deadline_timer&) ASIO_DELETED;
+
+  class initiate_async_wait
+  {
+  public:
+    typedef Executor executor_type;
+
+    explicit initiate_async_wait(basic_deadline_timer* self)
+      : self_(self)
+    {
+    }
+
+    executor_type get_executor() const ASIO_NOEXCEPT
+    {
+      return self_->get_executor();
+    }
+
+    template <typename WaitHandler>
+    void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const
+    {
+      // If you get an error on the following line it means that your handler
+      // does not meet the documented type requirements for a WaitHandler.
+      ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+      detail::non_const_lvalue<WaitHandler> handler2(handler);
+      self_->impl_.get_service().async_wait(
+          self_->impl_.get_implementation(),
+          handler2.value, self_->impl_.get_executor());
+    }
+
+  private:
+    basic_deadline_timer* self_;
+  };
+
+  detail::io_object_impl<
+    detail::deadline_timer_service<TimeTraits>, Executor> impl_;
+};
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
+       // || defined(GENERATING_DOCUMENTATION)
+
+#endif // ASIO_BASIC_DEADLINE_TIMER_HPP
diff --git a/cpp/third_party/asio/1.18.2/include/asio/basic_io_object.hpp b/cpp/third_party/asio/1.18.2/include/asio/basic_io_object.hpp
new file mode 100644
index 0000000..733557e
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio/basic_io_object.hpp
@@ -0,0 +1,290 @@
+//
+// basic_io_object.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_BASIC_IO_OBJECT_HPP
+#define ASIO_BASIC_IO_OBJECT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include "asio/io_context.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+
+#if defined(ASIO_HAS_MOVE)
+namespace detail
+{
+  // Type trait used to determine whether a service supports move.
+  template <typename IoObjectService>
+  class service_has_move
+  {
+  private:
+    typedef IoObjectService service_type;
+    typedef typename service_type::implementation_type implementation_type;
+
+    template <typename T, typename U>
+    static auto asio_service_has_move_eval(T* t, U* u)
+      -> decltype(t->move_construct(*u, *u), char());
+    static char (&asio_service_has_move_eval(...))[2];
+
+  public:
+    static const bool value =
+      sizeof(asio_service_has_move_eval(
+        static_cast<service_type*>(0),
+        static_cast<implementation_type*>(0))) == 1;
+  };
+}
+#endif // defined(ASIO_HAS_MOVE)
+
+/// Base class for all I/O objects.
+/**
+ * @note All I/O objects are non-copyable. However, when using C++0x, certain
+ * I/O objects do support move construction and move assignment.
+ */
+#if !defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+template <typename IoObjectService>
+#else
+template <typename IoObjectService,
+    bool Movable = detail::service_has_move<IoObjectService>::value>
+#endif
+class basic_io_object
+{
+public:
+  /// The type of the service that will be used to provide I/O operations.
+  typedef IoObjectService service_type;
+
+  /// The underlying implementation type of I/O object.
+  typedef typename service_type::implementation_type implementation_type;
+
+#if !defined(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.
+   */
+  asio::io_context& get_io_context()
+  {
+    return service_.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.
+   */
+  asio::io_context& get_io_service()
+  {
+    return service_.get_io_context();
+  }
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+  /// The type of the executor associated with the object.
+  typedef asio::io_context::executor_type executor_type;
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() ASIO_NOEXCEPT
+  {
+    return service_.get_io_context().get_executor();
+  }
+
+protected:
+  /// Construct a basic_io_object.
+  /**
+   * Performs:
+   * @code get_service().construct(get_implementation()); @endcode
+   */
+  explicit basic_io_object(asio::io_context& io_context)
+    : service_(asio::use_service<IoObjectService>(io_context))
+  {
+    service_.construct(implementation_);
+  }
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_io_object.
+  /**
+   * Performs:
+   * @code get_service().move_construct(
+   *     get_implementation(), other.get_implementation()); @endcode
+   *
+   * @note Available only for services that support movability,
+   */
+  basic_io_object(basic_io_object&& other);
+
+  /// Move-assign a basic_io_object.
+  /**
+   * Performs:
+   * @code get_service().move_assign(get_implementation(),
+   *     other.get_service(), other.get_implementation()); @endcode
+   *
+   * @note Available only for services that support movability,
+   */
+  basic_io_object& operator=(basic_io_object&& other);
+
+  /// Perform a converting move-construction of a basic_io_object.
+  template <typename IoObjectService1>
+  basic_io_object(IoObjectService1& other_service,
+      typename IoObjectService1::implementation_type& other_implementation);
+#endif // defined(GENERATING_DOCUMENTATION)
+
+  /// Protected destructor to prevent deletion through this type.
+  /**
+   * Performs:
+   * @code get_service().destroy(get_implementation()); @endcode
+   */
+  ~basic_io_object()
+  {
+    service_.destroy(implementation_);
+  }
+
+  /// Get the service associated with the I/O object.
+  service_type& get_service()
+  {
+    return service_;
+  }
+
+  /// Get the service associated with the I/O object.
+  const service_type& get_service() const
+  {
+    return service_;
+  }
+
+  /// Get the underlying implementation of the I/O object.
+  implementation_type& get_implementation()
+  {
+    return implementation_;
+  }
+
+  /// Get the underlying implementation of the I/O object.
+  const implementation_type& get_implementation() const
+  {
+    return implementation_;
+  }
+
+private:
+  basic_io_object(const basic_io_object&);
+  basic_io_object& operator=(const basic_io_object&);
+
+  // The service associated with the I/O object.
+  service_type& service_;
+
+  /// The underlying implementation of the I/O object.
+  implementation_type implementation_;
+};
+
+#if defined(ASIO_HAS_MOVE)
+// Specialisation for movable objects.
+template <typename IoObjectService>
+class basic_io_object<IoObjectService, true>
+{
+public:
+  typedef IoObjectService service_type;
+  typedef typename service_type::implementation_type implementation_type;
+
+#if !defined(ASIO_NO_DEPRECATED)
+  asio::io_context& get_io_context()
+  {
+    return service_->get_io_context();
+  }
+
+  asio::io_context& get_io_service()
+  {
+    return service_->get_io_context();
+  }
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+  typedef asio::io_context::executor_type executor_type;
+
+  executor_type get_executor() ASIO_NOEXCEPT
+  {
+    return service_->get_io_context().get_executor();
+  }
+
+protected:
+  explicit basic_io_object(asio::io_context& io_context)
+    : service_(&asio::use_service<IoObjectService>(io_context))
+  {
+    service_->construct(implementation_);
+  }
+
+  basic_io_object(basic_io_object&& other)
+    : service_(&other.get_service())
+  {
+    service_->move_construct(implementation_, other.implementation_);
+  }
+
+  template <typename IoObjectService1>
+  basic_io_object(IoObjectService1& other_service,
+      typename IoObjectService1::implementation_type& other_implementation)
+    : service_(&asio::use_service<IoObjectService>(
+          other_service.get_io_context()))
+  {
+    service_->converting_move_construct(implementation_,
+        other_service, other_implementation);
+  }
+
+  ~basic_io_object()
+  {
+    service_->destroy(implementation_);
+  }
+
+  basic_io_object& operator=(basic_io_object&& other)
+  {
+    service_->move_assign(implementation_,
+        *other.service_, other.implementation_);
+    service_ = other.service_;
+    return *this;
+  }
+
+  service_type& get_service()
+  {
+    return *service_;
+  }
+
+  const service_type& get_service() const
+  {
+    return *service_;
+  }
+
+  implementation_type& get_implementation()
+  {
+    return implementation_;
+  }
+
+  const implementation_type& get_implementation() const
+  {
+    return implementation_;
+  }
+
+private:
+  basic_io_object(const basic_io_object&);
+  void operator=(const basic_io_object&);
+
+  IoObjectService* service_;
+  implementation_type implementation_;
+};
+#endif // defined(ASIO_HAS_MOVE)
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_BASIC_IO_OBJECT_HPP
diff --git a/cpp/third_party/asio/1.18.2/include/asio/basic_raw_socket.hpp b/cpp/third_party/asio/1.18.2/include/asio/basic_raw_socket.hpp
new file mode 100644
index 0000000..60801e3
--- /dev/null
+++ b/cpp/third_party/asio/1.18.2/include/asio/basic_raw_socket.hpp
@@ -0,0 +1,1214 @@
+//
+// basic_raw_socket.hpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_BASIC_RAW_SOCKET_HPP
+#define ASIO_BASIC_RAW_SOCKET_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include <cstddef>
+#include "asio/basic_socket.hpp"
+#include "asio/detail/handler_type_requirements.hpp"
+#include "asio/detail/non_const_lvalue.hpp"
+#include "asio/detail/throw_error.hpp"
+#include "asio/detail/type_traits.hpp"
+#include "asio/error.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+
+#if !defined(ASIO_BASIC_RAW_SOCKET_FWD_DECL)
+#define ASIO_BASIC_RAW_SOCKET_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = any_io_executor>
+class basic_raw_socket;
+
+#endif // !defined(ASIO_BASIC_RAW_SOCKET_FWD_DECL)
+
+/// Provides raw-oriented socket functionality.
+/**
+ * The basic_raw_socket class template provides asynchronous and blocking
+ * raw-oriented socket functionality.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * Synchronous @c send, @c send_to, @c receive, @c receive_from, and @c connect
+ * operations are thread safe with respect to each other, if the underlying
+ * operating system calls are also thread safe. This means that it is permitted
+ * to perform concurrent calls to these synchronous operations on a single
+ * socket object. Other synchronous operations, such as @c open or @c close, are
+ * not thread safe.
+ */
+template <typename Protocol, typename Executor>
+class basic_raw_socket
+  : public basic_socket<Protocol, Executor>
+{
+public:
+  /// The type of the executor associated with the object.
+  typedef Executor executor_type;
+
+  /// Rebinds the socket type to another executor.
+  template <typename Executor1>
+  struct rebind_executor
+  {
+    /// The socket type when rebound to the specified executor.
+    typedef basic_raw_socket<Protocol, Executor1> other;
+  };
+
+  /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_handle_type;
+#else
+  typedef typename basic_socket<Protocol,
+    Executor>::native_handle_type native_handle_type;
+#endif
+
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+  /// Construct a basic_raw_socket without opening it.
+  /**
+   * This constructor creates a raw socket without opening it. The open()
+   * function must be called before data can be sent or received on the socket.
+   *
+   * @param ex The I/O executor that the socket will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   */
+  explicit basic_raw_socket(const executor_type& ex)
+    : basic_socket<Protocol, Executor>(ex)
+  {
+  }
+
+  /// Construct a basic_raw_socket without opening it.
+  /**
+   * This constructor creates a raw socket without opening it. The open()
+   * function must be called before data can be sent or received on the socket.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the socket will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the socket.
+   */
+  template <typename ExecutionContext>
+  explicit basic_raw_socket(ExecutionContext& context,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type = 0)
+    : basic_socket<Protocol, Executor>(context)
+  {
+  }
+
+  /// Construct and open a basic_raw_socket.
+  /**
+   * This constructor creates and opens a raw socket.
+   *
+   * @param ex The I/O executor that the socket will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  basic_raw_socket(const executor_type& ex, const protocol_type& protocol)
+    : basic_socket<Protocol, Executor>(ex, protocol)
+  {
+  }
+
+  /// Construct and open a basic_raw_socket.
+  /**
+   * This constructor creates and opens a raw socket.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the socket will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  template <typename ExecutionContext>
+  basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value,
+        defaulted_constraint
+      >::type = defaulted_constraint())
+    : basic_socket<Protocol, Executor>(context, protocol)
+  {
+  }
+
+  /// Construct a basic_raw_socket, opening it and binding it to the given
+  /// local endpoint.
+  /**
+   * This constructor creates a raw socket and automatically opens it bound
+   * to the specified endpoint on the local machine. The protocol used is the
+   * protocol associated with the given endpoint.
+   *
+   * @param ex The I/O executor that the socket will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param endpoint An endpoint on the local machine to which the raw
+   * socket will be bound.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint)
+    : basic_socket<Protocol, Executor>(ex, endpoint)
+  {
+  }
+
+  /// Construct a basic_raw_socket, opening it and binding it to the given
+  /// local endpoint.
+  /**
+   * This constructor creates a raw socket and automatically opens it bound
+   * to the specified endpoint on the local machine. The protocol used is the
+   * protocol associated with the given endpoint.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the socket will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the socket.
+   *
+   * @param endpoint An endpoint on the local machine to which the raw
+   * socket will be bound.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  template <typename ExecutionContext>
+  basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type = 0)
+    : basic_socket<Protocol, Executor>(context, endpoint)
+  {
+  }
+
+  /// Construct a basic_raw_socket on an existing native socket.
+  /**
+   * This constructor creates a raw socket object to hold an existing
+   * native socket.
+   *
+   * @param ex The I/O executor that the socket will use, by default, to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_socket The new underlying socket implementation.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  basic_raw_socket(const executor_type& ex,
+      const protocol_type& protocol, const native_handle_type& native_socket)
+    : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
+  {
+  }
+
+  /// Construct a basic_raw_socket on an existing native socket.
+  /**
+   * This constructor creates a raw socket object to hold an existing
+   * native socket.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the socket will use, by default, to dispatch handlers for any asynchronous
+   * operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_socket The new underlying socket implementation.
+   *
+   * @throws asio::system_error Thrown on failure.
+   */
+  template <typename ExecutionContext>
+  basic_raw_socket(ExecutionContext& context,
+      const protocol_type& protocol, const native_handle_type& native_socket,
+      typename constraint<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type = 0)
+    : basic_socket<Protocol, Executor>(context, protocol, native_socket)
+  {
+  }
+
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_raw_socket from another.
+  /**
+   * This constructor moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_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_raw_socket(const executor_type&)
+   * constructor.
+   */
+  basic_raw_socket(basic_raw_socket&& other) ASIO_NOEXCEPT
+    : basic_socket<Protocol, Executor>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_raw_socket from another.
+  /**
+   * This assignment operator moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_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_raw_socket(const executor_type&)
+   * constructor.
+   */
+  basic_raw_socket& operator=(basic_raw_socket&& other)
+  {
+    basic_socket<Protocol, Executor>::operator=(std::move(other));
+    return *this;
+  }
+
+  /// Move-construct a basic_raw_socket from a socket of another protocol
+  /// type.
+  /**
+   * This constructor moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_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_raw_socket(const executor_type&)
+   * constructor.
+   */
+  template <typename Protocol1, typename Executor1>
+  basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,
+      typename constraint<
+        is_convertible<Protocol1, Protocol>::value
+          && is_convertible<Executor1, Executor>::value
+      >::type = 0)
+    : basic_socket<Protocol, Executor>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_raw_socket from a socket of another protocol type.
+  /**
+   * This assignment operator moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_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_raw_socket(const executor_type&)
+   * constructor.
+   */
+  template <typename Protocol1, typename Executor1>
+  typename constraint<
+    is_convertible<Protocol1, Protocol>::value
+      && is_convertible<Executor1, Executor>::value,
+    basic_raw_socket&
+  >::type operator=(basic_raw_socket<Protocol1, Executor1>&& other)
+  {
+    basic_socket<Protocol, Executor>::operator=(std::move(other));
+    return *this;
+  }
+#endif // defined(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_raw_socket()
+  {
+  }
+
+  /// Send some data on a connected socket.
+  /**
+   * This function is used to send data on the raw 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 asio::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 raw socket.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code socket.send(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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().send(
+        this->impl_.get_implementation(), buffers, 0, ec);
+    asio::detail::throw_error(ec, "send");
+    return s;
+  }
+
+  /// Send some data on a connected socket.
+  /**
+   * This function is used to send data on the raw 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 asio::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 raw socket.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().send(
+        this->impl_.get_implementation(), buffers, flags, ec);
+    asio::detail::throw_error(ec, "send");
+    return s;
+  }
+
+  /// Send some data on a connected socket.
+  /**
+   * This function is used to send data on the raw 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 raw socket.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags, asio::error_code& ec)
+  {
+    return this->impl_.get_service().send(
+        this->impl_.get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous send on a connected socket.
+  /**
+   * This function is used to send data on the raw 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. 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 asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @note The async_send operation can only be used with a connected socket.
+   * Use the async_send_to function to send data on an unconnected raw
+   * socket.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.async_send(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,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) WriteHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
+      void (asio::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      ASIO_MOVE_ARG(WriteHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<WriteHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_send(this), handler,
+        buffers, socket_base::message_flags(0));
+  }
+
+  /// Start an asynchronous send on a connected socket.
+  /**
+   * This function is used to send data on the raw 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. 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 asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @note The async_send operation can only be used with a connected socket.
+   * Use the async_send_to function to send data on an unconnected raw
+   * socket.
+   */
+  template <typename ConstBufferSequence,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) WriteHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
+      void (asio::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags,
+      ASIO_MOVE_ARG(WriteHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<WriteHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_send(this), handler, buffers, flags);
+  }
+
+  /// Send raw data to the specified endpoint.
+  /**
+   * This function is used to send raw data 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 asio::system_error Thrown on failure.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * asio::ip::udp::endpoint destination(
+   *     asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.send_to(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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().send_to(
+        this->impl_.get_implementation(), buffers, destination, 0, ec);
+    asio::detail::throw_error(ec, "send_to");
+    return s;
+  }
+
+  /// Send raw data to the specified endpoint.
+  /**
+   * This function is used to send raw data 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 asio::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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().send_to(
+        this->impl_.get_implementation(), buffers, destination, flags, ec);
+    asio::detail::throw_error(ec, "send_to");
+    return s;
+  }
+
+  /// Send raw data to the specified endpoint.
+  /**
+   * This function is used to send raw data 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,
+      asio::error_code& ec)
+  {
+    return this->impl_.get_service().send_to(this->impl_.get_implementation(),
+        buffers, destination, flags, ec);
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send raw data 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 asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * asio::ip::udp::endpoint destination(
+   *     asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.async_send_to(
+   *     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,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) WriteHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
+      void (asio::error_code, std::size_t))
+  async_send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination,
+      ASIO_MOVE_ARG(WriteHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<WriteHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_send_to(this), handler, buffers,
+        destination, socket_base::message_flags(0));
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send raw data 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 asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   */
+  template <typename ConstBufferSequence,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) WriteHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
+      void (asio::error_code, std::size_t))
+  async_send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination, socket_base::message_flags flags,
+      ASIO_MOVE_ARG(WriteHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<WriteHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_send_to(this), handler, buffers, destination, flags);
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the raw 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 asio::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 raw
+   * socket.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code socket.receive(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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().receive(
+        this->impl_.get_implementation(), buffers, 0, ec);
+    asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the raw 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 asio::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 raw
+   * socket.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().receive(
+        this->impl_.get_implementation(), buffers, flags, ec);
+    asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the raw 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 raw
+   * socket.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags, asio::error_code& ec)
+  {
+    return this->impl_.get_service().receive(
+        this->impl_.get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous receive on a connected socket.
+  /**
+   * This function is used to asynchronously receive data from the raw
+   * 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 asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @note The async_receive operation can only be used with a connected socket.
+   * Use the async_receive_from function to receive data on an unconnected
+   * raw socket.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.async_receive(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,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) ReadHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
+      void (asio::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      ASIO_MOVE_ARG(ReadHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<ReadHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_receive(this), handler,
+        buffers, socket_base::message_flags(0));
+  }
+
+  /// Start an asynchronous receive on a connected socket.
+  /**
+   * This function is used to asynchronously receive data from the raw
+   * 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 asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @note The async_receive operation can only be used with a connected socket.
+   * Use the async_receive_from function to receive data on an unconnected
+   * raw socket.
+   */
+  template <typename MutableBufferSequence,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) ReadHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
+      void (asio::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags,
+      ASIO_MOVE_ARG(ReadHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<ReadHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_receive(this), handler, buffers, flags);
+  }
+
+  /// Receive raw data with the endpoint of the sender.
+  /**
+   * This function is used to receive raw data. 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 data.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * asio::ip::udp::endpoint sender_endpoint;
+   * socket.receive_from(
+   *     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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().receive_from(
+        this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
+    asio::detail::throw_error(ec, "receive_from");
+    return s;
+  }
+  
+  /// Receive raw data with the endpoint of the sender.
+  /**
+   * This function is used to receive raw data. 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 data.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws asio::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)
+  {
+    asio::error_code ec;
+    std::size_t s = this->impl_.get_service().receive_from(
+        this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
+    asio::detail::throw_error(ec, "receive_from");
+    return s;
+  }
+  
+  /// Receive raw data with the endpoint of the sender.
+  /**
+   * This function is used to receive raw data. 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 data.
+   *
+   * @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,
+      asio::error_code& ec)
+  {
+    return this->impl_.get_service().receive_from(
+        this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive raw data. 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 data. 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 asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code socket.async_receive_from(
+   *     asio::buffer(data, size), 0, 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,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) ReadHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
+      void (asio::error_code, std::size_t))
+  async_receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint,
+      ASIO_MOVE_ARG(ReadHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<ReadHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_receive_from(this), handler, buffers,
+        &sender_endpoint, socket_base::message_flags(0));
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive raw data. 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 data. 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 asio::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using asio::post().
+   */
+  template <typename MutableBufferSequence,
+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
+        std::size_t)) ReadHandler
+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
+      void (asio::error_code, std::size_t))
+  async_receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint, socket_base::message_flags flags,
+      ASIO_MOVE_ARG(ReadHandler) handler
+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
+  {
+    return async_initiate<ReadHandler,
+      void (asio::error_code, std::size_t)>(
+        initiate_async_receive_from(this), handler,
+        buffers, &sender_endpoint, flags);
+  }
+
+private:
+  // Disallow copying and assignment.
+  basic_raw_socket(const basic_raw_socket&) ASIO_DELETED;
+  basic_raw_socket& operator=(const basic_raw_socket&) ASIO_DELETED;
+
+  class initiate_async_send
+  {
+  public:
+    typedef Executor executor_type;
+
+    explicit initiate_async_send(basic_raw_socket* self)
+      : self_(self)
+    {
+    }
+
+    executor_type get_executor() const ASIO_NOEXCEPT
+    {
+      return self_->get_executor();
+    }
+
+    template <typename WriteHandler, typename ConstBufferSequence>
+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
+        const ConstBufferSequence& buffers,
+        socket_base::message_flags flags) const
+    {
+      // If you get an error on the following line it means that your handler
+      // does not meet the documented type requirements for a WriteHandler.
+      ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+      detail::non_const_lvalue<WriteHandler> handler2(handler);
+      self_->impl_.get_service().async_send(
+          self_->impl_.get_implementation(), buffers, flags,
+          handler2.value, self_->impl_.get_executor());
+    }
+
+  private:
+    basic_raw_socket* self_;
+  };
+
+  class initiate_async_send_to
+  {
+  public:
+    typedef Executor executor_type;
+
+    explicit initiate_async_send_to(basic_raw_socket* self)
+      : self_(self)
+    {
+    }
+
+    executor_type get_executor() const ASIO_NOEXCEPT
+    {
+      return self_->get_executor();
+    }
+
+    template <typename WriteHandler, typename ConstBufferSequence>
+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
+        const ConstBufferSequence& buffers, const endpoint_type& destination,
+        socket_base::message_flags flags) const
+    {
+      // If you get an error on the following line it means that your handler
+      // does not meet the documented type requirements for a WriteHandler.
+      ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+      detail::non_const_lvalue<WriteHandler> handler2(handler);
+      self_->impl_.get_service().async_send_to(
+          self_->impl_.get_implementation(), buffers, destination,
+          flags, handler2.value, self_->impl_.get_executor());
+    }
+
+  private:
+    basic_raw_socket* self_;
+  };
+
+  class initiate_async_receive
+  {
+  public:
+    typedef Executor executor_type;
+
+    explicit initiate_async_receive(basic_raw_socket* self)
+      : self_(self)
+    {
+    }
+
+    executor_type get_executor() const ASIO_NOEXCEPT
+    {
+      return self_->get_executor();
+    }
+
+    template <typename ReadHandler, typename MutableBufferSequence>
+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
+        const MutableBufferSequence& buffers,
+        socket_base::message_flags flags) const
+    {
+      // If you get an error on the following line it means that your handler
+      // does not meet the documented type requirements for a ReadHandler.
+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+      detail::non_const_lvalue<ReadHandler> handler2(handler);
+      self_->impl_.get_service().async_receive(
+          self_->impl_.get_implementation(), buffers, flags,
... 216320 lines suppressed ...